X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flogin%2Flogind-user-dbus.c;h=20ea2fbdc415882b28461ab7a70db53378b25921;hb=bf2098e9e4837573d84dd4949b9c28a7372c93b9;hp=717740ad044b24ef187088ade44fa29bc743d546;hpb=309a29dfd24f4175de334ca1593e3fe2436ab082;p=elogind.git diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c index 717740ad0..20ea2fbdc 100644 --- a/src/login/logind-user-dbus.c +++ b/src/login/logind-user-dbus.c @@ -26,6 +26,7 @@ #include "bus-util.h" #include "logind.h" #include "logind-user.h" +#include "formats-util.h" static int property_get_display( sd_bus *bus, @@ -102,11 +103,7 @@ static int property_get_sessions( } - r = sd_bus_message_close_container(reply); - if (r < 0) - return r; - - return 1; + return sd_bus_message_close_container(reply); } static int property_get_idle_hint( @@ -137,7 +134,7 @@ static int property_get_idle_since_hint( sd_bus_error *error) { User *u = userdata; - dual_timestamp t; + dual_timestamp t = DUAL_TIMESTAMP_NULL; uint64_t k; assert(bus); @@ -171,14 +168,27 @@ static int property_get_linger( return sd_bus_message_append(reply, "b", r > 0); } -static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { +int bus_user_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error) { User *u = userdata; int r; - assert(bus); assert(message); assert(u); + r = bus_verify_polkit_async( + message, + CAP_KILL, + "org.freedesktop.login1.manage", + NULL, + false, + u->uid, + &u->manager->polkit_registry, + error); + if (r < 0) + return r; + if (r == 0) + return 1; /* Will call us back */ + r = user_stop(u, true); if (r < 0) return r; @@ -186,15 +196,28 @@ static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata return sd_bus_reply_method_return(message, NULL); } -static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { +int bus_user_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error) { User *u = userdata; int32_t signo; int r; - assert(bus); assert(message); assert(u); + r = bus_verify_polkit_async( + message, + CAP_KILL, + "org.freedesktop.login1.manage", + NULL, + false, + u->uid, + &u->manager->polkit_registry, + error); + if (r < 0) + return r; + if (r == 0) + return 1; /* Will call us back */ + r = sd_bus_message_read(message, "i", &signo); if (r < 0) return r; @@ -227,8 +250,8 @@ const sd_bus_vtable user_vtable[] = { SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("Linger", "b", property_get_linger, 0, 0), - SD_BUS_METHOD("Terminate", NULL, NULL, method_terminate, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), - SD_BUS_METHOD("Kill", "i", NULL, method_kill, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), + SD_BUS_METHOD("Terminate", NULL, NULL, bus_user_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Kill", "i", NULL, bus_user_method_kill, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_VTABLE_END }; @@ -270,7 +293,7 @@ int user_object_find(sd_bus *bus, const char *path, const char *interface, void if (r < 0) return 0; - user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid)); + user = hashmap_get(m->users, UID_TO_PTR(uid)); if (!user) return 0; @@ -291,6 +314,7 @@ char *user_bus_path(User *u) { int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { _cleanup_strv_free_ char **l = NULL; + sd_bus_message *message; Manager *m = userdata; User *user; Iterator i; @@ -312,9 +336,24 @@ int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char *** return r; } - r = strv_extend(&l, "/org/freedesktop/login1/user/self"); - if (r < 0) - return r; + message = sd_bus_get_current_message(bus); + if (message) { + _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; + uid_t uid; + + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds); + if (r >= 0) { + r = sd_bus_creds_get_owner_uid(creds, &uid); + if (r >= 0) { + user = hashmap_get(m->users, UID_TO_PTR(uid)); + if (user) { + r = strv_extend(&l, "/org/freedesktop/login1/user/self"); + if (r < 0) + return r; + } + } + } + } *nodes = l; l = NULL;