X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flogin%2Flogind-dbus.c;h=77a06f2ce4587a6c228ee15b2521d566f8b09f8c;hp=4ae5ba70ba6e646366769ffeed23e1d159d7f304;hb=23406ce58aa7142e8df3c5c9e5ac34a01e90e3e0;hpb=beaafb2ea6be591882aef21fe19b88e3b2461087 diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 4ae5ba70b..77a06f2ce 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -83,6 +83,7 @@ " \n" \ " \n" \ " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -144,6 +145,9 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -156,6 +160,9 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -210,8 +217,11 @@ " \n" \ " \n" \ " \n" \ - " \n" \ + " \n" \ + " \n" \ " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" @@ -299,7 +309,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess User *user = NULL; const char *type, *class, *seat, *tty, *display, *remote_user, *remote_host, *service; uint32_t uid, leader, audit_id = 0; - dbus_bool_t remote, kill_processes; + dbus_bool_t remote, kill_processes, exists; char **controllers = NULL, **reset_controllers = NULL; SessionType t; SessionClass c; @@ -407,8 +417,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess if (vtnr != 0) return -EINVAL; - } else if (!isempty(tty) && s && seat_is_vtconsole(s)) - return -EINVAL; + } if (s) { if (seat_can_multi_session(s)) { @@ -517,6 +526,8 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess seat = session->seat ? session->seat->id : ""; vtnr = session->vtnr; + exists = true; + b = dbus_message_append_args( reply, DBUS_TYPE_STRING, &session->id, @@ -525,6 +536,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess DBUS_TYPE_UNIX_FD, &fifo_fd, DBUS_TYPE_STRING, &seat, DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_BOOLEAN, &exists, DBUS_TYPE_INVALID); free(p); @@ -641,6 +653,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess } seat = s ? s->id : ""; + exists = false; b = dbus_message_append_args( reply, DBUS_TYPE_STRING, &session->id, @@ -649,6 +662,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess DBUS_TYPE_UNIX_FD, &fifo_fd, DBUS_TYPE_STRING, &seat, DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_BOOLEAN, &exists, DBUS_TYPE_INVALID); free(p); @@ -729,12 +743,13 @@ static int bus_manager_inhibit(Manager *m, DBusConnection *connection, DBusMessa } r = verify_polkit(connection, message, - w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") : - w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") : - w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" : - w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" : - w == INHIBIT_HANDLE_SLEEP_KEY ? "org.freedesktop.login1.inhibit-handle-sleep-key" : - "org.freedesktop.login1.inhibit-handle-lid-switch", + w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") : + w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") : + w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" : + w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" : + w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" : + w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" : + "org.freedesktop.login1.inhibit-handle-lid-switch", false, NULL, error); if (r < 0) goto fail; @@ -956,24 +971,17 @@ static int flush_devices(Manager *m) { } static int have_multiple_sessions( - DBusConnection *connection, Manager *m, - DBusMessage *message, - DBusError *error) { + uid_t uid) { Session *session; Iterator i; - unsigned long ul; assert(m); - ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), error); - if (ul == (unsigned long) -1) - return -EIO; - /* Check for other users' sessions. Greeter sessions do not count. */ HASHMAP_FOREACH(session, m->sessions, i) - if (session->class == SESSION_USER && session->user->uid != ul) + if (session->class == SESSION_USER && session->user->uid != uid) return true; return false; @@ -1053,6 +1061,7 @@ static int bus_manager_can_shutdown_or_sleep( const char *action_multiple_sessions, const char *action_ignore_inhibit, const char *sleep_type, + const char *sleep_disk_type, DBusError *error, DBusMessage **_reply) { @@ -1060,6 +1069,7 @@ static int bus_manager_can_shutdown_or_sleep( const char *result; DBusMessage *reply = NULL; int r; + unsigned long ul; assert(m); assert(connection); @@ -1083,12 +1093,27 @@ static int bus_manager_can_shutdown_or_sleep( } } - r = have_multiple_sessions(connection, m, message, error); + if (sleep_disk_type) { + r = can_sleep_disk(sleep_disk_type); + if (r < 0) + return r; + + if (r == 0) { + result = "na"; + goto finish; + } + } + + ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), error); + if (ul == (unsigned long) -1) + return -EIO; + + r = have_multiple_sessions(m, (uid_t) ul); if (r < 0) return r; multiple_sessions = r > 0; - blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false); + blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, (uid_t) ul); if (multiple_sessions) { r = verify_polkit(connection, message, action_multiple_sessions, false, &challenge, error); @@ -1180,8 +1205,7 @@ static int bus_manager_log_shutdown( q = NULL; } - return log_struct(LOG_NOTICE, - "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(SD_MESSAGE_SHUTDOWN), + return log_struct(LOG_NOTICE, MESSAGE_ID(SD_MESSAGE_SHUTDOWN), p, q, NULL); } @@ -1202,7 +1226,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); + manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0); if (delayed) /* Shutdown is delayed, keep in mind what we @@ -1229,6 +1253,7 @@ static int bus_manager_do_shutdown_or_sleep( const char *action_multiple_sessions, const char *action_ignore_inhibit, const char *sleep_type, + const char *sleep_disk_type, DBusError *error, DBusMessage **_reply) { @@ -1236,6 +1261,7 @@ static int bus_manager_do_shutdown_or_sleep( bool multiple_sessions, blocked; DBusMessage *reply = NULL; int r; + unsigned long ul; assert(m); assert(connection); @@ -1265,12 +1291,25 @@ static int bus_manager_do_shutdown_or_sleep( return -ENOTSUP; } - r = have_multiple_sessions(connection, m, message, error); + if (sleep_disk_type) { + r = can_sleep_disk(sleep_disk_type); + if (r < 0) + return r; + + if (r == 0) + return -ENOTSUP; + } + + ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), error); + if (ul == (unsigned long) -1) + return -EIO; + + r = have_multiple_sessions(m, (uid_t) ul); if (r < 0) return r; multiple_sessions = r > 0; - blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false); + blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, (uid_t) ul); if (multiple_sessions) { r = verify_polkit(connection, message, action_multiple_sessions, interactive, NULL, error); @@ -1302,7 +1341,7 @@ static int bus_manager_do_shutdown_or_sleep( return 0; } -static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_handle_button, handle_button, HandleButton); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_handle_action, handle_action, HandleAction); static const BusProperty bus_login_manager_properties[] = { { "ControlGroupHierarchy", bus_property_append_string, "s", offsetof(Manager, cgroup_path), true }, @@ -1318,9 +1357,12 @@ static const BusProperty bus_login_manager_properties[] = { { "BlockInhibited", bus_manager_append_inhibited, "s", 0 }, { "DelayInhibited", bus_manager_append_inhibited, "s", 0 }, { "InhibitDelayMaxUSec", bus_property_append_usec, "t", offsetof(Manager, inhibit_delay_max) }, - { "HandlePowerKey", bus_manager_append_handle_button, "s", offsetof(Manager, handle_power_key) }, - { "HandleSleepKey", bus_manager_append_handle_button, "s", offsetof(Manager, handle_sleep_key) }, - { "HandleLidSwitch", bus_manager_append_handle_button, "s", offsetof(Manager, handle_lid_switch) }, + { "HandlePowerKey", bus_manager_append_handle_action, "s", offsetof(Manager, handle_power_key) }, + { "HandleSuspendKey", bus_manager_append_handle_action, "s", offsetof(Manager, handle_suspend_key) }, + { "HandleHibernateKey", bus_manager_append_handle_action, "s", offsetof(Manager, handle_hibernate_key)}, + { "HandleLidSwitch", bus_manager_append_handle_action, "s", offsetof(Manager, handle_lid_switch) }, + { "IdleAction", bus_manager_append_handle_action, "s", offsetof(Manager, idle_action) }, + { "IdleActionUSec", bus_property_append_usec, "t", offsetof(Manager, idle_action_usec) }, { "PreparingForShutdown", bus_manager_append_preparing, "b", 0 }, { "PreparingForSleep", bus_manager_append_preparing, "b", 0 }, { NULL, } @@ -1773,7 +1815,7 @@ static DBusHandlerResult manager_message_handler( session = hashmap_get(m->sessions, name); if (!session) - return bus_send_error_reply(connection, message, &error, -ENOENT); + return bus_send_error_reply(connection, message, NULL, -ENOENT); if (session_send_lock(session, streq(dbus_message_get_member(message), "LockSession")) < 0) goto oom; @@ -1783,12 +1825,9 @@ static DBusHandlerResult manager_message_handler( goto oom; } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "LockSessions")) { - Session *session; - Iterator i; - - HASHMAP_FOREACH(session, m->sessions, i) - if (session_send_lock(session, true) < 0) - goto oom; + r = session_send_lock_all(m, true); + if (r < 0) + bus_send_error_reply(connection, message, NULL, r); reply = dbus_message_new_method_return(message); if (!reply) @@ -2054,7 +2093,7 @@ static DBusHandlerResult manager_message_handler( "org.freedesktop.login1.power-off", "org.freedesktop.login1.power-off-multiple-sessions", "org.freedesktop.login1.power-off-ignore-inhibit", - NULL, + NULL, NULL, &error, &reply); if (r < 0) return bus_send_error_reply(connection, message, &error, r); @@ -2066,7 +2105,7 @@ static DBusHandlerResult manager_message_handler( "org.freedesktop.login1.reboot", "org.freedesktop.login1.reboot-multiple-sessions", "org.freedesktop.login1.reboot-ignore-inhibit", - NULL, + NULL, NULL, &error, &reply); if (r < 0) return bus_send_error_reply(connection, message, &error, r); @@ -2079,7 +2118,7 @@ static DBusHandlerResult manager_message_handler( "org.freedesktop.login1.suspend", "org.freedesktop.login1.suspend-multiple-sessions", "org.freedesktop.login1.suspend-ignore-inhibit", - "mem", + "mem", NULL, &error, &reply); if (r < 0) return bus_send_error_reply(connection, message, &error, r); @@ -2091,7 +2130,20 @@ static DBusHandlerResult manager_message_handler( "org.freedesktop.login1.hibernate", "org.freedesktop.login1.hibernate-multiple-sessions", "org.freedesktop.login1.hibernate-ignore-inhibit", - "disk", + "disk", NULL, + &error, &reply); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "HybridSleep")) { + r = bus_manager_do_shutdown_or_sleep( + m, connection, message, + SPECIAL_HYBRID_SLEEP_TARGET, + INHIBIT_SLEEP, + "org.freedesktop.login1.hibernate", + "org.freedesktop.login1.hibernate-multiple-sessions", + "org.freedesktop.login1.hibernate-ignore-inhibit", + "disk", "suspend", &error, &reply); if (r < 0) return bus_send_error_reply(connection, message, &error, r); @@ -2104,7 +2156,7 @@ static DBusHandlerResult manager_message_handler( "org.freedesktop.login1.power-off", "org.freedesktop.login1.power-off-multiple-sessions", "org.freedesktop.login1.power-off-ignore-inhibit", - NULL, + NULL, NULL, &error, &reply); if (r < 0) return bus_send_error_reply(connection, message, &error, r); @@ -2115,7 +2167,7 @@ static DBusHandlerResult manager_message_handler( "org.freedesktop.login1.reboot", "org.freedesktop.login1.reboot-multiple-sessions", "org.freedesktop.login1.reboot-ignore-inhibit", - NULL, + NULL, NULL, &error, &reply); if (r < 0) return bus_send_error_reply(connection, message, &error, r); @@ -2127,7 +2179,7 @@ static DBusHandlerResult manager_message_handler( "org.freedesktop.login1.suspend", "org.freedesktop.login1.suspend-multiple-sessions", "org.freedesktop.login1.suspend-ignore-inhibit", - "mem", + "mem", NULL, &error, &reply); if (r < 0) return bus_send_error_reply(connection, message, &error, r); @@ -2139,7 +2191,19 @@ static DBusHandlerResult manager_message_handler( "org.freedesktop.login1.hibernate", "org.freedesktop.login1.hibernate-multiple-sessions", "org.freedesktop.login1.hibernate-ignore-inhibit", - "disk", + "disk", NULL, + &error, &reply); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanHybridSleep")) { + r = bus_manager_can_shutdown_or_sleep( + m, connection, message, + INHIBIT_SLEEP, + "org.freedesktop.login1.hibernate", + "org.freedesktop.login1.hibernate-multiple-sessions", + "org.freedesktop.login1.hibernate-ignore-inhibit", + "disk", "suspend", &error, &reply); if (r < 0) return bus_send_error_reply(connection, message, &error, r); @@ -2216,8 +2280,8 @@ static DBusHandlerResult manager_message_handler( } if (reply) { - if (!dbus_connection_send(connection, reply, NULL)) - goto oom; + if (!bus_maybe_send_reply(connection, message, reply)) + goto oom; dbus_message_unref(reply); } @@ -2303,7 +2367,7 @@ int manager_dispatch_delayed(Manager *manager) { /* Continue delay? */ delayed = manager->delayed_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC) && - manager_is_inhibited(manager, manager->delayed_what, INHIBIT_DELAY, NULL, false); + manager_is_inhibited(manager, manager->delayed_what, INHIBIT_DELAY, NULL, false, false, 0); if (delayed) return 0;