summaryrefslogtreecommitdiff
path: root/src/login/logind-dbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/login/logind-dbus.c')
-rw-r--r--src/login/logind-dbus.c113
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;
}