From cf82fda94ea18432682970b0e873aa03263c4dde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 31 May 2017 22:10:15 -0400 Subject: [PATCH 1/3] logind: nicer error message when we cannot guess the caller's session Partial fix for #6032. --- src/login/logind-dbus.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index c6be596af3..c9b7d99818 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -65,6 +65,9 @@ int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const ch return r; r = sd_bus_creds_get_session(creds, &name); + if (r == -ENXIO) + return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, + "Caller does not belong to any known session"); if (r < 0) return r; } From bdb07fa5aca84cf6d092607e0e9d42f4bfeaa200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 31 May 2017 22:23:30 -0400 Subject: [PATCH 2/3] loginctl: use $XDG_SESSION_ID for "our" session Instead of always letting logind guess what the caller's session is, let's give it the value from $XDG_SESSION_ID when it is present in the caller's environment. Nowadays terminal emulators are often running as services under systemd --user, and not as part of an actual session, so all loginctl calls which depend on logind guessing the session will fail. I don't see a reason not to honour $XDG_SESSION_ID. This applies to LockSession, UnlockSession, TerminateSession, ActivateSession, SetUserLinger. Fixes #6032. --- src/login/loginctl.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/login/loginctl.c b/src/login/loginctl.c index be7acbb54c..04c2a070ac 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -1074,12 +1074,11 @@ static int activate(int argc, char *argv[], void *userdata) { polkit_agent_open_if_enabled(); if (argc < 2) { - /* No argument? Let's convert this into the empty - * session name, which the calls will then resolve to - * the caller's session. */ + /* No argument? Let's either use $XDG_SESSION_ID (if specified), or an empty + * session name, in which case logind will try to guess our session. */ short_argv[0] = argv[0]; - short_argv[1] = (char*) ""; + short_argv[1] = getenv("XDG_SESSION_ID") ?: (char*) ""; short_argv[2] = NULL; argv = short_argv; @@ -1155,8 +1154,11 @@ static int enable_linger(int argc, char *argv[], void *userdata) { b = streq(argv[0], "enable-linger"); if (argc < 2) { + /* No argument? Let's either use $XDG_SESSION_ID (if specified), or an empty + * session name, in which case logind will try to guess our session. */ + short_argv[0] = argv[0]; - short_argv[1] = (char*) ""; + short_argv[1] = getenv("XDG_SESSION_ID") ?: (char*) ""; short_argv[2] = NULL; argv = short_argv; argc = 2; From 9cf8e2087b237c15f9df969f910555f1f9d43956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 31 May 2017 22:42:14 -0400 Subject: [PATCH 3/3] loginctl: also use $XDG_SESSION_ID for session-status --- src/login/loginctl.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 04c2a070ac..1862e8983c 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -907,6 +907,8 @@ static int show_session(int argc, char *argv[], void *userdata) { bool properties, new_line = false; sd_bus *bus = userdata; int r, i; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_free_ char *path = NULL; assert(bus); assert(argv); @@ -916,19 +918,27 @@ static int show_session(int argc, char *argv[], void *userdata) { pager_open(arg_no_pager, false); if (argc <= 1) { - /* If not argument is specified inspect the manager - * itself */ + const char *session, *p = "/org/freedesktop/login1/session/self"; + if (properties) + /* If no argument is specified inspect the manager itself */ return show_properties(bus, "/org/freedesktop/login1", &new_line); /* And in the pretty case, show data of the calling session */ - return print_session_status_info(bus, "/org/freedesktop/login1/session/self", &new_line); + session = getenv("XDG_SESSION_ID"); + if (session) { + r = get_session_path(bus, session, &error, &path); + if (r < 0) { + log_error("Failed to get session path: %s", bus_error_message(&error, r)); + return r; + } + p = path; + } + + return print_session_status_info(bus, p, &new_line); } for (i = 1; i < argc; i++) { - _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_free_ char *path = NULL; - r = get_session_path(bus, argv[i], &error, &path); if (r < 0) { log_error("Failed to get session path: %s", bus_error_message(&error, r));