X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flogin%2Flogind-dbus.c;h=2568eb0364c17787f1a281b4b527d43af83050e3;hb=fa28bc2df724e4aff46d19cb7aa732cc64c71061;hp=b1c2ef19b13da67d6f999857572625a219666d3e;hpb=ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602;p=elogind.git diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index b1c2ef19b..2568eb036 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "sd-id128.h" #include "sd-messages.h" @@ -172,7 +173,13 @@ static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void return r; if (pid == 0) { - r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid); + _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; + + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds); + if (r < 0) + return r; + + r = sd_bus_creds_get_pid(creds, &pid); if (r < 0) return r; } @@ -234,7 +241,13 @@ static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *us return r; if (pid == 0) { - r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid); + _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; + + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds); + if (r < 0) + return r; + + r = sd_bus_creds_get_pid(creds, &pid); if (r < 0) return r; } @@ -496,7 +509,7 @@ static int method_create_session(sd_bus *bus, sd_bus_message *message, void *use if (v <= 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty); - if (vtnr <= 0) + if (!vtnr) vtnr = (uint32_t) v; else if (vtnr != (uint32_t) v) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match"); @@ -514,7 +527,7 @@ static int method_create_session(sd_bus *bus, sd_bus_message *message, void *use if (seat) { if (seat_has_vts(seat)) { - if (vtnr > 63) + if (!vtnr || vtnr > 63) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "VT number out of range"); } else { if (vtnr != 0) @@ -543,9 +556,15 @@ static int method_create_session(sd_bus *bus, sd_bus_message *message, void *use } if (leader <= 0) { + _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; + + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds); + if (r < 0) + return r; + assert_cc(sizeof(uint32_t) == sizeof(pid_t)); - r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), (pid_t*) &leader); + r = sd_bus_creds_get_pid(creds, (pid_t*) &leader); if (r < 0) return r; } @@ -568,11 +587,12 @@ static int method_create_session(sd_bus *bus, sd_bus_message *message, void *use return -ENOMEM; return sd_bus_reply_method_return( - message, "soshsub", + message, "soshusub", session->id, path, session->user->runtime_path, fifo_fd, + (uint32_t) session->user->uid, session->seat ? session->seat->id : "", (uint32_t) session->vtnr, true); @@ -1251,7 +1271,6 @@ static int have_multiple_sessions( * count, and non-login sessions do not count either. */ HASHMAP_FOREACH(session, m->sessions, i) if (session->class == SESSION_USER && - !session->closing && session->user->uid != uid) return true; @@ -1398,7 +1417,7 @@ int bus_manager_shutdown_or_sleep_now_or_later( delayed = m->inhibit_delay_max > 0 && - manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0); + manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL); if (delayed) /* Shutdown is delayed, keep in mind what we @@ -1424,6 +1443,7 @@ static int method_do_shutdown_or_sleep( sd_bus_message_handler_t method, sd_bus_error *error) { + _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; bool multiple_sessions, blocked; int interactive, r; uid_t uid; @@ -1455,7 +1475,11 @@ static int method_do_shutdown_or_sleep( return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported"); } - r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid); + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds); + if (r < 0) + return r; + + r = sd_bus_creds_get_uid(creds, &uid); if (r < 0) return r; @@ -1464,7 +1488,7 @@ static int method_do_shutdown_or_sleep( return r; multiple_sessions = r > 0; - blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid); + blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL); if (multiple_sessions) { r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message, @@ -1579,6 +1603,7 @@ static int method_can_shutdown_or_sleep( const char *sleep_verb, sd_bus_error *error) { + _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; bool multiple_sessions, challenge, blocked; const char *result = NULL; uid_t uid; @@ -1600,7 +1625,11 @@ static int method_can_shutdown_or_sleep( return sd_bus_reply_method_return(message, "s", "na"); } - r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid); + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds); + if (r < 0) + return r; + + r = sd_bus_creds_get_uid(creds, &uid); if (r < 0) return r; @@ -1609,7 +1638,7 @@ static int method_can_shutdown_or_sleep( return r; multiple_sessions = r > 0; - blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid); + blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL); if (multiple_sessions) { r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error); @@ -1722,6 +1751,7 @@ static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *u } static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) { + _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; const char *who, *why, *what, *mode; _cleanup_free_ char *id = NULL; _cleanup_close_ int fifo_fd = -1; @@ -1774,11 +1804,15 @@ static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ - r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid); + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds); + if (r < 0) + return r; + + r = sd_bus_creds_get_uid(creds, &uid); if (r < 0) return r; - r = sd_bus_get_owner_pid(m->bus, sd_bus_message_get_sender(message), &pid); + r = sd_bus_creds_get_pid(creds, &pid); if (r < 0) return r; @@ -1846,42 +1880,42 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0), SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0), - SD_BUS_METHOD("GetSession", "s", "o", method_get_session, 0), - SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, 0), - SD_BUS_METHOD("GetUser", "u", "o", method_get_user, 0), - SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, 0), - SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, 0), - SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, 0), - SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, 0), - SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, 0), - SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, 0), - SD_BUS_METHOD("CreateSession", "uussssussbssa(sv)", "soshsub", method_create_session, 0), + SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("CreateSession", "uussssussbssa(sv)", "soshusub", method_create_session, 0), SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0), - SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, 0), - SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, 0), + SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, 0), SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, 0), SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, 0), SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, 0), - SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, 0), - SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, 0), - SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, 0), - SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, 0), - SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, 0), - SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, 0), - SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, 0), - SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, 0), - SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, 0), - SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, 0), - SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, 0), - SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, 0), - SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, 0), - SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, 0), - SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, 0), - SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, 0), - SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, 0), - SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, 0), - SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, 0), + SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), + SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), + SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), + SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), + SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)), + SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_SIGNAL("SessionNew", "so", 0), SD_BUS_SIGNAL("SessionRemoved", "so", 0), @@ -2104,6 +2138,7 @@ int manager_send_changed(Manager *manager, const char *property, ...) { int manager_dispatch_delayed(Manager *manager) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + Inhibitor *offending = NULL; int r; assert(manager); @@ -2112,12 +2147,18 @@ int manager_dispatch_delayed(Manager *manager) { return 0; /* Continue delay? */ - if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0)) { + if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) { + _cleanup_free_ char *comm = NULL, *u = NULL; + + get_process_comm(offending->pid, &comm); + u = uid_to_name(offending->uid); if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC)) return 0; - log_info("Delay lock is active but inhibitor timeout is reached."); + log_info("Delay lock is active (UID %lu/%s, PID %lu/%s) but inhibitor timeout is reached.", + (unsigned long) offending->uid, strna(u), + (unsigned long) offending->pid, strna(comm)); } /* Actually do the operation */ @@ -2216,6 +2257,10 @@ int manager_start_scope( if (r < 0) return r; + r = sd_bus_message_append(m, "a(sa(sv))", 0); + if (r < 0) + return r; + r = sd_bus_call(manager->bus, m, 0, error, &reply); if (r < 0) return r;