From aeb075704b5e2ae4757da69ca8d6eda0235d327d Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Sat, 7 Oct 2017 12:24:02 +0100 Subject: [PATCH] logind: remove an obscure dbus error from GetSessionByPID(0) and friends GetSessionByPID(0) can fail with NO_SESSION_FOR_PID. More obscurely, if the session is abandoned, it can return NO_SUCH_SESSION. It is not clear that the latter was intended. The message associated with the former, hints that this was overlooked. We don't have a document enumerating the errors. Any specific error-handling in client code, e.g. translated messages, would also be liable to overlook the more obscure error code. I can't see any equivalent condition for GetUserByPID(0). On the other hand, the code did not return NO_USER_FOR_PID where it probably should. The relevant code is right next to that for GetSessionByPID(0), so it will be simpler to understand if both follow the same pattern. --- src/login/logind-dbus.c | 87 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 26 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index f62a02c..1350452 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -50,27 +50,44 @@ #include "user-util.h" #include "utmp-wtmp.h" -int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) { +static int get_sender_session(Manager *m, sd_bus_message *message, sd_bus_error *error, Session **ret) { + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; + const char *name; Session *session; int r; + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds); + if (r < 0) + return r; + + r = sd_bus_creds_get_session(creds, &name); + if (r == -ENXIO) + goto err_no_session; + if (r < 0) + return r; + + session = hashmap_get(m->sessions, name); + if (!session) + goto err_no_session; + + *ret = session; + return 0; + +err_no_session: + return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, + "Caller does not belong to any known session"); +} + +int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) { + Session *session; + assert(m); assert(message); assert(ret); - if (isempty(name)) { - r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds); - if (r < 0) - return r; - - r = sd_bus_creds_get_session(creds, &name); - if (r == -ENXIO) - return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, - "Caller does not belong to any known session"); - if (r < 0) - return r; - } + if (isempty(name)) + return get_sender_session(m, message, error, ret); session = hashmap_get(m->sessions, name); if (!session) @@ -80,26 +97,44 @@ int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const ch return 0; } -int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) { +static int get_sender_user(Manager *m, sd_bus_message *message, sd_bus_error *error, User **ret) { + + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; + uid_t uid; User *user; int r; + /* Note that we get the owner UID of the session, not the actual client UID here! */ + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds); + if (r < 0) + return r; + + r = sd_bus_creds_get_owner_uid(creds, &uid); + if (r == -ENXIO) + goto err_no_user; + if (r < 0) + return r; + + user = hashmap_get(m->users, UID_TO_PTR(uid)); + if (!user) + goto err_no_user; + + *ret = user; + return 0; + +err_no_user: + return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "Caller does not belong to any known or logged in user"); +} + +int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) { + User *user; + assert(m); assert(message); assert(ret); - if (!uid_is_valid(uid)) { - _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; - - /* Note that we get the owner UID of the session, not the actual client UID here! */ - r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds); - if (r < 0) - return r; - - r = sd_bus_creds_get_owner_uid(creds, &uid); - if (r < 0) - return r; - } + if (!uid_is_valid(uid)) + return get_sender_user(m, message, error, ret); user = hashmap_get(m->users, UID_TO_PTR(uid)); if (!user) -- 2.7.4