[systemd-commits] 15 commits - TODO man/busctl.xml src/bus-proxyd src/libsystemd src/shared src/systemd

Lennart Poettering lennart at kemper.freedesktop.org
Tue Nov 25 05:28:43 PST 2014


 TODO                                    |    4 
 man/busctl.xml                          |   21 +
 src/bus-proxyd/bus-proxyd.c             |   10 
 src/libsystemd/sd-bus/bus-control.c     |  183 ++++++++++---
 src/libsystemd/sd-bus/bus-convenience.c |   25 +
 src/libsystemd/sd-bus/bus-creds.c       |  425 +++++++++++++++++++++++---------
 src/libsystemd/sd-bus/bus-creds.h       |   10 
 src/libsystemd/sd-bus/bus-dump.c        |   49 ++-
 src/libsystemd/sd-bus/bus-internal.h    |    2 
 src/libsystemd/sd-bus/bus-kernel.c      |  158 +++++++++--
 src/libsystemd/sd-bus/bus-message.c     |   14 -
 src/libsystemd/sd-bus/busctl.c          |   64 +++-
 src/libsystemd/sd-bus/kdbus.h           |  103 +++++--
 src/libsystemd/sd-bus/sd-bus.c          |    2 
 src/shared/util.c                       |    4 
 src/systemd/sd-bus.h                    |   67 +++--
 16 files changed, 861 insertions(+), 280 deletions(-)

New commits:
commit 3c575b641716a1d21cdb1a411443a96b5399b501
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 25 13:24:08 2014 +0100

    update TODO

diff --git a/TODO b/TODO
index 328a46a..0b705c1 100644
--- a/TODO
+++ b/TODO
@@ -307,7 +307,7 @@ Features:
   ReadOnlyDirectories=... for whitelisting files for a service.
 
 * sd-bus:
-  - kdbus: maybe add euid, egid, fsuid, fsgid, controlling tty and ppid metadata fields
+  - kdbus: maybe add controlling tty and ppid metadata fields
   - see if we can introduce a new sd_bus_get_owner_machine_id() call to retrieve the machine ID of the machine of the bus itself
   - when kdbus does not take our message without memfds, try again with memfds
   - systemd-bus-proxyd needs to enforce good old XML policy

commit 9f6dfd0624e44002e407a72acb0c15b7177e9a9f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 25 13:23:44 2014 +0100

    sd-bus: fix error handling when receiving invalid service name
    
    Also, properly keep track of incoming additional service names.

diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index a8adb9c..27a5910 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -646,19 +646,27 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
                         break;
 
                 case KDBUS_ITEM_DST_NAME:
-                        if (!service_name_is_valid(d->str))
-                                return -EBADMSG;
+                        if (!service_name_is_valid(d->str)) {
+                                r = -EBADMSG;
+                                goto fail;
+                        }
 
                         destination = d->str;
                         break;
 
                 case KDBUS_ITEM_OWNED_NAME:
-                        if (!service_name_is_valid(d->name.name))
-                                return -EBADMSG;
-
-                        r = strv_extend(&m->creds.well_known_names, d->name.name);
-                        if (r < 0)
+                        if (!service_name_is_valid(d->name.name)) {
+                                r = -EBADMSG;
                                 goto fail;
+                        }
+
+                        if (bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
+                                r = strv_extend(&m->creds.well_known_names, d->name.name);
+                                if (r < 0)
+                                        goto fail;
+
+                                m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
+                        }
                         break;
 
                 case KDBUS_ITEM_CONN_DESCRIPTION:

commit 6dfcc64bb5c67ec2e026715146c19acf93dab31a
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 25 13:22:55 2014 +0100

    sd-bus: properly handle non-initialized audit records attached to incoming kernel messages

diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index e66a263..a8adb9c 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -628,9 +628,15 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
                         break;
 
                 case KDBUS_ITEM_AUDIT:
-                        m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
-                        m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
-                        m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
+                        if ((uint32_t) d->audit.sessionid != (uint32_t) -1) {
+                                m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
+                                m->creds.mask |= SD_BUS_CREDS_AUDIT_SESSION_ID & bus->creds_mask;
+                        }
+
+                        if ((uid_t) d->audit.loginuid != (uid_t) -1) {
+                                m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
+                                m->creds.mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID & bus->creds_mask;
+                        }
                         break;
 
                 case KDBUS_ITEM_CAPS:

commit a6ede528c478177821423f1e61e625030a6602c0
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 25 13:22:19 2014 +0100

    sd-bus: properly copy selinux label and description field when duplicating creds object

diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c
index 7a73387..43315b5 100644
--- a/src/libsystemd/sd-bus/bus-creds.c
+++ b/src/libsystemd/sd-bus/bus-creds.c
@@ -1080,11 +1080,17 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
                 n->mask |= c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS);
         }
 
+        if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
+                n->label = strdup(c->label);
+                if (!n->label)
+                        return -ENOMEM;
+                n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+        }
+
         if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
                 n->audit_session_id = c->audit_session_id;
                 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
         }
-
         if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
                 n->audit_login_uid = c->audit_login_uid;
                 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
@@ -1094,12 +1100,21 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
                 n->unique_name = strdup(c->unique_name);
                 if (!n->unique_name)
                         return -ENOMEM;
+                n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
         }
 
         if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
                 n->well_known_names = strv_copy(c->well_known_names);
                 if (!n->well_known_names)
                         return -ENOMEM;
+                n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
+        }
+
+        if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
+                n->description = strdup(c->description);
+                if (!n->description)
+                        return -ENOMEM;
+                n->mask |= SD_BUS_CREDS_DESCRIPTION;
         }
 
         /* Get more data */

commit 0258159049d5b381c6097533a69a1b29c3ba7ce2
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 25 13:21:23 2014 +0100

    sd-bus: add supplementary groups list to creds object

diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index 0027ad3..23fb0e7 100644
--- a/src/libsystemd/sd-bus/bus-control.c
+++ b/src/libsystemd/sd-bus/bus-control.c
@@ -500,7 +500,7 @@ static int bus_populate_creds_from_items(sd_bus *bus,
 
                 case KDBUS_ITEM_CMDLINE:
                         if (mask & SD_BUS_CREDS_CMDLINE) {
-                                c->cmdline_size = item->size - KDBUS_ITEM_HEADER_SIZE;
+                                c->cmdline_size = item->size - offsetof(struct kdbus_item, data);
                                 c->cmdline = memdup(item->data, c->cmdline_size);
                                 if (!c->cmdline)
                                         return -ENOMEM;
@@ -578,7 +578,7 @@ static int bus_populate_creds_from_items(sd_bus *bus,
                         break;
 
                 case KDBUS_ITEM_CONN_DESCRIPTION:
-                        if ((mask & SD_BUS_CREDS_DESCRIPTION)) {
+                        if (mask & SD_BUS_CREDS_DESCRIPTION) {
                                 c->description = strdup(item->str);
                                 if (!c->description)
                                         return -ENOMEM;
@@ -586,6 +586,26 @@ static int bus_populate_creds_from_items(sd_bus *bus,
                                 c->mask |= SD_BUS_CREDS_DESCRIPTION;
                         }
                         break;
+
+                case KDBUS_ITEM_AUXGROUPS:
+                        if (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
+                                size_t i, n;
+                                uid_t *u;
+
+                                n = (item->size - offsetof(struct kdbus_item, data64)) / sizeof(uint64_t);
+                                u = new(uid_t, n);
+                                if (!u)
+                                        return -ENOMEM;
+
+                                for (i = 0; i < n; i++)
+                                        u[i] = (uid_t) item->data64[i];
+
+                                c->supplementary_gids = u;
+                                c->n_supplementary_gids = n;
+
+                                c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
+                        }
+                        break;
                 }
         }
 
diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c
index 02a7372..7a73387 100644
--- a/src/libsystemd/sd-bus/bus-creds.c
+++ b/src/libsystemd/sd-bus/bus-creds.c
@@ -53,6 +53,8 @@ void bus_creds_done(sd_bus_creds *c) {
 
         strv_free(c->cmdline_array);
         strv_free(c->well_known_names);
+
+        free(c->supplementary_gids);
 }
 
 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
@@ -237,7 +239,6 @@ _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
         return 0;
 }
 
-
 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
         assert_return(c, -EINVAL);
         assert_return(fsgid, -EINVAL);
@@ -249,6 +250,17 @@ _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
         return 0;
 }
 
+_public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
+        assert_return(c, -EINVAL);
+        assert_return(gids, -EINVAL);
+
+        if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
+                return -ENODATA;
+
+        *gids = c->supplementary_gids;
+        return (int) c->n_supplementary_gids;
+}
+
 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
         assert_return(c, -EINVAL);
         assert_return(pid, -EINVAL);
@@ -680,6 +692,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
 
         if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | 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_SUPPLEMENTARY_GIDS |
                        SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
                        SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
 
@@ -736,6 +749,34 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
                                         }
                                 }
 
+                                if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
+                                        p = startswith(line, "Groups:");
+                                        if (p) {
+                                                size_t allocated = 0;
+
+                                                for (;;) {
+                                                        unsigned long g;
+                                                        int n = 0;
+
+                                                        p += strspn(p, WHITESPACE);
+                                                        if (*p == 0)
+                                                                break;
+
+                                                        if (sscanf(p, "%lu%n", &g, &n) != 1)
+                                                                return -EIO;
+
+                                                        if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
+                                                                return -ENOMEM;
+
+                                                        c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
+                                                        p += n;
+                                                }
+
+                                                c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
+                                                continue;
+                                        }
+                                }
+
                                 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
                                         p = startswith(line, "CapEff:");
                                         if (p) {
@@ -962,6 +1003,14 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
                 n->mask |= SD_BUS_CREDS_FSGID;
         }
 
+        if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
+                n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
+                if (!n->supplementary_gids)
+                        return -ENOMEM;
+                n->n_supplementary_gids = c->n_supplementary_gids;
+                n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
+        }
+
         if (c->mask & mask & SD_BUS_CREDS_PID) {
                 n->pid = c->pid;
                 n->mask |= SD_BUS_CREDS_PID;
diff --git a/src/libsystemd/sd-bus/bus-creds.h b/src/libsystemd/sd-bus/bus-creds.h
index 15821a5..882110b 100644
--- a/src/libsystemd/sd-bus/bus-creds.h
+++ b/src/libsystemd/sd-bus/bus-creds.h
@@ -40,6 +40,9 @@ struct sd_bus_creds {
         gid_t sgid;
         gid_t fsgid;
 
+        gid_t *supplementary_gids;
+        unsigned n_supplementary_gids;
+
         pid_t pid;
         usec_t pid_starttime;
         pid_t tid;
diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c
index d6e5546..2ddf016 100644
--- a/src/libsystemd/sd-bus/bus-dump.c
+++ b/src/libsystemd/sd-bus/bus-dump.c
@@ -384,8 +384,18 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) {
         if (c->mask & SD_BUS_CREDS_FSGID)
                 fprintf(f, "%sFSGID=%s"GID_FMT"%s", prefix, color, c->fsgid, suffix);
 
+        if (c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
+                unsigned i;
+
+                fprintf(f, "%sSupplementaryGIDs=%s", prefix, color);
+                for (i = 0; i < c->n_supplementary_gids; i++)
+                        fprintf(f, "%s" GID_FMT, i > 0 ? " " : "", c->supplementary_gids[i]);
+                fprintf(f, "%s", suffix);
+        }
+
         if (terse && ((c->mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
-                                  SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) || r >= 0))
+                                  SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
+                                  SD_BUS_CREDS_SUPPLEMENTARY_GIDS)) || r >= 0))
                 fputs("\n", f);
 
         if (c->mask & SD_BUS_CREDS_COMM)
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index 79d29dc..e66a263 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -660,6 +660,29 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
                         m->creds.mask |= SD_BUS_CREDS_DESCRIPTION & bus->creds_mask;
                         break;
 
+                case KDBUS_ITEM_AUXGROUPS:
+
+                        if (bus->creds_mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
+                                size_t i, n;
+                                uid_t *u;
+                                n = (d->size - offsetof(struct kdbus_item, data64)) / sizeof(uint64_t);
+                                u = new(uid_t, n);
+                                if (!u) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                for (i = 0; i < n; i++)
+                                        u[i] = (uid_t) d->data64[i];
+
+                                m->creds.supplementary_gids = u;
+                                m->creds.n_supplementary_gids = n;
+
+                                m->creds.mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
+                        }
+
+                        break;
+
                 case KDBUS_ITEM_FDS:
                 case KDBUS_ITEM_SECLABEL:
                         break;
@@ -1332,6 +1355,9 @@ int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
         if (mask & SD_BUS_CREDS_DESCRIPTION)
                 m |= KDBUS_ATTACH_CONN_DESCRIPTION;
 
+        if (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS)
+                m |= KDBUS_ATTACH_AUXGROUPS;
+
         *kdbus_mask = m;
         return 0;
 }
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 21d693b..cb53a32 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -49,39 +49,40 @@ typedef struct {
 /* Flags */
 
 enum {
-        SD_BUS_CREDS_PID              = 1ULL << 0,
-        SD_BUS_CREDS_PID_STARTTIME    = 1ULL << 1,
-        SD_BUS_CREDS_TID              = 1ULL << 2,
-        SD_BUS_CREDS_UID              = 1ULL << 3,
-        SD_BUS_CREDS_EUID             = 1ULL << 4,
-        SD_BUS_CREDS_SUID             = 1ULL << 5,
-        SD_BUS_CREDS_FSUID            = 1ULL << 6,
-        SD_BUS_CREDS_GID              = 1ULL << 7,
-        SD_BUS_CREDS_EGID             = 1ULL << 8,
-        SD_BUS_CREDS_SGID             = 1ULL << 9,
-        SD_BUS_CREDS_FSGID            = 1ULL << 10,
-        SD_BUS_CREDS_COMM             = 1ULL << 11,
-        SD_BUS_CREDS_TID_COMM         = 1ULL << 12,
-        SD_BUS_CREDS_EXE              = 1ULL << 13,
-        SD_BUS_CREDS_CMDLINE          = 1ULL << 14,
-        SD_BUS_CREDS_CGROUP           = 1ULL << 15,
-        SD_BUS_CREDS_UNIT             = 1ULL << 16,
-        SD_BUS_CREDS_USER_UNIT        = 1ULL << 17,
-        SD_BUS_CREDS_SLICE            = 1ULL << 18,
-        SD_BUS_CREDS_SESSION          = 1ULL << 19,
-        SD_BUS_CREDS_OWNER_UID        = 1ULL << 20,
-        SD_BUS_CREDS_EFFECTIVE_CAPS   = 1ULL << 21,
-        SD_BUS_CREDS_PERMITTED_CAPS   = 1ULL << 22,
-        SD_BUS_CREDS_INHERITABLE_CAPS = 1ULL << 23,
-        SD_BUS_CREDS_BOUNDING_CAPS    = 1ULL << 24,
-        SD_BUS_CREDS_SELINUX_CONTEXT  = 1ULL << 25,
-        SD_BUS_CREDS_AUDIT_SESSION_ID = 1ULL << 26,
-        SD_BUS_CREDS_AUDIT_LOGIN_UID  = 1ULL << 27,
-        SD_BUS_CREDS_UNIQUE_NAME      = 1ULL << 28,
-        SD_BUS_CREDS_WELL_KNOWN_NAMES = 1ULL << 29,
-        SD_BUS_CREDS_DESCRIPTION      = 1ULL << 30,
-        SD_BUS_CREDS_AUGMENT          = 1ULL << 63, /* special flag, if on sd-bus will augment creds struct, in a potentially race-full way. */
-        _SD_BUS_CREDS_ALL             = (1ULL << 31) -1,
+        SD_BUS_CREDS_PID                = 1ULL << 0,
+        SD_BUS_CREDS_PID_STARTTIME      = 1ULL << 1,
+        SD_BUS_CREDS_TID                = 1ULL << 2,
+        SD_BUS_CREDS_UID                = 1ULL << 3,
+        SD_BUS_CREDS_EUID               = 1ULL << 4,
+        SD_BUS_CREDS_SUID               = 1ULL << 5,
+        SD_BUS_CREDS_FSUID              = 1ULL << 6,
+        SD_BUS_CREDS_GID                = 1ULL << 7,
+        SD_BUS_CREDS_EGID               = 1ULL << 8,
+        SD_BUS_CREDS_SGID               = 1ULL << 9,
+        SD_BUS_CREDS_FSGID              = 1ULL << 10,
+        SD_BUS_CREDS_SUPPLEMENTARY_GIDS = 1ULL << 11,
+        SD_BUS_CREDS_COMM               = 1ULL << 12,
+        SD_BUS_CREDS_TID_COMM           = 1ULL << 13,
+        SD_BUS_CREDS_EXE                = 1ULL << 14,
+        SD_BUS_CREDS_CMDLINE            = 1ULL << 15,
+        SD_BUS_CREDS_CGROUP             = 1ULL << 16,
+        SD_BUS_CREDS_UNIT               = 1ULL << 17,
+        SD_BUS_CREDS_USER_UNIT          = 1ULL << 18,
+        SD_BUS_CREDS_SLICE              = 1ULL << 19,
+        SD_BUS_CREDS_SESSION            = 1ULL << 20,
+        SD_BUS_CREDS_OWNER_UID          = 1ULL << 21,
+        SD_BUS_CREDS_EFFECTIVE_CAPS     = 1ULL << 22,
+        SD_BUS_CREDS_PERMITTED_CAPS     = 1ULL << 23,
+        SD_BUS_CREDS_INHERITABLE_CAPS   = 1ULL << 24,
+        SD_BUS_CREDS_BOUNDING_CAPS      = 1ULL << 25,
+        SD_BUS_CREDS_SELINUX_CONTEXT    = 1ULL << 26,
+        SD_BUS_CREDS_AUDIT_SESSION_ID   = 1ULL << 27,
+        SD_BUS_CREDS_AUDIT_LOGIN_UID    = 1ULL << 28,
+        SD_BUS_CREDS_UNIQUE_NAME        = 1ULL << 29,
+        SD_BUS_CREDS_WELL_KNOWN_NAMES   = 1ULL << 30,
+        SD_BUS_CREDS_DESCRIPTION        = 1ULL << 31,
+        SD_BUS_CREDS_AUGMENT            = 1ULL << 63, /* special flag, if on sd-bus will augment creds struct, in a potentially race-full way. */
+        _SD_BUS_CREDS_ALL               = (1ULL << 32) -1,
 };
 
 enum {
@@ -319,6 +320,7 @@ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid);
 int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid);
 int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid);
 int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid);
+int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids);
 int sd_bus_creds_get_comm(sd_bus_creds *c, const char **comm);
 int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **comm);
 int sd_bus_creds_get_exe(sd_bus_creds *c, const char **exe);

commit 2e9efd22ce0099c3b4d35898d70f8fc706c8a66c
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 25 02:11:57 2014 +0100

    busctl: if no parameter is specified for "busctl status" show credentials of bus owner

diff --git a/man/busctl.xml b/man/busctl.xml
index a4c4227..285725e 100644
--- a/man/busctl.xml
+++ b/man/busctl.xml
@@ -271,10 +271,13 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
       </varlistentry>
 
       <varlistentry>
-        <term><command>status</command> <arg choice="plain"><replaceable>SERVICE</replaceable></arg></term>
+        <term><command>status</command> <arg choice="opt"><replaceable>SERVICE</replaceable></arg></term>
 
         <listitem><para>Show process information and credentials of a
-        bus service.</para></listitem>
+        bus service (if one is specified by its unique or well-known
+        name), a process (if one is specified by its numeric PID), or
+        the owner of the bus (if no parameter is
+        specified).</para></listitem>
       </varlistentry>
 
       <varlistentry>
diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c
index 0795472..50291ba 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/libsystemd/sd-bus/busctl.c
@@ -1175,20 +1175,29 @@ static int status(sd_bus *bus, char *argv[]) {
 
         assert(bus);
 
-        if (strv_length(argv) != 2) {
-                log_error("Expects one argument.");
+        if (strv_length(argv) > 2) {
+                log_error("Expects no or one argument.");
                 return -EINVAL;
         }
 
-        r = parse_pid(argv[1], &pid);
-        if (r < 0)
-                r = sd_bus_get_name_creds(
+        if (argv[1]) {
+                r = parse_pid(argv[1], &pid);
+                if (r < 0)
+                        r = sd_bus_get_name_creds(
+                                        bus,
+                                        argv[1],
+                                        (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) | _SD_BUS_CREDS_ALL,
+                                        &creds);
+                else
+                        r = sd_bus_creds_new_from_pid(
+                                        &creds,
+                                        pid,
+                                        _SD_BUS_CREDS_ALL);
+        } else
+                r = sd_bus_get_owner_creds(
                                 bus,
-                                argv[1],
                                 (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) | _SD_BUS_CREDS_ALL,
                                 &creds);
-        else
-                r = sd_bus_creds_new_from_pid(&creds, pid, _SD_BUS_CREDS_ALL);
 
         if (r < 0) {
                 log_error("Failed to get credentials: %s", strerror(-r));
@@ -1675,7 +1684,7 @@ static int help(void) {
                "     --augment-creds=BOOL Extend credential data with data read from /proc/$PID\n\n"
                "Commands:\n"
                "  list                    List bus names\n"
-               "  status SERVICE          Show service name status\n"
+               "  status [SERVICE]        Show bus service, process or bus owner credentials\n"
                "  monitor [SERVICE...]    Show bus traffic\n"
                "  capture [SERVICE...]    Capture bus traffic as pcap\n"
                "  tree [SERVICE...]       Show object tree of service\n"

commit becca6eaafa8ad7771363099f55b8a7dde516f21
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Nov 25 01:59:48 2014 +0100

    sd-bus: properly handle uninitialized audit creds from kdbus

diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index b887d32..0027ad3 100644
--- a/src/libsystemd/sd-bus/bus-control.c
+++ b/src/libsystemd/sd-bus/bus-control.c
@@ -556,12 +556,14 @@ static int bus_populate_creds_from_items(sd_bus *bus,
                         break;
 
                 case KDBUS_ITEM_AUDIT:
-                        m = (SD_BUS_CREDS_AUDIT_SESSION_ID | SD_BUS_CREDS_AUDIT_LOGIN_UID) & mask;
+                        if (mask & SD_BUS_CREDS_AUDIT_SESSION_ID && (uint32_t) item->audit.sessionid != (uint32_t) -1) {
+                                c->audit_session_id = (uint32_t) item->audit.sessionid;
+                                c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
+                        }
 
-                        if (m) {
-                                c->audit_session_id = item->audit.sessionid;
-                                c->audit_login_uid = item->audit.loginuid;
-                                c->mask |= m;
+                        if (mask & SD_BUS_CREDS_AUDIT_LOGIN_UID && (uid_t) item->audit.loginuid != (uid_t) -1) {
+                                c->audit_login_uid = (uid_t) item->audit.loginuid;
+                                c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
                         }
                         break;
 

commit 359c09b1c1afa5a5ed4002940d7d6e61b74b7e3b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Nov 24 22:11:53 2014 +0100

    sd-bus: don't fail when querying creds and dbus1 refuses to tell us the selinux context

diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index 7db912b..b887d32 100644
--- a/src/libsystemd/sd-bus/bus-control.c
+++ b/src/libsystemd/sd-bus/bus-control.c
@@ -797,6 +797,7 @@ static int bus_get_name_creds_dbus1(
                 }
 
                 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
+                        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
                         const void *p = NULL;
                         size_t sz = 0;
 
@@ -806,22 +807,24 @@ static int bus_get_name_creds_dbus1(
                                         "/org/freedesktop/DBus",
                                         "org.freedesktop.DBus",
                                         "GetConnectionSELinuxSecurityContext",
-                                        NULL,
+                                        &error,
                                         &reply,
                                         "s",
                                         unique ? unique : name);
-                        if (r < 0)
-                                return r;
-
-                        r = sd_bus_message_read_array(reply, 'y', &p, &sz);
-                        if (r < 0)
-                                return r;
+                        if (r < 0) {
+                                if (!sd_bus_error_has_name(&error, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"))
+                                        return r;
+                        } else {
+                                r = sd_bus_message_read_array(reply, 'y', &p, &sz);
+                                if (r < 0)
+                                        return r;
 
-                        c->label = strndup(p, sz);
-                        if (!c->label)
-                                return -ENOMEM;
+                                c->label = strndup(p, sz);
+                                if (!c->label)
+                                        return -ENOMEM;
 
-                        c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+                                c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+                        }
                 }
 
                 r = bus_creds_add_more(c, mask, pid, 0);

commit 40ed1a4574152337479f7f9c01763b84847ff09f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Nov 24 21:53:29 2014 +0100

    busctl: add new --augment-creds= switch for controlling whether shown credential data shall be augment with data from /proc

diff --git a/man/busctl.xml b/man/busctl.xml
index 872f3f4..a4c4227 100644
--- a/man/busctl.xml
+++ b/man/busctl.xml
@@ -232,6 +232,20 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--augment-creds=</option><replaceable>BOOL</replaceable></term>
+
+        <listitem>
+          <para>Controls whether credential data reported by
+          <command>list</command> or <command>status</command> shall
+          be augmented with data from
+          <filename>/proc</filename>. When this is turned on the data
+          shown is possibly inconsistent, as the data read from
+          <filename>/proc</filename> might be more recent than rest of
+          the credential information. Defaults to <literal>yes</literal>.</para>
+        </listitem>
+      </varlistentry>
+
       <xi:include href="user-system-options.xml" xpointer="user" />
       <xi:include href="user-system-options.xml" xpointer="system" />
       <xi:include href="user-system-options.xml" xpointer="host" />
diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c
index b2c7be2..0795472 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/libsystemd/sd-bus/busctl.c
@@ -56,6 +56,7 @@ static bool arg_verbose = false;
 static bool arg_expect_reply = true;
 static bool arg_auto_start = true;
 static bool arg_allow_interactive_authorization = true;
+static bool arg_augment_creds = true;
 static usec_t arg_timeout = 0;
 
 static void pager_open_if_enabled(void) {
@@ -161,10 +162,12 @@ static int list_bus_names(sd_bus *bus, char **argv) {
 
                 printf("%-*s", (int) max_i, *i);
 
-                r = sd_bus_get_name_creds(bus, *i,
-                                     SD_BUS_CREDS_UID|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);
+                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_UNIQUE_NAME|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_SESSION|
+                                SD_BUS_CREDS_DESCRIPTION, &creds);
                 if (r >= 0) {
                         const char *unique, *session, *unit, *cn;
                         pid_t pid;
@@ -1179,7 +1182,11 @@ static int status(sd_bus *bus, char *argv[]) {
 
         r = parse_pid(argv[1], &pid);
         if (r < 0)
-                r = sd_bus_get_name_creds(bus, argv[1], _SD_BUS_CREDS_ALL, &creds);
+                r = sd_bus_get_name_creds(
+                                bus,
+                                argv[1],
+                                (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) | _SD_BUS_CREDS_ALL,
+                                &creds);
         else
                 r = sd_bus_creds_new_from_pid(&creds, pid, _SD_BUS_CREDS_ALL);
 
@@ -1664,7 +1671,8 @@ static int help(void) {
                "     --auto-start=BOOL    Auto-start destination service\n"
                "     --allow-interactive-authorization=BOOL\n"
                "                          Allow interactive authorization for operation\n"
-               "     --timeout=SECS       Maximum time to wait for method call completion\n\n"
+               "     --timeout=SECS       Maximum time to wait for method call completion\n"
+               "     --augment-creds=BOOL Extend credential data with data read from /proc/$PID\n\n"
                "Commands:\n"
                "  list                    List bus names\n"
                "  status SERVICE          Show service name status\n"
@@ -1705,6 +1713,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_AUTO_START,
                 ARG_ALLOW_INTERACTIVE_AUTHORIZATION,
                 ARG_TIMEOUT,
+                ARG_AUGMENT_CREDS,
         };
 
         static const struct option options[] = {
@@ -1730,6 +1739,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "auto-start",   required_argument, NULL, ARG_AUTO_START   },
                 { "allow-interactive-authorization", required_argument, NULL, ARG_ALLOW_INTERACTIVE_AUTHORIZATION },
                 { "timeout",      required_argument, NULL, ARG_TIMEOUT      },
+                { "augment-creds",required_argument, NULL, ARG_AUGMENT_CREDS},
                 {},
         };
 
@@ -1872,6 +1882,16 @@ static int parse_argv(int argc, char *argv[]) {
 
                         break;
 
+                case ARG_AUGMENT_CREDS:
+                        r = parse_boolean(optarg);
+                        if (r < 0) {
+                                log_error("Failed to parse --augment-creds= parameter.");
+                                return r;
+                        }
+
+                        arg_augment_creds = !!r;
+                        break;
+
                 case '?':
                         return -EINVAL;
 

commit 705a415f684f8e9ee19983e5859de00bbb1477cb
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Nov 24 21:41:40 2014 +0100

    sd-bus: update to current kernel version, by splitting off the extended KDBUS_ITEM_PIDS structure from KDBUS_ITEM_CREDS
    
    Also:
    
    - adds support for euid, suid, fsuid, egid, sgid, fsgid fields.
    
    - makes augmentation of creds with data from /proc explicitly
      controllable to give apps better control over this, given that this is
      racy.
    
    - enables augmentation for kdbus connections (previously we only did it
      for dbus1). This is useful since with recent kdbus versions it is
      possible for clients to control the metadata they want to send.
    
    - changes sd_bus_query_sender_privilege() to take the euid of the client
      into consideration, if known
    
    - when we don't have permissions to read augmentation data from /proc,
      don't fail, just don't add the data in

diff --git a/src/bus-proxyd/bus-proxyd.c b/src/bus-proxyd/bus-proxyd.c
index 9c4f2a6..32c8242 100644
--- a/src/bus-proxyd/bus-proxyd.c
+++ b/src/bus-proxyd/bus-proxyd.c
@@ -1242,9 +1242,17 @@ int main(int argc, char *argv[]) {
         }
 
         if (ucred.pid > 0) {
-                a->fake_creds.pid = ucred.pid;
+                a->fake_pids.pid = ucred.pid;
+                a->fake_pids_valid = true;
+
                 a->fake_creds.uid = ucred.uid;
+                a->fake_creds.euid = (uid_t) -1;
+                a->fake_creds.suid = (uid_t) -1;
+                a->fake_creds.fsuid = (uid_t) -1;
                 a->fake_creds.gid = ucred.gid;
+                a->fake_creds.egid = (gid_t) -1;
+                a->fake_creds.sgid = (gid_t) -1;
+                a->fake_creds.fsgid = (gid_t) -1;
                 a->fake_creds_valid = true;
         }
 
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index c25a491..7db912b 100644
--- a/src/libsystemd/sd-bus/bus-control.c
+++ b/src/libsystemd/sd-bus/bus-control.c
@@ -405,24 +405,65 @@ static int bus_populate_creds_from_items(sd_bus *bus,
 
                 switch (item->type) {
 
+                case KDBUS_ITEM_PIDS:
+
+                        if (mask & SD_BUS_CREDS_PID && item->pids.pid > 0) {
+                                c->pid = (pid_t) item->pids.pid;
+                                c->mask |= SD_BUS_CREDS_PID;
+                        }
+
+                        if (mask & SD_BUS_CREDS_TID && item->pids.tid > 0) {
+                                c->tid = (pid_t) item->pids.tid;
+                                c->mask |= SD_BUS_CREDS_TID;
+                        }
+
+                        if (mask & SD_BUS_CREDS_PID_STARTTIME && item->pids.starttime > 0) {
+                                c->pid_starttime = item->pids.starttime;
+                                c->mask |= SD_BUS_CREDS_PID_STARTTIME;
+                        }
+
+                        break;
+
                 case KDBUS_ITEM_CREDS:
-                        m = (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID | SD_BUS_CREDS_PID) & mask;
 
-                        if (m) {
+                        if (mask & SD_BUS_CREDS_UID && (uid_t) item->creds.uid != (uid_t) -1) {
                                 c->uid = (uid_t) item->creds.uid;
-                                c->pid = (pid_t) item->creds.pid;
+                                c->mask |= SD_BUS_CREDS_UID;
+                        }
+
+                        if (mask & SD_BUS_CREDS_EUID && (uid_t) item->creds.euid != (uid_t) -1) {
+                                c->euid = (uid_t) item->creds.euid;
+                                c->mask |= SD_BUS_CREDS_EUID;
+                        }
+
+                        if (mask & SD_BUS_CREDS_SUID && (uid_t) item->creds.suid != (uid_t) -1) {
+                                c->suid = (uid_t) item->creds.suid;
+                                c->mask |= SD_BUS_CREDS_SUID;
+                        }
+
+                        if (mask & SD_BUS_CREDS_FSUID && (uid_t) item->creds.fsuid != (uid_t) -1) {
+                                c->fsuid = (uid_t) item->creds.fsuid;
+                                c->mask |= SD_BUS_CREDS_FSUID;
+                        }
+
+                        if (mask & SD_BUS_CREDS_GID && (gid_t) item->creds.gid != (gid_t) -1) {
                                 c->gid = (gid_t) item->creds.gid;
-                                c->mask |= m;
+                                c->mask |= SD_BUS_CREDS_GID;
                         }
 
-                        if (mask & SD_BUS_CREDS_TID && item->creds.tid > 0) {
-                                c->tid = (pid_t) item->creds.tid;
-                                c->mask |= SD_BUS_CREDS_TID;
+                        if (mask & SD_BUS_CREDS_EGID && (gid_t) item->creds.egid != (gid_t) -1) {
+                                c->egid = (gid_t) item->creds.egid;
+                                c->mask |= SD_BUS_CREDS_EGID;
                         }
 
-                        if (mask & SD_BUS_CREDS_PID_STARTTIME && item->creds.starttime > 0) {
-                                c->pid_starttime = item->creds.starttime;
-                                c->mask |= SD_BUS_CREDS_PID_STARTTIME;
+                        if (mask & SD_BUS_CREDS_SGID && (gid_t) item->creds.sgid != (gid_t) -1) {
+                                c->sgid = (gid_t) item->creds.sgid;
+                                c->mask |= SD_BUS_CREDS_SGID;
+                        }
+
+                        if (mask & SD_BUS_CREDS_FSGID && (gid_t) item->creds.fsgid != (gid_t) -1) {
+                                c->fsgid = (gid_t) item->creds.fsgid;
+                                c->mask |= SD_BUS_CREDS_FSGID;
                         }
 
                         break;
@@ -581,6 +622,19 @@ static int bus_get_name_creds_kdbus(
         cmd->size = size;
         kdbus_translate_attach_flags(mask, (uint64_t*) &cmd->flags);
 
+        /* If augmentation is on, and the bus doesn't didn't allow us
+         * to get the bits we want, then ask for the PID/TID so that we
+         * can read the rest from /proc. */
+        if ((mask & SD_BUS_CREDS_AUGMENT) &&
+            (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|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_TID_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|
+                     SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
+                     SD_BUS_CREDS_SELINUX_CONTEXT|
+                     SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))
+                cmd->flags |= KDBUS_ATTACH_PIDS;
+
         r = ioctl(bus->input_fd, KDBUS_CMD_CONN_INFO, cmd);
         if (r < 0)
                 return -errno;
@@ -615,6 +669,10 @@ static int bus_get_name_creds_kdbus(
         if (r < 0)
                 goto fail;
 
+        r = bus_creds_add_more(c, mask, 0, 0);
+        if (r < 0)
+                goto fail;
+
         if (creds) {
                 *creds = c;
                 c = NULL;
@@ -673,11 +731,17 @@ static int bus_get_name_creds_dbus1(
                         c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
                 }
 
-                if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_GID|
-                            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|
-                            SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
-                            SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)) {
+                if ((mask & SD_BUS_CREDS_PID) ||
+                    ((mask & SD_BUS_CREDS_AUGMENT) &&
+                     (mask & (SD_BUS_CREDS_PID_STARTTIME|
+                              SD_BUS_CREDS_EUID|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|
+                              SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
+                              SD_BUS_CREDS_SELINUX_CONTEXT|
+                              SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))) {
+
                         uint32_t u;
 
                         r = sd_bus_call_method(
@@ -781,7 +845,7 @@ _public_ int sd_bus_get_name_creds(
 
         assert_return(bus, -EINVAL);
         assert_return(name, -EINVAL);
-        assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
+        assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -ENOTSUP);
         assert_return(mask == 0 || creds, -EINVAL);
         assert_return(!bus_pid_changed(bus), -ECHILD);
         assert_return(service_name_is_valid(name), -EINVAL);
@@ -802,7 +866,7 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r
         int r;
 
         assert_return(bus, -EINVAL);
-        assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
+        assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -ENOTSUP);
         assert_return(ret, -EINVAL);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
@@ -837,7 +901,21 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r
                 struct kdbus_info *creator_info;
 
                 cmd.size = sizeof(cmd);
-                cmd.flags = _KDBUS_ATTACH_ALL;
+                kdbus_translate_attach_flags(mask, (uint64_t*) &cmd.flags);
+
+                /* If augmentation is on, and the bus doesn't didn't allow us
+                 * to get the bits we want, then ask for the PID/TID so that we
+                 * can read the rest from /proc. */
+                if ((mask & SD_BUS_CREDS_AUGMENT) &&
+                    (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|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_TID_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|
+                             SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
+                             SD_BUS_CREDS_SELINUX_CONTEXT|
+                             SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))
+                        cmd.flags |= KDBUS_ATTACH_PIDS;
+
                 r = ioctl(bus->input_fd, KDBUS_CMD_BUS_CREATOR_INFO, &cmd);
                 if (r < 0)
                         return -errno;
@@ -849,12 +927,12 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r
 
                 if (r < 0)
                         return r;
-        } else {
-                r = bus_creds_add_more(c, mask, pid, 0);
-                if (r < 0)
-                        return r;
         }
 
+        r = bus_creds_add_more(c, mask, pid, 0);
+        if (r < 0)
+                return r;
+
         *ret = c;
         c = NULL;
         return 0;
diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c
index 8081a2f..ae0f4fa 100644
--- a/src/libsystemd/sd-bus/bus-convenience.c
+++ b/src/libsystemd/sd-bus/bus-convenience.c
@@ -476,6 +476,7 @@ _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_b
 _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability) {
         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
         uid_t our_uid;
+        bool know_caps = false;
         int r;
 
         assert_return(call, -EINVAL);
@@ -486,21 +487,21 @@ _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability)
         if (!BUS_IS_OPEN(call->bus->state))
                 return -ENOTCONN;
 
-        /* We only trust the effective capability set if this is
-         * kdbus. On classic dbus1 we cannot retrieve the value
-         * without races. Since this function is supposed to be useful
-         * for authentication decision we hence avoid requesting and
-         * using that information. */
-        if (call->bus->is_kernel && capability >= 0) {
-                r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds);
+        if (capability >= 0) {
+                r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds);
                 if (r < 0)
                         return r;
 
+                /* Note that not even on kdbus we might have the caps
+                 * field, due to faked identities, or namespace
+                 * translation issues. */
                 r = sd_bus_creds_has_effective_cap(creds, capability);
                 if (r > 0)
                         return 1;
+                if (r == 0)
+                        know_caps = true;
         } else {
-                r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID, &creds);
+                r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID, &creds);
                 if (r < 0)
                         return r;
         }
@@ -508,10 +509,14 @@ _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability)
         /* Now, check the UID, but only if the capability check wasn't
          * sufficient */
         our_uid = getuid();
-        if (our_uid != 0 || !call->bus->is_kernel || capability < 0) {
+        if (our_uid != 0 || !know_caps || capability < 0) {
                 uid_t sender_uid;
 
-                r = sd_bus_creds_get_uid(creds, &sender_uid);
+                /* Try to use the EUID, if we have it. */
+                r = sd_bus_creds_get_euid(creds, &sender_uid);
+                if (r < 0)
+                        r = sd_bus_creds_get_uid(creds, &sender_uid);
+
                 if (r >= 0) {
                         /* Sender has same UID as us, then let's grant access */
                         if (sender_uid == our_uid)
diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c
index d27ef1e..02a7372 100644
--- a/src/libsystemd/sd-bus/bus-creds.c
+++ b/src/libsystemd/sd-bus/bus-creds.c
@@ -141,7 +141,7 @@ _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t m
         if (!c)
                 return -ENOMEM;
 
-        r = bus_creds_add_more(c, mask, pid, 0);
+        r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
         if (r < 0) {
                 sd_bus_creds_unref(c);
                 return r;
@@ -169,6 +169,40 @@ _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
         return 0;
 }
 
+_public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
+        assert_return(c, -EINVAL);
+        assert_return(euid, -EINVAL);
+
+        if (!(c->mask & SD_BUS_CREDS_EUID))
+                return -ENODATA;
+
+        *euid = c->euid;
+        return 0;
+}
+
+_public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
+        assert_return(c, -EINVAL);
+        assert_return(suid, -EINVAL);
+
+        if (!(c->mask & SD_BUS_CREDS_SUID))
+                return -ENODATA;
+
+        *suid = c->suid;
+        return 0;
+}
+
+
+_public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
+        assert_return(c, -EINVAL);
+        assert_return(fsuid, -EINVAL);
+
+        if (!(c->mask & SD_BUS_CREDS_FSUID))
+                return -ENODATA;
+
+        *fsuid = c->fsuid;
+        return 0;
+}
+
 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
         assert_return(c, -EINVAL);
         assert_return(gid, -EINVAL);
@@ -180,6 +214,41 @@ _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
         return 0;
 }
 
+
+_public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
+        assert_return(c, -EINVAL);
+        assert_return(egid, -EINVAL);
+
+        if (!(c->mask & SD_BUS_CREDS_EGID))
+                return -ENODATA;
+
+        *egid = c->egid;
+        return 0;
+}
+
+_public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
+        assert_return(c, -EINVAL);
+        assert_return(sgid, -EINVAL);
+
+        if (!(c->mask & SD_BUS_CREDS_SGID))
+                return -ENODATA;
+
+        *sgid = c->sgid;
+        return 0;
+}
+
+
+_public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
+        assert_return(c, -EINVAL);
+        assert_return(fsgid, -EINVAL);
+
+        if (!(c->mask & SD_BUS_CREDS_FSGID))
+                return -ENODATA;
+
+        *fsgid = c->fsgid;
+        return 0;
+}
+
 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
         assert_return(c, -EINVAL);
         assert_return(pid, -EINVAL);
@@ -581,6 +650,9 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
         assert(c);
         assert(c->allocated);
 
+        if (!(mask & SD_BUS_CREDS_AUGMENT))
+                return 0;
+
         missing = mask & ~c->mask;
         if (missing == 0)
                 return 0;
@@ -596,98 +668,120 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
         if (pid <= 0)
                 return 0;
 
-        if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID |
+        if (pid > 0) {
+                c->pid = pid;
+                c->mask |= SD_BUS_CREDS_PID;
+        }
+
+        if (tid > 0) {
+                c->tid = tid;
+                c->mask |= SD_BUS_CREDS_TID;
+        }
+
+        if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | 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_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
                        SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
 
                 _cleanup_fclose_ FILE *f = NULL;
-                char line[LINE_MAX];
                 const char *p;
 
                 p = procfs_file_alloca(pid, "status");
 
                 f = fopen(p, "re");
-                if (!f)
-                        return errno == ENOENT ? -ESRCH : -errno;
-
-                FOREACH_LINE(line, f, return -errno) {
-                        truncate_nl(line);
-
-                        if (missing & SD_BUS_CREDS_UID) {
-                                p = startswith(line, "Uid:");
-                                if (p) {
-                                        unsigned long uid;
-
-                                        p += strspn(p, WHITESPACE);
-                                        if (sscanf(p, "%lu", &uid) != 1)
-                                                return -EIO;
-
-                                        c->uid = (uid_t) uid;
-                                        c->mask |= SD_BUS_CREDS_UID;
-                                        continue;
+                if (!f) {
+                        if (errno == ENOENT)
+                                return -ESRCH;
+                        else if (errno != EPERM && errno != EACCES)
+                                return -errno;
+                } else {
+                        char line[LINE_MAX];
+
+                        FOREACH_LINE(line, f, return -errno) {
+                                truncate_nl(line);
+
+                                if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
+                                        p = startswith(line, "Uid:");
+                                        if (p) {
+                                                unsigned long uid, euid, suid, fsuid;
+
+                                                p += strspn(p, WHITESPACE);
+                                                if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
+                                                        return -EIO;
+
+                                                c->uid = (uid_t) uid;
+                                                c->euid = (uid_t) euid;
+                                                c->suid = (uid_t) suid;
+                                                c->fsuid = (uid_t) fsuid;
+                                                c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
+                                                continue;
+                                        }
                                 }
-                        }
-
-                        if (missing & SD_BUS_CREDS_GID) {
-                                p = startswith(line, "Gid:");
-                                if (p) {
-                                        unsigned long gid;
-
-                                        p += strspn(p, WHITESPACE);
-                                        if (sscanf(p, "%lu", &gid) != 1)
-                                                return -EIO;
 
-                                        c->gid = (uid_t) gid;
-                                        c->mask |= SD_BUS_CREDS_GID;
-                                        continue;
+                                if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
+                                        p = startswith(line, "Gid:");
+                                        if (p) {
+                                                unsigned long gid, egid, sgid, fsgid;
+
+                                                p += strspn(p, WHITESPACE);
+                                                if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
+                                                        return -EIO;
+
+                                                c->gid = (gid_t) gid;
+                                                c->egid = (gid_t) egid;
+                                                c->sgid = (gid_t) sgid;
+                                                c->fsgid = (gid_t) fsgid;
+                                                c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
+                                                continue;
+                                        }
                                 }
-                        }
 
-                        if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
-                                p = startswith(line, "CapEff:");
-                                if (p) {
-                                        r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
-                                        if (r < 0)
-                                                return r;
+                                if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
+                                        p = startswith(line, "CapEff:");
+                                        if (p) {
+                                                r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
+                                                if (r < 0)
+                                                        return r;
 
-                                        c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
-                                        continue;
+                                                c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
+                                                continue;
+                                        }
                                 }
-                        }
 
-                        if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
-                                p = startswith(line, "CapPrm:");
-                                if (p) {
-                                        r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
-                                        if (r < 0)
-                                                return r;
+                                if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
+                                        p = startswith(line, "CapPrm:");
+                                        if (p) {
+                                                r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
+                                                if (r < 0)
+                                                        return r;
 
-                                        c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
-                                        continue;
+                                                c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
+                                                continue;
+                                        }
                                 }
-                        }
 
-                        if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
-                                p = startswith(line, "CapInh:");
-                                if (p) {
-                                        r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
-                                        if (r < 0)
-                                                return r;
+                                if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
+                                        p = startswith(line, "CapInh:");
+                                        if (p) {
+                                                r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
+                                                if (r < 0)
+                                                        return r;
 
-                                        c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
-                                        continue;
+                                                c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
+                                                continue;
+                                        }
                                 }
-                        }
 
-                        if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
-                                p = startswith(line, "CapBnd:");
-                                if (p) {
-                                        r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
-                                        if (r < 0)
-                                                return r;
+                                if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
+                                        p = startswith(line, "CapBnd:");
+                                        if (p) {
+                                                r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
+                                                if (r < 0)
+                                                        return r;
 
-                                        c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
-                                        continue;
+                                                c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
+                                                continue;
+                                        }
                                 }
                         }
                 }
@@ -697,11 +791,13 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
                 unsigned long long st;
 
                 r = get_starttime_of_pid(pid, &st);
-                if (r < 0)
-                        return r;
-
-                c->pid_starttime = ((usec_t) st * USEC_PER_SEC) / (usec_t) sysconf(_SC_CLK_TCK);
-                c->mask |= SD_BUS_CREDS_PID_STARTTIME;
+                if (r < 0) {
+                        if (r != -EPERM && r != -EACCES)
+                                return r;
+                } else {
+                        c->pid_starttime = ((usec_t) st * USEC_PER_SEC) / (usec_t) sysconf(_SC_CLK_TCK);
+                        c->mask |= SD_BUS_CREDS_PID_STARTTIME;
+                }
         }
 
         if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
@@ -709,26 +805,29 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
 
                 p = procfs_file_alloca(pid, "attr/current");
                 r = read_one_line_file(p, &c->label);
-                if (r < 0 && r != -ENOENT && r != -EINVAL)
-                        return r;
-                else if (r >= 0)
+                if (r < 0) {
+                        if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
+                                return r;
+                } else
                         c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
         }
 
         if (missing & SD_BUS_CREDS_COMM) {
                 r = get_process_comm(pid, &c->comm);
-                if (r < 0)
-                        return r;
-
-                c->mask |= SD_BUS_CREDS_COMM;
+                if (r < 0) {
+                        if (r != -EPERM && r != -EACCES)
+                                return r;
+                } else
+                        c->mask |= SD_BUS_CREDS_COMM;
         }
 
         if (missing & SD_BUS_CREDS_EXE) {
                 r = get_process_exe(pid, &c->exe);
-                if (r < 0)
-                        return r;
-
-                c->mask |= SD_BUS_CREDS_EXE;
+                if (r < 0) {
+                        if (r != -EPERM && r != -EACCES)
+                                return r;
+                } else
+                        c->mask |= SD_BUS_CREDS_EXE;
         }
 
         if (missing & SD_BUS_CREDS_CMDLINE) {
@@ -736,14 +835,18 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
 
                 p = procfs_file_alloca(pid, "cmdline");
                 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
-                if (r < 0)
-                        return r;
-
-                if (c->cmdline_size == 0) {
-                        free(c->cmdline);
-                        c->cmdline = NULL;
-                } else
-                        c->mask |= SD_BUS_CREDS_CMDLINE;
+                if (r < 0) {
+                        if (r == -ENOENT)
+                                return -ESRCH;
+                        if (r != -EPERM && r != -EACCES)
+                                return r;
+                } else {
+                        if (c->cmdline_size == 0) {
+                                free(c->cmdline);
+                                c->cmdline = NULL;
+                        } else
+                                c->mask |= SD_BUS_CREDS_CMDLINE;
+                }
         }
 
         if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
@@ -753,38 +856,45 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
                         return -ENOMEM;
 
                 r = read_one_line_file(p, &c->tid_comm);
-                if (r < 0)
-                        return r == -ENOENT ? -ESRCH : r;
-
-                c->mask |= SD_BUS_CREDS_TID_COMM;
+                if (r < 0) {
+                        if (r == -ENOENT)
+                                return -ESRCH;
+                        if (r != -EPERM && r != -EACCES)
+                                return r;
+                } else
+                        c->mask |= SD_BUS_CREDS_TID_COMM;
         }
 
         if (missing & (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)) {
 
                 r = cg_pid_get_path(NULL, pid, &c->cgroup);
-                if (r < 0)
-                        return r;
-
-                r = cg_get_root_path(&c->cgroup_root);
-                if (r < 0)
-                        return r;
-
-                c->mask |= missing & (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);
+                if (r < 0) {
+                        if (r != -EPERM && r != -EACCES)
+                                return r;
+                } else {
+                        r = cg_get_root_path(&c->cgroup_root);
+                        if (r < 0)
+                                return r;
+
+                        c->mask |= missing & (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);
+                }
         }
 
         if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
                 r = audit_session_from_pid(pid, &c->audit_session_id);
-                if (r < 0 && r != -ENOTSUP && r != -ENXIO && r != -ENOENT)
-                        return r;
-                else if (r >= 0)
+                if (r < 0) {
+                        if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
+                                return r;
+                } else
                         c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
         }
 
         if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
                 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
-                if (r < 0 && r != -ENOTSUP && r != -ENXIO && r != -ENOENT)
-                        return r;
-                else if (r >= 0)
+                if (r < 0) {
+                        if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
+                                return r;
+                } else
                         c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
         }
 
@@ -798,8 +908,9 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
         assert(c);
         assert(ret);
 
-        if ((mask & ~c->mask) == 0) {
-                /* There's already all data we need. */
+        if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
+                /* There's already all data we need, or augmentation
+                 * wasn't turned on. */
 
                 *ret = sd_bus_creds_ref(c);
                 return 0;
@@ -816,11 +927,41 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
                 n->mask |= SD_BUS_CREDS_UID;
         }
 
+        if (c->mask & mask & SD_BUS_CREDS_EUID) {
+                n->euid = c->euid;
+                n->mask |= SD_BUS_CREDS_EUID;
+        }
+
+        if (c->mask & mask & SD_BUS_CREDS_SUID) {
+                n->suid = c->suid;
+                n->mask |= SD_BUS_CREDS_SUID;
+        }
+
+        if (c->mask & mask & SD_BUS_CREDS_FSUID) {
+                n->fsuid = c->fsuid;
+                n->mask |= SD_BUS_CREDS_FSUID;
+        }
+
         if (c->mask & mask & SD_BUS_CREDS_GID) {
                 n->gid = c->gid;
                 n->mask |= SD_BUS_CREDS_GID;
         }
 
+        if (c->mask & mask & SD_BUS_CREDS_EGID) {
+                n->egid = c->egid;
+                n->mask |= SD_BUS_CREDS_EGID;
+        }
+
+        if (c->mask & mask & SD_BUS_CREDS_SGID) {
+                n->sgid = c->sgid;
+                n->mask |= SD_BUS_CREDS_SGID;
+        }
+
+        if (c->mask & mask & SD_BUS_CREDS_FSGID) {
+                n->fsgid = c->fsgid;
+                n->mask |= SD_BUS_CREDS_FSGID;
+        }
+
         if (c->mask & mask & SD_BUS_CREDS_PID) {
                 n->pid = c->pid;
                 n->mask |= SD_BUS_CREDS_PID;
diff --git a/src/libsystemd/sd-bus/bus-creds.h b/src/libsystemd/sd-bus/bus-creds.h
index cf1f611..15821a5 100644
--- a/src/libsystemd/sd-bus/bus-creds.h
+++ b/src/libsystemd/sd-bus/bus-creds.h
@@ -32,7 +32,14 @@ struct sd_bus_creds {
         uint64_t mask;
 
         uid_t uid;
+        uid_t euid;
+        uid_t suid;
+        uid_t fsuid;
         gid_t gid;
+        gid_t egid;
+        gid_t sgid;
+        gid_t fsgid;
+
         pid_t pid;
         usec_t pid_starttime;
         pid_t tid;
diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c
index 5e96b00..d6e5546 100644
--- a/src/libsystemd/sd-bus/bus-dump.c
+++ b/src/libsystemd/sd-bus/bus-dump.c
@@ -360,15 +360,32 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) {
                 fprintf(f, "%sPIDStartTime=%s"USEC_FMT"%s", prefix, color, c->pid_starttime, suffix);
         if (c->mask & SD_BUS_CREDS_TID)
                 fprintf(f, "%sTID=%s"PID_FMT"%s", prefix, color, c->tid, suffix);
+
+        if (terse && ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))))
+                fputs("\n", f);
+
         if (c->mask & SD_BUS_CREDS_UID)
                 fprintf(f, "%sUID=%s"UID_FMT"%s", prefix, color, c->uid, suffix);
+        if (c->mask & SD_BUS_CREDS_EUID)
+                fprintf(f, "%sEUID=%s"UID_FMT"%s", prefix, color, c->euid, suffix);
+        if (c->mask & SD_BUS_CREDS_SUID)
+                fprintf(f, "%sSUID=%s"UID_FMT"%s", prefix, color, c->suid, suffix);
+        if (c->mask & SD_BUS_CREDS_FSUID)
+                fprintf(f, "%sFSUID=%s"UID_FMT"%s", prefix, color, c->fsuid, suffix);
         r = sd_bus_creds_get_owner_uid(c, &owner);
         if (r >= 0)
                 fprintf(f, "%sOwnerUID=%s"UID_FMT"%s", prefix, color, owner, suffix);
         if (c->mask & SD_BUS_CREDS_GID)
                 fprintf(f, "%sGID=%s"GID_FMT"%s", prefix, color, c->gid, suffix);
-
-        if (terse && ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID|SD_BUS_CREDS_UID|SD_BUS_CREDS_GID)) || r >= 0))
+        if (c->mask & SD_BUS_CREDS_EGID)
+                fprintf(f, "%sEGID=%s"GID_FMT"%s", prefix, color, c->egid, suffix);
+        if (c->mask & SD_BUS_CREDS_SGID)
+                fprintf(f, "%sSGID=%s"GID_FMT"%s", prefix, color, c->sgid, suffix);
+        if (c->mask & SD_BUS_CREDS_FSGID)
+                fprintf(f, "%sFSGID=%s"GID_FMT"%s", prefix, color, c->fsgid, suffix);
+
+        if (terse && ((c->mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
+                                  SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) || r >= 0))
                 fputs("\n", f);
 
         if (c->mask & SD_BUS_CREDS_COMM)
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
index f6b0211..977b340 100644
--- a/src/libsystemd/sd-bus/bus-internal.h
+++ b/src/libsystemd/sd-bus/bus-internal.h
@@ -206,6 +206,7 @@ struct sd_bus {
         bool nodes_modified:1;
         bool trusted:1;
         bool fake_creds_valid:1;
+        bool fake_pids_valid:1;
         bool manual_peer_interface:1;
         bool is_system:1;
         bool is_user:1;
@@ -306,6 +307,7 @@ struct sd_bus {
         pid_t tid;
 
         struct kdbus_creds fake_creds;
+        struct kdbus_pids fake_pids;
         char *fake_label;
 
         char *cgroup_root;
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index afac3b6..79d29dc 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -513,28 +513,75 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
                         break;
                 }
 
-                case KDBUS_ITEM_CREDS:
-                        /* UID/GID/PID are always valid */
-                        m->creds.uid = (uid_t) d->creds.uid;
-                        m->creds.gid = (gid_t) d->creds.gid;
-                        m->creds.pid = (pid_t) d->creds.pid;
-                        m->creds.mask |= (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID) & bus->creds_mask;
-
-                        /* The PID starttime/TID might be missing
-                         * however, when the data is faked by some
-                         * data bus proxy and it lacks that
-                         * information about the real client since
-                         * SO_PEERCRED is used for that */
-
-                        if (d->creds.starttime > 0) {
-                                m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
+                case KDBUS_ITEM_PIDS:
+
+                        /* The PID starttime/TID might be missing,
+                         * when the data is faked by some data bus
+                         * proxy and it lacks that information about
+                         * the real client since SO_PEERCRED is used
+                         * for that. */
+
+                        if (d->pids.pid > 0) {
+                                m->creds.pid = (pid_t) d->pids.pid;
+                                m->creds.mask |= SD_BUS_CREDS_PID & bus->creds_mask;
+                        }
+
+                        if (d->pids.starttime > 0) {
+                                m->creds.pid_starttime = d->pids.starttime / NSEC_PER_USEC;
                                 m->creds.mask |= SD_BUS_CREDS_PID_STARTTIME & bus->creds_mask;
                         }
 
-                        if (d->creds.tid > 0) {
-                                m->creds.tid = (pid_t) d->creds.tid;
+                        if (d->pids.tid > 0) {
+                                m->creds.tid = (pid_t) d->pids.tid;
                                 m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
                         }
+
+                        break;
+
+                case KDBUS_ITEM_CREDS:
+
+                        /* EUID/SUID/FSUID/EGID/SGID/FSGID might be missing too (see above). */
+
+                        if ((uid_t) d->creds.uid != (uid_t) -1) {
+                                m->creds.uid = (uid_t) d->creds.uid;
+                                m->creds.mask |= SD_BUS_CREDS_UID & bus->creds_mask;
+                        }
+
+                        if ((uid_t) d->creds.euid != (uid_t) -1) {
+                                m->creds.euid = (uid_t) d->creds.euid;
+                                m->creds.mask |= SD_BUS_CREDS_EUID & bus->creds_mask;
+                        }
+
+                        if ((uid_t) d->creds.suid != (uid_t) -1) {
+                                m->creds.suid = (uid_t) d->creds.suid;
+                                m->creds.mask |= SD_BUS_CREDS_SUID & bus->creds_mask;
+                        }
+
+                        if ((uid_t) d->creds.fsuid != (uid_t) -1) {
+                                m->creds.fsuid = (uid_t) d->creds.fsuid;
+                                m->creds.mask |= SD_BUS_CREDS_FSUID & bus->creds_mask;
+                        }
+
+                        if ((gid_t) d->creds.gid != (gid_t) -1) {
+                                m->creds.gid = (gid_t) d->creds.gid;
+                                m->creds.mask |= SD_BUS_CREDS_GID & bus->creds_mask;
+                        }
+
+                        if ((gid_t) d->creds.egid != (gid_t) -1) {
+                                m->creds.egid = (gid_t) d->creds.egid;
+                                m->creds.mask |= SD_BUS_CREDS_EGID & bus->creds_mask;
+                        }
+
+                        if ((gid_t) d->creds.sgid != (gid_t) -1) {
+                                m->creds.sgid = (gid_t) d->creds.sgid;
+                                m->creds.mask |= SD_BUS_CREDS_SGID & bus->creds_mask;
+                        }
+
+                        if ((gid_t) d->creds.fsgid != (gid_t) -1) {
+                                m->creds.fsgid = (gid_t) d->creds.fsgid;
+                                m->creds.mask |= SD_BUS_CREDS_FSGID & bus->creds_mask;
+                        }
+
                         break;
 
                 case KDBUS_ITEM_TIMESTAMP:
@@ -724,6 +771,9 @@ int bus_kernel_take_fd(sd_bus *b) {
         if (b->fake_creds_valid)
                 sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
 
+        if (b->fake_pids_valid)
+                sz += ALIGN8(offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids));
+
         if (b->fake_label) {
                 l = strlen(b->fake_label);
                 sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
@@ -751,6 +801,14 @@ int bus_kernel_take_fd(sd_bus *b) {
                 item = KDBUS_ITEM_NEXT(item);
         }
 
+        if (b->fake_pids_valid) {
+                item->size = offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids);
+                item->type = KDBUS_ITEM_PIDS;
+                item->pids = b->fake_pids;
+
+                item = KDBUS_ITEM_NEXT(item);
+        }
+
         if (b->fake_label) {
                 item->size = offsetof(struct kdbus_item, str) + l + 1;
                 item->type = KDBUS_ITEM_SECLABEL;
@@ -1237,9 +1295,13 @@ int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
 
         assert(kdbus_mask);
 
-        if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
+        if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
+                    SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID))
                 m |= KDBUS_ATTACH_CREDS;
 
+        if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
+                m |= KDBUS_ATTACH_PIDS;
+
         if (mask & SD_BUS_CREDS_COMM)
                 m |= KDBUS_ATTACH_PID_COMM;
 
diff --git a/src/libsystemd/sd-bus/kdbus.h b/src/libsystemd/sd-bus/kdbus.h
index e3a80c3..65266ee 100644
--- a/src/libsystemd/sd-bus/kdbus.h
+++ b/src/libsystemd/sd-bus/kdbus.h
@@ -58,22 +58,43 @@ struct kdbus_notify_name_change {
 /**
  * struct kdbus_creds - process credentials
  * @uid:		User ID
+ * @euid:		Effective UID
+ * @suid:		Saved UID
+ * @fsuid:		Filesystem UID
  * @gid:		Group ID
- * @pid:		Process ID
- * @tid:		Thread ID
- * @starttime:		Starttime of the process
- *
- * The starttime of the process PID. This is useful to detect PID overruns
- * from the client side. i.e. if you use the PID to look something up in
- * /proc/$PID/ you can afterwards check the starttime field of it, to ensure
- * you didn't run into a PID overrun.
+ * @egid:		Effective GID
+ * @sgid:		Saved GID
+ * @fsgid:		Filesystem GID
  *
  * Attached to:
  *   KDBUS_ITEM_CREDS
  */
 struct kdbus_creds {
 	__u64 uid;
+        __u64 euid;
+        __u64 suid;
+        __u64 fsuid;
 	__u64 gid;
+        __u64 egid;
+        __u64 sgid;
+        __u64 fsgid;
+};
+
+/**
+ * struct kdbus_pids - process identifiers
+ * @pid:		Process ID
+ * @tid:		Thread ID
+ * @starttime:		Starttime of the process
+ *
+ * The PID, TID and starttime of a process. The start tmie is useful to detect
+ * PID overruns from the client side. i.e. if you use the PID to look something
+ * up in /proc/$PID/ you can afterwards check the starttime field of it, to
+ * ensure you didn't run into a PID overrun.
+ *
+ * Attached to:
+ *   KDBUS_ITEM_PIDS
+ */
+struct kdbus_pids {
 	__u64 pid;
 	__u64 tid;
 	__u64 starttime;
@@ -229,14 +250,19 @@ struct kdbus_policy_access {
  * @KDBUS_ITEM_NAME:			Well-know name with flags
  * @_KDBUS_ITEM_ATTACH_BASE:		Start of metadata attach items
  * @KDBUS_ITEM_TIMESTAMP:		Timestamp
- * @KDBUS_ITEM_CREDS:			Process credential
+ * @KDBUS_ITEM_CREDS:			Process credentials
+ * @KDBUS_ITEM_PIDS:			Process identifiers
  * @KDBUS_ITEM_AUXGROUPS:		Auxiliary process groups
  * @KDBUS_ITEM_OWNED_NAME:		A name owned by the associated
  *					connection
  * @KDBUS_ITEM_TID_COMM:		Thread ID "comm" identifier
+ *					(Don't trust this, see below.)
  * @KDBUS_ITEM_PID_COMM:		Process ID "comm" identifier
+ *					(Don't trust this, see below.)
  * @KDBUS_ITEM_EXE:			The path of the executable
+ *					(Don't trust this, see below.)
  * @KDBUS_ITEM_CMDLINE:			The process command line
+ *					(Don't trust this, see below.)
  * @KDBUS_ITEM_CGROUP:			The croup membership
  * @KDBUS_ITEM_CAPS:			The process capabilities
  * @KDBUS_ITEM_SECLABEL:		The security label
@@ -253,6 +279,12 @@ struct kdbus_policy_access {
  * @KDBUS_ITEM_ID_REMOVE:		Notification in kdbus_notify_id_change
  * @KDBUS_ITEM_REPLY_TIMEOUT:		Timeout has been reached
  * @KDBUS_ITEM_REPLY_DEAD:		Destination died
+ *
+ * N.B: The process and thread COMM fields, as well as the CMDLINE and
+ * EXE fields may be altered by unprivileged processes und should
+ * hence *not* used for security decisions. Peers should make use of
+ * these items only for informational purposes, such as generating log
+ * records.
  */
 enum kdbus_item_type {
 	_KDBUS_ITEM_NULL,
@@ -275,6 +307,7 @@ enum kdbus_item_type {
 	_KDBUS_ITEM_ATTACH_BASE	= 0x1000,
 	KDBUS_ITEM_TIMESTAMP	= _KDBUS_ITEM_ATTACH_BASE,
 	KDBUS_ITEM_CREDS,
+        KDBUS_ITEM_PIDS,
 	KDBUS_ITEM_AUXGROUPS,
 	KDBUS_ITEM_OWNED_NAME,
 	KDBUS_ITEM_TID_COMM,
@@ -336,6 +369,7 @@ struct kdbus_item {
 		__u64 id;
 		struct kdbus_vec vec;
 		struct kdbus_creds creds;
+                struct kdbus_pids pids;
 		struct kdbus_audit audit;
 		struct kdbus_caps caps;
 		struct kdbus_timestamp timestamp;
@@ -455,6 +489,10 @@ enum kdbus_recv_flags {
  * @offset:		Returned offset in the pool where the message is
  *			stored. The user must use KDBUS_CMD_FREE to free
  *			the allocated memory.
+ * @dropped_msgs:	In case the KDBUS_CMD_MSG_RECV ioctl returns
+ *			-EOVERFLOW, this field will contain the number of
+ *			broadcast messages that have been lost since the
+ *			last call.
  *
  * This struct is used with the KDBUS_CMD_MSG_RECV ioctl.
  */
@@ -462,7 +500,10 @@ struct kdbus_cmd_recv {
 	__u64 flags;
 	__u64 kernel_flags;
 	__s64 priority;
-	__u64 offset;
+        union {
+                __u64 offset;
+                __u64 dropped_msgs;
+        };
 } __attribute__((aligned(8)));
 
 /**
@@ -547,6 +588,7 @@ enum kdbus_hello_flags {
  * enum kdbus_attach_flags - flags for metadata attachments
  * @KDBUS_ATTACH_TIMESTAMP:		Timestamp
  * @KDBUS_ATTACH_CREDS:			Credentials
+ * @KDBUS_ATTACH_PIDS:			PIDs
  * @KDBUS_ATTACH_AUXGROUPS:		Auxiliary groups
  * @KDBUS_ATTACH_NAMES:			Well-known names
  * @KDBUS_ATTACH_TID_COMM:		The "comm" process identifier of the TID
@@ -565,18 +607,19 @@ enum kdbus_hello_flags {
 enum kdbus_attach_flags {
 	KDBUS_ATTACH_TIMESTAMP		=  1ULL <<  0,
 	KDBUS_ATTACH_CREDS		=  1ULL <<  1,
-	KDBUS_ATTACH_AUXGROUPS		=  1ULL <<  2,
-	KDBUS_ATTACH_NAMES		=  1ULL <<  3,
-	KDBUS_ATTACH_TID_COMM		=  1ULL <<  4,
-	KDBUS_ATTACH_PID_COMM		=  1ULL <<  5,
-	KDBUS_ATTACH_EXE		=  1ULL <<  6,
-	KDBUS_ATTACH_CMDLINE		=  1ULL <<  7,
-	KDBUS_ATTACH_CGROUP		=  1ULL <<  8,
-	KDBUS_ATTACH_CAPS		=  1ULL <<  9,
-	KDBUS_ATTACH_SECLABEL		=  1ULL << 10,
-	KDBUS_ATTACH_AUDIT		=  1ULL << 11,
-	KDBUS_ATTACH_CONN_DESCRIPTION	=  1ULL << 12,
-	_KDBUS_ATTACH_ALL		=  (1ULL << 13) - 1,
+        KDBUS_ATTACH_PIDS		=  1ULL <<  2,
+        KDBUS_ATTACH_AUXGROUPS		=  1ULL <<  3,
+        KDBUS_ATTACH_NAMES		=  1ULL <<  4,
+        KDBUS_ATTACH_TID_COMM		=  1ULL <<  5,
+        KDBUS_ATTACH_PID_COMM		=  1ULL <<  6,
+        KDBUS_ATTACH_EXE		=  1ULL <<  7,
+        KDBUS_ATTACH_CMDLINE		=  1ULL <<  8,
+        KDBUS_ATTACH_CGROUP		=  1ULL <<  9,
+        KDBUS_ATTACH_CAPS		=  1ULL << 10,
+        KDBUS_ATTACH_SECLABEL		=  1ULL << 11,
+        KDBUS_ATTACH_AUDIT		=  1ULL << 12,
+        KDBUS_ATTACH_CONN_DESCRIPTION	=  1ULL << 13,
+        _KDBUS_ATTACH_ALL		=  (1ULL << 14) - 1,
 	_KDBUS_ATTACH_ANY		=  ~0ULL
 };
 
@@ -619,8 +662,8 @@ struct kdbus_cmd_hello {
 
 /**
  * enum kdbus_make_flags - Flags for KDBUS_CMD_{BUS,EP,NS}_MAKE
- * @KDBUS_MAKE_ACCESS_GROUP:	Make the device node group-accessible
- * @KDBUS_MAKE_ACCESS_WORLD:	Make the device node world-accessible
+ * @KDBUS_MAKE_ACCESS_GROUP:	Make the bus or endpoint node group-accessible
+ * @KDBUS_MAKE_ACCESS_WORLD:	Make the bus or endpoint node world-accessible
  */
 enum kdbus_make_flags {
 	KDBUS_MAKE_ACCESS_GROUP		= 1ULL <<  0,
@@ -713,7 +756,7 @@ enum kdbus_name_list_flags {
 /**
  * struct kdbus_cmd_name_list - request a list of name entries
  * @flags:		Flags for the query (KDBUS_NAME_LIST_*),
- * 			userspace → kernel
+ *			userspace → kernel
  * @kernel_flags:	Supported flags for queries, kernel → userspace
  * @offset:		The returned offset in the caller's pool buffer.
  *			The user must use KDBUS_CMD_FREE to free the
@@ -834,16 +877,16 @@ struct kdbus_cmd_match {
 
 /**
  * Ioctl API
- * KDBUS_CMD_BUS_MAKE:		After opening the "control" device node, this
- *				command creates a new bus with the specified
+ * KDBUS_CMD_BUS_MAKE:		After opening the "control" node, this command
+ *				creates a new bus with the specified
  *				name. The bus is immediately shut down and
- *				cleaned up when the opened "control" device node
- *				is closed.
+ *				cleaned up when the opened file descriptor is
+ *				closed.
  * KDBUS_CMD_ENDPOINT_MAKE:	Creates a new named special endpoint to talk to
  *				the bus. Such endpoints usually carry a more
  *				restrictive policy and grant restricted access
  *				to specific applications.
- * KDBUS_CMD_HELLO:		By opening the bus device node a connection is
+ * KDBUS_CMD_HELLO:		By opening the bus node, a connection is
  *				created. After a HELLO the opened connection
  *				becomes an active peer on the bus.
  * KDBUS_CMD_BYEBYE:		Disconnect a connection. If there are no
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index b1a1f79..5aa8eac 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -1070,7 +1070,7 @@ _public_ int sd_bus_open(sd_bus **ret) {
         /* We don't know whether the bus is trusted or not, so better
          * be safe, and authenticate everything */
         b->trusted = false;
-        b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
+        b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS | KDBUS_ATTACH_PIDS;
 
         r = sd_bus_start(b);
         if (r < 0)
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 58a8980..21d693b 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -53,28 +53,35 @@ enum {
         SD_BUS_CREDS_PID_STARTTIME    = 1ULL << 1,
         SD_BUS_CREDS_TID              = 1ULL << 2,
         SD_BUS_CREDS_UID              = 1ULL << 3,
-        SD_BUS_CREDS_GID              = 1ULL << 4,
-        SD_BUS_CREDS_COMM             = 1ULL << 5,
-        SD_BUS_CREDS_TID_COMM         = 1ULL << 6,
-        SD_BUS_CREDS_EXE              = 1ULL << 7,
-        SD_BUS_CREDS_CMDLINE          = 1ULL << 8,
-        SD_BUS_CREDS_CGROUP           = 1ULL << 9,
-        SD_BUS_CREDS_UNIT             = 1ULL << 10,
-        SD_BUS_CREDS_USER_UNIT        = 1ULL << 11,
-        SD_BUS_CREDS_SLICE            = 1ULL << 12,
-        SD_BUS_CREDS_SESSION          = 1ULL << 13,
-        SD_BUS_CREDS_OWNER_UID        = 1ULL << 14,
-        SD_BUS_CREDS_EFFECTIVE_CAPS   = 1ULL << 15,
-        SD_BUS_CREDS_PERMITTED_CAPS   = 1ULL << 16,
-        SD_BUS_CREDS_INHERITABLE_CAPS = 1ULL << 17,
-        SD_BUS_CREDS_BOUNDING_CAPS    = 1ULL << 18,
-        SD_BUS_CREDS_SELINUX_CONTEXT  = 1ULL << 19,
-        SD_BUS_CREDS_AUDIT_SESSION_ID = 1ULL << 20,
-        SD_BUS_CREDS_AUDIT_LOGIN_UID  = 1ULL << 21,
-        SD_BUS_CREDS_UNIQUE_NAME      = 1ULL << 22,
-        SD_BUS_CREDS_WELL_KNOWN_NAMES = 1ULL << 23,
-        SD_BUS_CREDS_DESCRIPTION      = 1ULL << 24,
-        _SD_BUS_CREDS_ALL             = (1ULL << 25) -1,
+        SD_BUS_CREDS_EUID             = 1ULL << 4,
+        SD_BUS_CREDS_SUID             = 1ULL << 5,
+        SD_BUS_CREDS_FSUID            = 1ULL << 6,
+        SD_BUS_CREDS_GID              = 1ULL << 7,
+        SD_BUS_CREDS_EGID             = 1ULL << 8,
+        SD_BUS_CREDS_SGID             = 1ULL << 9,
+        SD_BUS_CREDS_FSGID            = 1ULL << 10,
+        SD_BUS_CREDS_COMM             = 1ULL << 11,
+        SD_BUS_CREDS_TID_COMM         = 1ULL << 12,
+        SD_BUS_CREDS_EXE              = 1ULL << 13,
+        SD_BUS_CREDS_CMDLINE          = 1ULL << 14,
+        SD_BUS_CREDS_CGROUP           = 1ULL << 15,
+        SD_BUS_CREDS_UNIT             = 1ULL << 16,
+        SD_BUS_CREDS_USER_UNIT        = 1ULL << 17,
+        SD_BUS_CREDS_SLICE            = 1ULL << 18,
+        SD_BUS_CREDS_SESSION          = 1ULL << 19,
+        SD_BUS_CREDS_OWNER_UID        = 1ULL << 20,
+        SD_BUS_CREDS_EFFECTIVE_CAPS   = 1ULL << 21,
+        SD_BUS_CREDS_PERMITTED_CAPS   = 1ULL << 22,
+        SD_BUS_CREDS_INHERITABLE_CAPS = 1ULL << 23,
+        SD_BUS_CREDS_BOUNDING_CAPS    = 1ULL << 24,
+        SD_BUS_CREDS_SELINUX_CONTEXT  = 1ULL << 25,
+        SD_BUS_CREDS_AUDIT_SESSION_ID = 1ULL << 26,
+        SD_BUS_CREDS_AUDIT_LOGIN_UID  = 1ULL << 27,
+        SD_BUS_CREDS_UNIQUE_NAME      = 1ULL << 28,
+        SD_BUS_CREDS_WELL_KNOWN_NAMES = 1ULL << 29,
+        SD_BUS_CREDS_DESCRIPTION      = 1ULL << 30,
+        SD_BUS_CREDS_AUGMENT          = 1ULL << 63, /* special flag, if on sd-bus will augment creds struct, in a potentially race-full way. */
+        _SD_BUS_CREDS_ALL             = (1ULL << 31) -1,
 };
 
 enum {
@@ -305,7 +312,13 @@ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid);
 int sd_bus_creds_get_pid_starttime(sd_bus_creds *c, uint64_t *usec);
 int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid);
 int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid);
+int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid);
+int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid);
+int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid);
 int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid);
+int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid);
+int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid);
+int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid);
 int sd_bus_creds_get_comm(sd_bus_creds *c, const char **comm);
 int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **comm);
 int sd_bus_creds_get_exe(sd_bus_creds *c, const char **exe);

commit 1d58a1fe13cd725110be595c40cdc973d7e57d9e
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Nov 24 21:39:18 2014 +0100

    busctl: improve readability a bit

diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c
index 2cea21e..b2c7be2 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/libsystemd/sd-bus/busctl.c
@@ -67,6 +67,9 @@ static void pager_open_if_enabled(void) {
         pager_open(false);
 }
 
+#define NAME_IS_ACQUIRED INT_TO_PTR(1)
+#define NAME_IS_ACTIVATABLE INT_TO_PTR(2)
+
 static int list_bus_names(sd_bus *bus, char **argv) {
         _cleanup_strv_free_ char **acquired = NULL, **activatable = NULL;
         _cleanup_free_ char **merged = NULL;
@@ -99,7 +102,7 @@ static int list_bus_names(sd_bus *bus, char **argv) {
         STRV_FOREACH(i, acquired) {
                 max_i = MAX(max_i, strlen(*i));
 
-                r = hashmap_put(names, *i, INT_TO_PTR(1));
+                r = hashmap_put(names, *i, NAME_IS_ACQUIRED);
                 if (r < 0) {
                         log_error("Failed to add to hashmap: %s", strerror(-r));
                         return r;
@@ -109,7 +112,7 @@ static int list_bus_names(sd_bus *bus, char **argv) {
         STRV_FOREACH(i, activatable) {
                 max_i = MAX(max_i, strlen(*i));
 
-                r = hashmap_put(names, *i, INT_TO_PTR(2));
+                r = hashmap_put(names, *i, NAME_IS_ACTIVATABLE);
                 if (r < 0 && r != -EEXIST) {
                         log_error("Failed to add to hashmap: %s", strerror(-r));
                         return r;
@@ -137,7 +140,7 @@ static int list_bus_names(sd_bus *bus, char **argv) {
                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
                 sd_id128_t mid;
 
-                if (hashmap_get(names, *i) == INT_TO_PTR(2)) {
+                if (hashmap_get(names, *i) == NAME_IS_ACTIVATABLE) {
                         /* Activatable */
 
                         printf("%-*s", (int) max_i, *i);

commit 5cf4f2d1761cba895315d8f1f137afb3fdcd7a85
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Nov 24 21:37:26 2014 +0100

    bus: change creds dumping order to be more close to internal storage order

diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c
index 8814070..5e96b00 100644
--- a/src/libsystemd/sd-bus/bus-dump.c
+++ b/src/libsystemd/sd-bus/bus-dump.c
@@ -371,24 +371,16 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) {
         if (terse && ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID|SD_BUS_CREDS_UID|SD_BUS_CREDS_GID)) || r >= 0))
                 fputs("\n", f);
 
-        if (c->mask & SD_BUS_CREDS_EXE)
-                fprintf(f, "%sExe=%s%s%s", prefix, color, c->exe, suffix);
         if (c->mask & SD_BUS_CREDS_COMM)
                 fprintf(f, "%sComm=%s%s%s", prefix, color, c->comm, suffix);
         if (c->mask & SD_BUS_CREDS_TID_COMM)
                 fprintf(f, "%sTIDComm=%s%s%s", prefix, color, c->tid_comm, suffix);
+        if (c->mask & SD_BUS_CREDS_EXE)
+                fprintf(f, "%sExe=%s%s%s", prefix, color, c->exe, suffix);
 
         if (terse && (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM)))
                 fputs("\n", f);
 
-        if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)
-                fprintf(f, "%sLabel=%s%s%s", prefix, color, c->label, suffix);
-        if (c->mask & SD_BUS_CREDS_DESCRIPTION)
-                fprintf(f, "%sDescription=%s%s%s", prefix, color, c->description, suffix);
-
-        if (terse && (c->mask & (SD_BUS_CREDS_SELINUX_CONTEXT|SD_BUS_CREDS_DESCRIPTION)))
-                fputs("\n", f);
-
         if (sd_bus_creds_get_cmdline(c, &cmdline) >= 0) {
                 char **i;
 
@@ -403,6 +395,14 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) {
                 fprintf(f, "%s", suffix);
         }
 
+        if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)
+                fprintf(f, "%sLabel=%s%s%s", prefix, color, c->label, suffix);
+        if (c->mask & SD_BUS_CREDS_DESCRIPTION)
+                fprintf(f, "%sDescription=%s%s%s", prefix, color, c->description, suffix);
+
+        if (terse && (c->mask & (SD_BUS_CREDS_SELINUX_CONTEXT|SD_BUS_CREDS_DESCRIPTION)))
+                fputs("\n", f);
+
         if (c->mask & SD_BUS_CREDS_CGROUP)
                 fprintf(f, "%sCGroup=%s%s%s", prefix, color, c->cgroup, suffix);
         sd_bus_creds_get_unit(c, &u);

commit 62028d9c2b72bdbcec71d5c9f33d9a3bf143c6e4
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Nov 24 21:21:24 2014 +0100

    util: skip incomplete ucred information in getpeersec()

diff --git a/src/shared/util.c b/src/shared/util.c
index 0166052..b1ba0ed 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -6482,6 +6482,10 @@ int getpeercred(int fd, struct ucred *ucred) {
          * to namespacing issues */
         if (u.pid <= 0)
                 return -ENODATA;
+        if (u.uid == (uid_t) -1)
+                return -ENODATA;
+        if (u.gid == (gid_t) -1)
+                return -ENODATA;
 
         *ucred = u;
         return 0;

commit dc18cefdc3bdedddeddf05ede7d662ed15cde825
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Nov 24 21:20:53 2014 +0100

    sd-bus: don't blindly take incomplete ucred bits from AF_UNIX when constructing message

diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 9d6647b..6889754 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -420,10 +420,20 @@ int bus_message_from_header(
         m->n_fds = n_fds;
 
         if (ucred) {
-                m->creds.uid = ucred->uid;
                 m->creds.pid = ucred->pid;
+                m->creds.uid = ucred->uid;
                 m->creds.gid = ucred->gid;
-                m->creds.mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_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_t) -1)
+                        m->creds.mask |= SD_BUS_CREDS_UID;
+
+                if (m->creds.gid != (gid_t) -1)
+                        m->creds.mask |= SD_BUS_CREDS_GID;
         }
 
         if (label) {

commit bdb074a562e358d36590d09daddbf1f0c24e6676
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Nov 24 17:55:44 2014 +0100

    update TODO

diff --git a/TODO b/TODO
index 3e8d04c..328a46a 100644
--- a/TODO
+++ b/TODO
@@ -40,8 +40,6 @@ Features:
   races though, since we should flush out all journal messages before
   returning from the "systemctl stop".
 
-* increase CORE resource limit by default for all services, so that coredumpctl becomes useful
-
 * firstboot: make it useful to be run immediately after yum --installroot to set up a machine.
 
 * timesyncd + resolved: add ugly bus calls to set NTP and DNS servers per-interface, for usage by NM



More information about the systemd-commits mailing list