[systemd-commits] 4 commits - src/bus-proxyd src/core src/libsystemd src/login

David Herrmann dvdhrm at kemper.freedesktop.org
Sun Jan 18 05:03:59 PST 2015


 src/bus-proxyd/bus-proxyd.c         |   12 ++++++++----
 src/bus-proxyd/driver.c             |    2 +-
 src/bus-proxyd/proxy.c              |   32 ++++++++++++++++----------------
 src/bus-proxyd/stdio-bridge.c       |    4 ++--
 src/core/selinux-access.c           |    6 +++---
 src/libsystemd/sd-bus/bus-control.c |   16 ++++++++--------
 src/libsystemd/sd-bus/bus-message.c |   12 ++++++------
 src/libsystemd/sd-bus/busctl.c      |    4 ++--
 src/login/logind-dbus.c             |   12 ++++++------
 src/login/logind-seat-dbus.c        |   23 ++++++++++++++++++++---
 src/login/logind-session-dbus.c     |   30 +++++++++++++++++++++++-------
 src/login/logind-user-dbus.c        |   22 +++++++++++++++++++---
 12 files changed, 114 insertions(+), 61 deletions(-)

New commits:
commit 05bae4a60c32e29797597979cee2f3684eb3bc1e
Author: David Herrmann <dh.herrmann at gmail.com>
Date:   Sun Jan 18 13:55:55 2015 +0100

    bus: use EUID over UID and fix unix-creds
    
    Whenever a process performs an action on an object, the kernel uses the
    EUID of the process to do permission checks and to apply on any newly
    created objects. The UID of a process is only used if someone *ELSE* acts
    on the process. That is, the UID of a process defines who owns the
    process, the EUID defines what privileges are used by this process when
    performing an action.
    
    Process limits, on the other hand, are always applied to the real UID, not
    the effective UID. This is, because a process has a user object linked,
    which always corresponds to its UID. A process never has a user object
    linked for its EUID. Thus, accounting (and limits) is always done on the
    real UID.
    
    This commit fixes all sd-bus users to use the EUID when performing
    privilege checks and alike. Furthermore, it fixes unix-creds to be parsed
    as EUID, not UID (as the kernel always takes the EUID on UDS). Anyone
    using UID (eg., to do user-accounting) has to fall back to the EUID as UDS
    does not transmit the UID.

diff --git a/src/bus-proxyd/driver.c b/src/bus-proxyd/driver.c
index 361b14c..b2a4456 100644
--- a/src/bus-proxyd/driver.c
+++ b/src/bus-proxyd/driver.c
@@ -252,7 +252,7 @@ int bus_proxy_process_driver(sd_bus *a, sd_bus *b, sd_bus_message *m, SharedPoli
                 if (!sd_bus_message_has_signature(m, "s"))
                         return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
 
-                r = get_creds_by_message(a, m, SD_BUS_CREDS_UID, &creds, &error);
+                r = get_creds_by_message(a, m, SD_BUS_CREDS_EUID, &creds, &error);
                 if (r < 0)
                         return synthetic_reply_method_errno(m, r, &error);
 
diff --git a/src/bus-proxyd/proxy.c b/src/bus-proxyd/proxy.c
index 329188e..bd02ee1 100644
--- a/src/bus-proxyd/proxy.c
+++ b/src/bus-proxyd/proxy.c
@@ -73,7 +73,7 @@ static int proxy_create_dest(Proxy *p, const char *dest, const char *local_sec,
         if (r < 0)
                 return log_error_errno(r, "Failed to set FD negotiation: %m");
 
-        r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT);
+        r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SELINUX_CONTEXT);
         if (r < 0)
                 return log_error_errno(r, "Failed to set credential negotiation: %m");
 
@@ -134,7 +134,7 @@ static int proxy_create_local(Proxy *p, int in_fd, int out_fd, bool negotiate_fd
         if (r < 0)
                 return log_error_errno(r, "Failed to set FD negotiation: %m");
 
-        r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT);
+        r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SELINUX_CONTEXT);
         if (r < 0)
                 return log_error_errno(r, "Failed to set credential negotiation: %m");
 
@@ -433,8 +433,8 @@ static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m,
                 /* The message came from the kernel, and is sent to our legacy client. */
                 sd_bus_creds_get_well_known_names(&m->creds, &sender_names);
 
-                (void) sd_bus_creds_get_uid(&m->creds, &sender_uid);
-                (void) sd_bus_creds_get_gid(&m->creds, &sender_gid);
+                (void) sd_bus_creds_get_euid(&m->creds, &sender_uid);
+                (void) sd_bus_creds_get_egid(&m->creds, &sender_gid);
 
                 if (sender_uid == UID_INVALID || sender_gid == GID_INVALID) {
                         _cleanup_bus_creds_unref_ sd_bus_creds *sender_creds = NULL;
@@ -446,12 +446,12 @@ static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m,
                          * case, query the creds of the peer
                          * instead. */
 
-                        r = bus_get_name_creds_kdbus(from, m->sender, SD_BUS_CREDS_UID|SD_BUS_CREDS_GID, true, &sender_creds);
+                        r = bus_get_name_creds_kdbus(from, m->sender, SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID, true, &sender_creds);
                         if (r < 0)
                                 return handle_policy_error(m, r);
 
-                        (void) sd_bus_creds_get_uid(sender_creds, &sender_uid);
-                        (void) sd_bus_creds_get_gid(sender_creds, &sender_gid);
+                        (void) sd_bus_creds_get_euid(sender_creds, &sender_uid);
+                        (void) sd_bus_creds_get_egid(sender_creds, &sender_gid);
                 }
 
                 /* First check whether the sender can send the message to our name */
@@ -483,7 +483,7 @@ static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m,
                 if (m->destination) {
                         r = bus_get_name_creds_kdbus(to, m->destination,
                                                      SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME|
-                                                     SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID,
+                                                     SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_PID,
                                                      true, &destination_creds);
                         if (r < 0)
                                 return handle_policy_error(m, r);
@@ -494,8 +494,8 @@ static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m,
 
                         sd_bus_creds_get_well_known_names(destination_creds, &destination_names);
 
-                        (void) sd_bus_creds_get_uid(destination_creds, &destination_uid);
-                        (void) sd_bus_creds_get_gid(destination_creds, &destination_gid);
+                        (void) sd_bus_creds_get_euid(destination_creds, &destination_uid);
+                        (void) sd_bus_creds_get_egid(destination_creds, &destination_gid);
                 }
 
                 /* First check if we (the sender) can send to this name */
diff --git a/src/bus-proxyd/stdio-bridge.c b/src/bus-proxyd/stdio-bridge.c
index c17047b..6fb8303 100644
--- a/src/bus-proxyd/stdio-bridge.c
+++ b/src/bus-proxyd/stdio-bridge.c
@@ -174,11 +174,11 @@ static int rename_service(sd_bus *a, sd_bus *b) {
         assert(a);
         assert(b);
 
-        r = sd_bus_get_owner_creds(b, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_AUGMENT, &creds);
+        r = sd_bus_get_owner_creds(b, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_AUGMENT, &creds);
         if (r < 0)
                 return r;
 
-        r = sd_bus_creds_get_uid(creds, &uid);
+        r = sd_bus_creds_get_euid(creds, &uid);
         if (r < 0)
                 return r;
 
diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c
index b45a451..f638958 100644
--- a/src/core/selinux-access.c
+++ b/src/core/selinux-access.c
@@ -70,9 +70,9 @@ static int audit_callback(
 
         if (sd_bus_creds_get_audit_login_uid(audit->creds, &login_uid) >= 0)
                 snprintf(login_uid_buf, sizeof(login_uid_buf), UID_FMT, login_uid);
-        if (sd_bus_creds_get_uid(audit->creds, &uid) >= 0)
+        if (sd_bus_creds_get_euid(audit->creds, &uid) >= 0)
                 snprintf(uid_buf, sizeof(uid_buf), UID_FMT, uid);
-        if (sd_bus_creds_get_gid(audit->creds, &gid) >= 0)
+        if (sd_bus_creds_get_egid(audit->creds, &gid) >= 0)
                 snprintf(gid_buf, sizeof(gid_buf), GID_FMT, gid);
 
         snprintf(msgbuf, msgbufsize,
@@ -203,7 +203,7 @@ int mac_selinux_generic_access_check(
 
         r = sd_bus_query_sender_creds(
                         message,
-                        SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|
+                        SD_BUS_CREDS_PID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID|
                         SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_AUDIT_LOGIN_UID|
                         SD_BUS_CREDS_SELINUX_CONTEXT|
                         SD_BUS_CREDS_AUGMENT /* get more bits from /proc */,
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index b450140..35c79cf 100644
--- a/src/libsystemd/sd-bus/bus-control.c
+++ b/src/libsystemd/sd-bus/bus-control.c
@@ -762,7 +762,7 @@ static int bus_get_name_creds_dbus1(
 
                 if ((mask & SD_BUS_CREDS_PID) ||
                     ((mask & SD_BUS_CREDS_AUGMENT) &&
-                     (mask & (SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
+                     (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
                               SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
                               SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
                               SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID|
@@ -798,7 +798,7 @@ static int bus_get_name_creds_dbus1(
                         reply = sd_bus_message_unref(reply);
                 }
 
-                if (mask & SD_BUS_CREDS_UID) {
+                if (mask & SD_BUS_CREDS_EUID) {
                         uint32_t u;
 
                         r = sd_bus_call_method(
@@ -818,8 +818,8 @@ static int bus_get_name_creds_dbus1(
                         if (r < 0)
                                 return r;
 
-                        c->uid = u;
-                        c->mask |= SD_BUS_CREDS_UID;
+                        c->euid = u;
+                        c->mask |= SD_BUS_CREDS_EUID;
 
                         reply = sd_bus_message_unref(reply);
                 }
@@ -961,13 +961,13 @@ static int bus_get_owner_creds_dbus1(sd_bus *bus, uint64_t mask, sd_bus_creds **
                 }
 
                 if (bus->ucred.uid != UID_INVALID) {
-                        c->uid = bus->ucred.uid;
-                        c->mask |= SD_BUS_CREDS_UID & mask;
+                        c->euid = bus->ucred.uid;
+                        c->mask |= SD_BUS_CREDS_EUID & mask;
                 }
 
                 if (bus->ucred.gid != GID_INVALID) {
-                        c->gid = bus->ucred.gid;
-                        c->mask |= SD_BUS_CREDS_GID & mask;
+                        c->egid = bus->ucred.gid;
+                        c->mask |= SD_BUS_CREDS_EGID & mask;
                 }
         }
 
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index f352c72..23076d2 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -424,19 +424,19 @@ int bus_message_from_header(
 
         if (ucred) {
                 m->creds.pid = ucred->pid;
-                m->creds.uid = ucred->uid;
-                m->creds.gid = ucred->gid;
+                m->creds.euid = ucred->uid;
+                m->creds.egid = ucred->gid;
 
                 /* Due to namespace translations some data might be
                  * missing from this ucred record. */
                 if (m->creds.pid > 0)
                         m->creds.mask |= SD_BUS_CREDS_PID;
 
-                if (m->creds.uid != UID_INVALID)
-                        m->creds.mask |= SD_BUS_CREDS_UID;
+                if (m->creds.euid != UID_INVALID)
+                        m->creds.mask |= SD_BUS_CREDS_EUID;
 
-                if (m->creds.gid != GID_INVALID)
-                        m->creds.mask |= SD_BUS_CREDS_GID;
+                if (m->creds.egid != GID_INVALID)
+                        m->creds.mask |= SD_BUS_CREDS_EGID;
         }
 
         if (label) {
diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c
index c0d51e0..f0bc2a7 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/libsystemd/sd-bus/busctl.c
@@ -160,7 +160,7 @@ static int list_bus_names(sd_bus *bus, char **argv) {
                 r = sd_bus_get_name_creds(
                                 bus, *i,
                                 (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) |
-                                SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|
+                                SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|
                                 SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_SESSION|
                                 SD_BUS_CREDS_DESCRIPTION, &creds);
                 if (r >= 0) {
@@ -178,7 +178,7 @@ static int list_bus_names(sd_bus *bus, char **argv) {
                         } else
                                 fputs("          - -              ", stdout);
 
-                        r = sd_bus_creds_get_uid(creds, &uid);
+                        r = sd_bus_creds_get_euid(creds, &uid);
                         if (r >= 0) {
                                 _cleanup_free_ char *u = NULL;
 
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index bc985a3..f2f91d5 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -1606,11 +1606,11 @@ static int method_do_shutdown_or_sleep(
                         return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
         }
 
-        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
+        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
         if (r < 0)
                 return r;
 
-        r = sd_bus_creds_get_uid(creds, &uid);
+        r = sd_bus_creds_get_euid(creds, &uid);
         if (r < 0)
                 return r;
 
@@ -1759,11 +1759,11 @@ static int method_can_shutdown_or_sleep(
                         return sd_bus_reply_method_return(message, "s", "na");
         }
 
-        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
+        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
         if (r < 0)
                 return r;
 
-        r = sd_bus_creds_get_uid(creds, &uid);
+        r = sd_bus_creds_get_euid(creds, &uid);
         if (r < 0)
                 return r;
 
@@ -1938,11 +1938,11 @@ static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata,
         if (r == 0)
                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
 
-        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
+        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
         if (r < 0)
                 return r;
 
-        r = sd_bus_creds_get_uid(creds, &uid);
+        r = sd_bus_creds_get_euid(creds, &uid);
         if (r < 0)
                 return r;
 
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
index e3486fe..4e7edef 100644
--- a/src/login/logind-session-dbus.c
+++ b/src/login/logind-session-dbus.c
@@ -239,11 +239,11 @@ static int method_set_idle_hint(sd_bus *bus, sd_bus_message *message, void *user
         if (r < 0)
                 return r;
 
-        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
+        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
         if (r < 0)
                 return r;
 
-        r = sd_bus_creds_get_uid(creds, &uid);
+        r = sd_bus_creds_get_euid(creds, &uid);
         if (r < 0)
                 return r;
 
@@ -302,11 +302,11 @@ static int method_take_control(sd_bus *bus, sd_bus_message *message, void *userd
         if (r < 0)
                 return r;
 
-        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
+        r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
         if (r < 0)
                 return r;
 
-        r = sd_bus_creds_get_uid(creds, &uid);
+        r = sd_bus_creds_get_euid(creds, &uid);
         if (r < 0)
                 return r;
 

commit e23f4bb525991c5908be0d0e7f8374c964d9996c
Author: David Herrmann <dh.herrmann at gmail.com>
Date:   Sun Jan 18 13:54:46 2015 +0100

    bus-proxy: fake all UIDs/GIDs, not just the real UID/GID
    
    Make sure we tell the kernel to fake all UIDs/GIDs. Otherwise, the remote
    side has no chance of querying our effective UID (which is usually what
    they're interested in).

diff --git a/src/bus-proxyd/proxy.c b/src/bus-proxyd/proxy.c
index f7daec6..329188e 100644
--- a/src/bus-proxyd/proxy.c
+++ b/src/bus-proxyd/proxy.c
@@ -82,13 +82,13 @@ static int proxy_create_dest(Proxy *p, const char *dest, const char *local_sec,
                 b->fake_pids_valid = true;
 
                 b->fake_creds.uid = p->local_creds.uid;
-                b->fake_creds.euid = UID_INVALID;
-                b->fake_creds.suid = UID_INVALID;
-                b->fake_creds.fsuid = UID_INVALID;
+                b->fake_creds.euid = p->local_creds.uid;
+                b->fake_creds.suid = p->local_creds.uid;
+                b->fake_creds.fsuid = p->local_creds.uid;
                 b->fake_creds.gid = p->local_creds.gid;
-                b->fake_creds.egid = GID_INVALID;
-                b->fake_creds.sgid = GID_INVALID;
-                b->fake_creds.fsgid = GID_INVALID;
+                b->fake_creds.egid = p->local_creds.gid;
+                b->fake_creds.sgid = p->local_creds.gid;
+                b->fake_creds.fsgid = p->local_creds.gid;
                 b->fake_creds_valid = true;
         }
 

commit d340f82032e4eb538e7b79087d95d5af1ae3dd91
Author: David Herrmann <dh.herrmann at gmail.com>
Date:   Sun Jan 18 13:07:21 2015 +0100

    bus-proxy: fix bus-uid tracking
    
    We need to implicitly allow HELLO from users with the same uid as the bus.
    Fix the bus-uid tracking to use the original uid, not the uid after
    privilege-dropping.

diff --git a/src/bus-proxyd/bus-proxyd.c b/src/bus-proxyd/bus-proxyd.c
index 3cf35f4..8cc4412 100644
--- a/src/bus-proxyd/bus-proxyd.c
+++ b/src/bus-proxyd/bus-proxyd.c
@@ -62,6 +62,7 @@ static char **arg_configuration = NULL;
 typedef struct {
         int fd;
         SharedPolicy *policy;
+        uid_t bus_uid;
 } ClientContext;
 
 static ClientContext *client_context_free(ClientContext *c) {
@@ -110,7 +111,7 @@ static void *run_client(void *userdata) {
         if (r < 0)
                 goto exit;
 
-        r = proxy_hello_policy(p, getuid());
+        r = proxy_hello_policy(p, c->bus_uid);
         if (r < 0)
                 goto exit;
 
@@ -120,7 +121,7 @@ exit:
         return NULL;
 }
 
-static int loop_clients(int accept_fd) {
+static int loop_clients(int accept_fd, uid_t bus_uid) {
         _cleanup_(shared_policy_freep) SharedPolicy *sp = NULL;
         pthread_attr_t attr;
         int r;
@@ -164,6 +165,7 @@ static int loop_clients(int accept_fd) {
 
                 c->fd = fd;
                 c->policy = sp;
+                c->bus_uid = bus_uid;
 
                 r = pthread_create(&tid, &attr, run_client, c);
                 if (r < 0) {
@@ -294,13 +296,15 @@ static int parse_argv(int argc, char *argv[]) {
 int main(int argc, char *argv[]) {
         const char *user = "systemd-bus-proxy";
         int r, accept_fd;
-        uid_t uid;
+        uid_t uid, bus_uid;
         gid_t gid;
 
         log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
         log_parse_environment();
         log_open();
 
+        bus_uid = getuid();
+
         if (geteuid() == 0) {
                 r = get_user_creds(&user, &uid, &gid, NULL, NULL);
                 if (r < 0) {
@@ -332,7 +336,7 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        r = loop_clients(accept_fd);
+        r = loop_clients(accept_fd, bus_uid);
 
 finish:
         sd_notify(false,

commit ca56b0a68300b035c605bedc5b339128897debfc
Author: David Herrmann <dh.herrmann at gmail.com>
Date:   Sun Jan 18 12:59:39 2015 +0100

    logind: hide 'self' links if not available
    
    If the caller does not run in a session/seat or has no tracked user, hide
    the /org/freedesktop/login1/.../self links in introspection data.
    Otherwise, "busctl tree org.freedesktop.login1" tries to query those nodes
    even though it cant.

diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c
index ddf2cd8..50b0b88 100644
--- a/src/login/logind-seat-dbus.c
+++ b/src/login/logind-seat-dbus.c
@@ -381,6 +381,7 @@ char *seat_bus_path(Seat *s) {
 
 int seat_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
         _cleanup_strv_free_ char **l = NULL;
+        sd_bus_message *message;
         Manager *m = userdata;
         Seat *seat;
         Iterator i;
@@ -402,9 +403,25 @@ int seat_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***
                         return r;
         }
 
-        r = strv_extend(&l, "/org/freedesktop/login1/seat/self");
-        if (r < 0)
-                return r;
+        message = sd_bus_get_current_message(bus);
+        if (message) {
+                _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+                const char *name;
+                Session *session;
+
+                r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
+                if (r >= 0) {
+                        r = sd_bus_creds_get_session(creds, &name);
+                        if (r >= 0) {
+                                session = hashmap_get(m->sessions, name);
+                                if (session && session->seat) {
+                                        r = strv_extend(&l, "/org/freedesktop/login1/seat/self");
+                                        if (r < 0)
+                                                return r;
+                                }
+                        }
+                }
+        }
 
         *nodes = l;
         l = NULL;
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
index d341131..e3486fe 100644
--- a/src/login/logind-session-dbus.c
+++ b/src/login/logind-session-dbus.c
@@ -541,6 +541,7 @@ char *session_bus_path(Session *s) {
 
 int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
         _cleanup_strv_free_ char **l = NULL;
+        sd_bus_message *message;
         Manager *m = userdata;
         Session *session;
         Iterator i;
@@ -562,9 +563,24 @@ int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char
                         return r;
         }
 
-        r = strv_extend(&l, "/org/freedesktop/login1/session/self");
-        if (r < 0)
-                return r;
+        message = sd_bus_get_current_message(bus);
+        if (message) {
+                _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+                const char *name;
+
+                r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
+                if (r >= 0) {
+                        r = sd_bus_creds_get_session(creds, &name);
+                        if (r >= 0) {
+                                session = hashmap_get(m->sessions, name);
+                                if (session) {
+                                        r = strv_extend(&l, "/org/freedesktop/login1/session/self");
+                                        if (r < 0)
+                                                return r;
+                                }
+                        }
+                }
+        }
 
         *nodes = l;
         l = NULL;
diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c
index bff42e8..5cfaac0 100644
--- a/src/login/logind-user-dbus.c
+++ b/src/login/logind-user-dbus.c
@@ -291,6 +291,7 @@ char *user_bus_path(User *u) {
 
 int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
         _cleanup_strv_free_ char **l = NULL;
+        sd_bus_message *message;
         Manager *m = userdata;
         User *user;
         Iterator i;
@@ -312,9 +313,24 @@ int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***
                         return r;
         }
 
-        r = strv_extend(&l, "/org/freedesktop/login1/user/self");
-        if (r < 0)
-                return r;
+        message = sd_bus_get_current_message(bus);
+        if (message) {
+                _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+                uid_t uid;
+
+                r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
+                if (r >= 0) {
+                        r = sd_bus_creds_get_owner_uid(creds, &uid);
+                        if (r >= 0) {
+                                user = hashmap_get(m->users, UID_TO_PTR(uid));
+                                if (user) {
+                                        r = strv_extend(&l, "/org/freedesktop/login1/user/self");
+                                        if (r < 0)
+                                                return r;
+                                }
+                        }
+                }
+        }
 
         *nodes = l;
         l = NULL;



More information about the systemd-commits mailing list