diff options
Diffstat (limited to 'src/login/logind-dbus.c')
-rw-r--r-- | src/login/logind-dbus.c | 113 |
1 files changed, 62 insertions, 51 deletions
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index acf50e62e..44f08c583 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -775,6 +775,9 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus } while (hashmap_get(m->sessions, id)); } + /* If we are not watching utmp aleady, try again */ + manager_reconnect_utmp(m); + r = manager_add_user_by_uid(m, uid, &user); if (r < 0) goto fail; @@ -784,9 +787,8 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus goto fail; session_set_user(session, user); + session_set_leader(session, leader); - session->leader = leader; - session->audit_id = audit_id; session->type = t; session->class = c; session->remote = remote; @@ -798,6 +800,8 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus r = -ENOMEM; goto fail; } + + session->tty_validity = TTY_FROM_PAM; } if (!isempty(display)) { @@ -848,9 +852,9 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus r = sd_bus_message_enter_container(message, 'a', "(sv)"); if (r < 0) - return r; + goto fail; - r = session_start(session, message); + r = session_start(session, message, error); if (r < 0) goto fail; @@ -1842,8 +1846,9 @@ static int method_do_shutdown_or_sleep( #if 0 /// Within elogind the manager m must be provided, too r = can_sleep(sleep_verb); if (r == -ENOSPC) - return sd_bus_error_set(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, - "Not enough swap space for hibernation"); + return sd_bus_error_set(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Not enough swap space for hibernation"); + if (r == -EADV) + return sd_bus_error_set(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Resume not configured, can't hibernate"); if (r == 0) return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb \"%s\" not supported", sleep_verb); @@ -2285,6 +2290,7 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd if (cancelled && m->enable_wall_messages) { _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; + _cleanup_free_ char *username = NULL; const char *tty = NULL; uid_t uid = 0; int r; @@ -2295,9 +2301,10 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd (void) sd_bus_creds_get_tty(creds, &tty); } + username = uid_to_name(uid); #if 0 /// elogind wants to allow extra cancellation messages utmp_wall("The system shutdown has been cancelled", - uid_to_name(uid), tty, logind_wall_tty_filter, m); + username, tty, logind_wall_tty_filter, m); #else r = asprintf(&l, "%s%sThe system shutdown has been cancelled!", strempty(m->wall_message), @@ -2345,7 +2352,7 @@ static int method_can_shutdown_or_sleep( #else r = can_sleep(m, sleep_verb); #endif // 0 - if (IN_SET(r, 0, -ENOSPC)) + if (IN_SET(r, 0, -ENOSPC, -EADV)) return sd_bus_reply_method_return(message, "s", "na"); if (r < 0) return r; @@ -2367,7 +2374,6 @@ static int method_can_shutdown_or_sleep( blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL); handle = handle_action_from_string(sleep_verb); - if (handle >= 0) { #if 0 /// elogind uses its own variant, which can use the handle directly. const char *target; @@ -2385,7 +2391,6 @@ static int method_can_shutdown_or_sleep( goto finish; } } - } #else log_debug_elogind("CanShutDownOrSleep: %s [%d] %s blocked", sleep_verb, handle, blocked ? "is" : "not"); @@ -2819,6 +2824,7 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("UserStopDelayUSec", "t", NULL, offsetof(Manager, user_stop_delay), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST), @@ -2900,24 +2906,20 @@ const sd_bus_vtable manager_vtable[] = { #if 0 /// UNNEEDED by elogind static int session_jobs_reply(Session *s, const char *unit, const char *result) { - int r = 0; - assert(s); assert(unit); if (!s->started) - return r; + return 0; - if (streq(result, "done")) - r = session_send_create_reply(s, NULL); - else { + if (result && !streq(result, "done")) { _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL; - sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result); - r = session_send_create_reply(s, &e); + sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit '%s' failed with '%s'", unit, result); + return session_send_create_reply(s, &e); } - return r; + return session_send_create_reply(s, NULL); } int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -2950,30 +2952,29 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err } session = hashmap_get(m->session_units, unit); - if (session && streq_ptr(path, session->scope_job)) { - session->scope_job = mfree(session->scope_job); - session_jobs_reply(session, unit, result); + if (session) { + if (streq_ptr(path, session->scope_job)) { + session->scope_job = mfree(session->scope_job); + (void) session_jobs_reply(session, unit, result); + + session_save(session); + user_save(session->user); + } - session_save(session); - user_save(session->user); session_add_to_gc_queue(session); } user = hashmap_get(m->user_units, unit); - if (user && - (streq_ptr(path, user->service_job) || - streq_ptr(path, user->slice_job))) { - - if (streq_ptr(path, user->service_job)) + if (user) { + if (streq_ptr(path, user->service_job)) { user->service_job = mfree(user->service_job); - if (streq_ptr(path, user->slice_job)) - user->slice_job = mfree(user->slice_job); + LIST_FOREACH(sessions_by_user, session, user->sessions) + (void) session_jobs_reply(session, unit, NULL /* don't propagate user service failures to the client */); - LIST_FOREACH(sessions_by_user, session, user->sessions) - session_jobs_reply(session, unit, result); + user_save(user); + } - user_save(user); user_add_to_gc_queue(user); } @@ -3107,13 +3108,15 @@ int manager_start_scope( pid_t pid, const char *slice, const char *description, - const char *after, - const char *after2, + char **wants, + char **after, + const char *requires_mounts_for, sd_bus_message *more_properties, sd_bus_error *error, char **job) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; + char **i; int r; assert(manager); @@ -3151,14 +3154,20 @@ int manager_start_scope( return r; } - if (!isempty(after)) { - r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after); + STRV_FOREACH(i, wants) { + r = sd_bus_message_append(m, "(sv)", "Wants", "as", 1, *i); if (r < 0) return r; } - if (!isempty(after2)) { - r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2); + STRV_FOREACH(i, after) { + r = sd_bus_message_append(m, "(sv)", "After", "as", 1, *i); + if (r < 0) + return r; + } + + if (!empty_or_root(requires_mounts_for)) { + r = sd_bus_message_append(m, "(sv)", "RequiresMountsFor", "as", 1, requires_mounts_for); if (r < 0) return r; } @@ -3255,7 +3264,8 @@ int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, c return strdup_job(reply, job); } -int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error) { +int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *ret_error) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_free_ char *path = NULL; int r; @@ -3272,17 +3282,16 @@ int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *err path, "org.freedesktop.systemd1.Scope", "Abandon", - error, + &error, NULL, NULL); if (r < 0) { - if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) || - sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED) || - sd_bus_error_has_name(error, BUS_ERROR_SCOPE_NOT_RUNNING)) { - sd_bus_error_free(error); + if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) || + sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED) || + sd_bus_error_has_name(&error, BUS_ERROR_SCOPE_NOT_RUNNING)) return 0; - } + sd_bus_error_move(ret_error, &error); return r; } @@ -3304,7 +3313,7 @@ int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo "ssi", unit, who == KILL_LEADER ? "main" : "all", signo); } -int manager_unit_is_active(Manager *manager, const char *unit) { +int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *ret_error) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_free_ char *path = NULL; @@ -3340,17 +3349,18 @@ int manager_unit_is_active(Manager *manager, const char *unit) { sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED)) return false; + sd_bus_error_move(ret_error, &error); return r; } r = sd_bus_message_read(reply, "s", &state); if (r < 0) - return -EINVAL; + return r; - return !streq(state, "inactive") && !streq(state, "failed"); + return !STR_IN_SET(state, "inactive", "failed"); } -int manager_job_is_active(Manager *manager, const char *path) { +int manager_job_is_active(Manager *manager, const char *path, sd_bus_error *ret_error) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; int r; @@ -3375,6 +3385,7 @@ int manager_job_is_active(Manager *manager, const char *path) { if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT)) return false; + sd_bus_error_move(ret_error, &error); return r; } |