summaryrefslogtreecommitdiff
path: root/src/login/logind-session-dbus.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2019-04-28 17:55:36 +0200
committerLennart Poettering <lennart@poettering.net>2019-05-24 15:05:27 +0200
commit3b92c086a8d5338e2164ffa0ae48b3d03d10cfb5 (patch)
treea8aaf4ad9f5778566018a63fd95cf37b69aa06e7 /src/login/logind-session-dbus.c
parent469df514c7e10fbfdc3abb243e0458fd44084fc2 (diff)
downloadsystemd-3b92c086a8d5338e2164ffa0ae48b3d03d10cfb5.tar.gz
logind: make "self" and "auto" magic strings when operating on seats + sessions
Most of the operations one can do on sessions so far accepted an empty session name as a shortcut for the caller's session. This is quite useful traditionally, but much less useful than it used to be, since most user code now (rightfully) runs in --user context, not in a session. With this change we tweak the logic a bit: we introduce the two special session and seat names "self" and "auto". The former refers to the session/seat the client is in, and is hence mostly equivalent to te empty string "" as before. However, the latter refers to the session/seat the client is in if that exists, with a fallback of the user's display session if not. Clients can hence reference "auto" instead of the empty string if they really don't want to think much about sessions. Why "self" btw? Previously, we'd already expose a special dbus object with the path /org/freedesktop/login1/session/self (and similar for the seat), matching what the empty string did for bus calls that took a session name. With this scheme we reuse this identifier and introduce "auto" in a similar way. Of course this means real-life seats and sessions can never be named "self" or "auto", but they aren't anyway: valid seat names have to start with "seat" anyway, and sessions are generated server-side as either a numeric value or "c" suffixed with a counter ID. Fixes: #12399
Diffstat (limited to 'src/login/logind-session-dbus.c')
-rw-r--r--src/login/logind-session-dbus.c68
1 files changed, 43 insertions, 25 deletions
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
index c6b8794096..5eb240834a 100644
--- a/src/login/logind-session-dbus.c
+++ b/src/login/logind-session-dbus.c
@@ -17,6 +17,7 @@
#include "signal-util.h"
#include "stat-util.h"
#include "strv.h"
+#include "user-util.h"
#include "util.h"
static int property_get_user(
@@ -583,8 +584,11 @@ const sd_bus_vtable session_vtable[] = {
};
int session_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
+ _cleanup_free_ char *e = NULL;
+ sd_bus_message *message;
Manager *m = userdata;
Session *session;
+ const char *p;
int r;
assert(bus);
@@ -593,32 +597,25 @@ int session_object_find(sd_bus *bus, const char *path, const char *interface, vo
assert(found);
assert(m);
- if (streq(path, "/org/freedesktop/login1/session/self")) {
- sd_bus_message *message;
-
- message = sd_bus_get_current_message(bus);
- if (!message)
- return 0;
-
- r = manager_get_session_from_creds(m, message, NULL, error, &session);
- if (r < 0)
- return r;
- } else {
- _cleanup_free_ char *e = NULL;
- const char *p;
+ p = startswith(path, "/org/freedesktop/login1/session/");
+ if (!p)
+ return 0;
- p = startswith(path, "/org/freedesktop/login1/session/");
- if (!p)
- return 0;
+ e = bus_label_unescape(p);
+ if (!e)
+ return -ENOMEM;
- e = bus_label_unescape(p);
- if (!e)
- return -ENOMEM;
+ message = sd_bus_get_current_message(bus);
+ if (!message)
+ return 0;
- session = hashmap_get(m->sessions, e);
- if (!session)
- return 0;
+ r = manager_get_session_from_creds(m, message, e, error, &session);
+ if (r == -ENXIO) {
+ sd_bus_error_free(error);
+ return 0;
}
+ if (r < 0)
+ return r;
*found = session;
return 1;
@@ -663,10 +660,12 @@ int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char
message = sd_bus_get_current_message(bus);
if (message) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- const char *name;
- r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
+ r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
if (r >= 0) {
+ bool may_auto = false;
+ const char *name;
+
r = sd_bus_creds_get_session(creds, &name);
if (r >= 0) {
session = hashmap_get(m->sessions, name);
@@ -674,13 +673,32 @@ int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char
r = strv_extend(&l, "/org/freedesktop/login1/session/self");
if (r < 0)
return r;
+
+ may_auto = true;
+ }
+ }
+
+ if (!may_auto) {
+ uid_t uid;
+
+ r = sd_bus_creds_get_owner_uid(creds, &uid);
+ if (r >= 0) {
+ User *user;
+
+ user = hashmap_get(m->users, UID_TO_PTR(uid));
+ may_auto = user && user->display;
}
}
+
+ if (may_auto) {
+ r = strv_extend(&l, "/org/freedesktop/login1/session/auto");
+ if (r < 0)
+ return r;
+ }
}
}
*nodes = TAKE_PTR(l);
-
return 1;
}