chiark / gitweb /
bus: include unique and well known names in credentials object
authorLennart Poettering <lennart@poettering.net>
Sat, 30 Nov 2013 03:14:10 +0000 (04:14 +0100)
committerLennart Poettering <lennart@poettering.net>
Sat, 30 Nov 2013 13:46:14 +0000 (14:46 +0100)
14 files changed:
TODO
src/core/service.c
src/libsystemd-bus/bus-control.c
src/libsystemd-bus/bus-convenience.c
src/libsystemd-bus/bus-creds.c
src/libsystemd-bus/bus-creds.h
src/libsystemd-bus/bus-dump.c
src/libsystemd-bus/bus-kernel.c
src/libsystemd-bus/bus-message.c
src/libsystemd-bus/busctl.c
src/libsystemd-bus/libsystemd-bus.sym
src/libsystemd-bus/sd-bus.c
src/shared/strv.c
src/systemd/sd-bus.h

diff --git a/TODO b/TODO
index 127994a..ff162ea 100644 (file)
--- a/TODO
+++ b/TODO
@@ -135,6 +135,7 @@ Features:
   - support "const" properties as flag
   - add API to clone sd_bus_message objects
   - SD_BUS_COMMENT() macro for inclusion in vtables, syntax inspired by gdbus
+  - unelss configure option is specified refuse connecting and creating kdbus, so that we can break compat
 
 * sd-event
   - allow multiple signal handlers per signal
index 10bf7cb..fcfeda7 100644 (file)
@@ -3678,7 +3678,7 @@ static void service_bus_name_owner_change(
 
                 /* Try to acquire PID from bus service */
 
-                r = sd_bus_get_owner(u->manager->api_bus, name, SD_BUS_CREDS_PID, NULL, &creds);
+                r = sd_bus_get_owner(u->manager->api_bus, name, SD_BUS_CREDS_PID, &creds);
                 if (r >= 0)
                         r = sd_bus_creds_get_pid(creds, &pid);
                 if (r >= 0) {
index 1d1f6d0..9e815a6 100644 (file)
@@ -251,24 +251,21 @@ _public_ int sd_bus_list_names(sd_bus *bus, char ***l) {
         return 0;
 }
 
-static int sd_bus_get_owner_dbus(
+static int bus_get_owner_dbus(
                 sd_bus *bus,
                 const char *name,
                 uint64_t mask,
-                char **owner,
                 sd_bus_creds **creds) {
 
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_bus_message_unref_ sd_bus_message *reply_unique = NULL, *reply = NULL;
         _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
-        _cleanup_free_ char *unique = NULL;
+        const char *unique = NULL;
         pid_t pid = 0;
         int r;
 
         /* Only query the owner if the caller wants to know it or if
          * the caller just wants to check whether a name exists */
-        if (owner || mask == 0) {
-                const char *found;
-
+        if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) {
                 r = sd_bus_call_method(
                                 bus,
                                 "org.freedesktop.DBus",
@@ -276,21 +273,15 @@ static int sd_bus_get_owner_dbus(
                                 "org.freedesktop.DBus",
                                 "GetNameOwner",
                                 NULL,
-                                &reply,
+                                &reply_unique,
                                 "s",
                                 name);
                 if (r < 0)
                         return r;
 
-                r = sd_bus_message_read(reply, "s", &found);
+                r = sd_bus_message_read(reply_unique, "s", &unique);
                 if (r < 0)
                         return r;
-
-                unique = strdup(found);
-                if (!unique)
-                        return -ENOMEM;
-
-                reply = sd_bus_message_unref(reply);
         }
 
         if (mask != 0) {
@@ -298,8 +289,19 @@ static int sd_bus_get_owner_dbus(
                 if (!c)
                         return -ENOMEM;
 
-                if ((mask & SD_BUS_CREDS_PID) ||
-                    mask & ~(SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|SD_BUS_CREDS_SELINUX_CONTEXT)) {
+                if ((mask & SD_BUS_CREDS_UNIQUE_NAME) && unique) {
+                        c->unique_name = strdup(unique);
+                        if (!c->unique_name)
+                                return -ENOMEM;
+
+                        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)) {
                         uint32_t u;
 
                         r = sd_bus_call_method(
@@ -311,7 +313,7 @@ static int sd_bus_get_owner_dbus(
                                         NULL,
                                         &reply,
                                         "s",
-                                        name);
+                                        unique ? unique : name);
                         if (r < 0)
                                 return r;
 
@@ -340,7 +342,7 @@ static int sd_bus_get_owner_dbus(
                                         NULL,
                                         &reply,
                                         "s",
-                                        name);
+                                        unique ? unique : name);
                         if (r < 0)
                                 return r;
 
@@ -367,7 +369,7 @@ static int sd_bus_get_owner_dbus(
                                         NULL,
                                         &reply,
                                         "s",
-                                        name);
+                                        unique ? unique : name);
                         if (r < 0)
                                 return r;
 
@@ -392,12 +394,225 @@ static int sd_bus_get_owner_dbus(
                 c = NULL;
         }
 
-        if (owner) {
-                *owner = unique;
-                unique = NULL;
+        return 0;
+}
+
+static int bus_get_owner_kdbus(
+                sd_bus *bus,
+                const char *name,
+                uint64_t mask,
+                sd_bus_creds **creds) {
+
+        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
+        struct kdbus_cmd_name_info *cmd;
+        struct kdbus_name_info *name_info;
+        struct kdbus_item *item;
+        size_t size;
+        uint64_t m, id;
+        int r;
+
+        r = bus_kernel_parse_unique_name(name, &id);
+        if (r < 0)
+                return r;
+        if (r > 0) {
+                size = offsetof(struct kdbus_cmd_name_info, name);
+                cmd = alloca0(size);
+                cmd->id = id;
+        } else {
+                size = offsetof(struct kdbus_cmd_name_info, name) + strlen(name) + 1;
+                cmd = alloca0(size);
+                strcpy(cmd->name, name);
         }
 
-        return 0;
+        cmd->size = size;
+
+        r = kdbus_translate_attach_flags(mask, (uint64_t*) &cmd->attach_flags);
+        if (r < 0)
+                return r;
+
+        r = ioctl(bus->input_fd, KDBUS_CMD_NAME_INFO, cmd);
+        if (r < 0)
+                return -errno;
+
+        name_info = (struct kdbus_name_info *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
+
+        c = bus_creds_new();
+        if (!c)
+                return -ENOMEM;
+
+        if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
+                if (asprintf(&c->unique_name, ":1.%llu", (unsigned long long) name_info->id) < 0)
+                        return -ENOMEM;
+
+                c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
+        }
+
+        KDBUS_PART_FOREACH(item, name_info, items) {
+
+                switch (item->type) {
+
+                case KDBUS_ITEM_CREDS:
+                        m = (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID | SD_BUS_CREDS_PID |
+                             SD_BUS_CREDS_TID | SD_BUS_CREDS_PID_STARTTIME) & mask;
+
+                        if (m) {
+                                c->uid = item->creds.uid;
+                                c->pid = item->creds.pid;
+                                c->gid = item->creds.gid;
+                                c->tid = item->creds.tid;
+                                c->pid_starttime = item->creds.starttime;
+                                c->mask |= m;
+                        }
+                        break;
+
+                case KDBUS_ITEM_PID_COMM:
+                        if (mask & SD_BUS_CREDS_COMM) {
+                                c->comm = strdup(item->str);
+                                if (!c->comm) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                c->mask |= SD_BUS_CREDS_COMM;
+                        }
+                        break;
+
+                case KDBUS_ITEM_TID_COMM:
+                        if (mask & SD_BUS_CREDS_TID_COMM) {
+                                c->tid_comm = strdup(item->str);
+                                if (!c->tid_comm) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                c->mask |= SD_BUS_CREDS_TID_COMM;
+                        }
+                        break;
+
+                case KDBUS_ITEM_EXE:
+                        if (mask & SD_BUS_CREDS_EXE) {
+                                c->exe = strdup(item->str);
+                                if (!c->exe) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                c->mask |= SD_BUS_CREDS_EXE;
+                        }
+                        break;
+
+                case KDBUS_ITEM_CMDLINE:
+                        if (mask & SD_BUS_CREDS_CMDLINE) {
+                                c->cmdline_size = item->size - KDBUS_PART_HEADER_SIZE;
+                                c->cmdline = memdup(item->data, c->cmdline_size);
+                                if (!c->cmdline) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                c->mask |= SD_BUS_CREDS_CMDLINE;
+                        }
+                        break;
+
+                case KDBUS_ITEM_CGROUP:
+                        m = (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) & mask;
+
+                        if (m) {
+                                c->cgroup = strdup(item->str);
+                                if (!c->cgroup) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                c->mask |= m;
+                        }
+                        break;
+
+                case KDBUS_ITEM_CAPS:
+                        m = (SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_PERMITTED_CAPS |
+                             SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
+
+                        if (m) {
+                                c->capability_size = item->size - KDBUS_PART_HEADER_SIZE;
+                                c->capability = memdup(item->data, c->capability_size);
+                                if (!c->capability) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                c->mask |= m;
+                        }
+                        break;
+
+                case KDBUS_ITEM_SECLABEL:
+                        if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
+                                c->label = strdup(item->str);
+                                if (!c->label) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+                        }
+                        break;
+
+                case KDBUS_ITEM_AUDIT:
+                        m = (SD_BUS_CREDS_AUDIT_SESSION_ID | SD_BUS_CREDS_AUDIT_LOGIN_UID) & mask;
+
+                        if (m) {
+                                c->audit_session_id = item->audit.sessionid;
+                                c->audit_login_uid = item->audit.loginuid;
+                                c->mask |= m;
+                        }
+                        break;
+
+                case KDBUS_ITEM_NAMES:
+                        if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
+                                c->well_known_names_size = item->size - KDBUS_PART_HEADER_SIZE;
+                                c->well_known_names = memdup(item->data, c->well_known_names_size);
+                                if (!c->well_known_names) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                c->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
+                        }
+                        break;
+                }
+        }
+
+        if (creds) {
+                *creds = c;
+                c = NULL;
+        }
+
+        r = 0;
+
+fail:
+        ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd->offset);
+        return r;
+}
+
+_public_ int sd_bus_get_owner(
+                sd_bus *bus,
+                const char *name,
+                uint64_t mask,
+                sd_bus_creds **creds) {
+
+        assert_return(bus, -EINVAL);
+        assert_return(name, -EINVAL);
+        assert_return(mask <= _SD_BUS_CREDS_MAX, -ENOTSUP);
+        assert_return(mask == 0 || creds, -EINVAL);
+        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
+        assert_return(!bus_pid_changed(bus), -ECHILD);
+
+        if (bus->is_kernel)
+                return bus_get_owner_kdbus(bus, name, mask, creds);
+        else
+                return bus_get_owner_dbus(bus, name, mask, creds);
 }
 
 static int add_name_change_match(sd_bus *bus,
@@ -578,192 +793,6 @@ static int add_name_change_match(sd_bus *bus,
         return 0;
 }
 
-static int kdbus_name_info(
-                sd_bus *bus,
-                const char *name,
-                uint64_t mask,
-                char **owner,
-                sd_bus_creds **creds) {
-
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
-        _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
-        _cleanup_free_ struct kdbus_cmd_name_info *cmd = NULL;
-        _cleanup_free_ char *unique = NULL;
-        struct kdbus_name_info *name_info;
-        struct kdbus_item *item;
-        uint64_t attach_flags, m;
-        size_t size;
-        int r;
-
-        r = kdbus_translate_attach_flags(mask, &attach_flags);
-        if (r < 0)
-                return r;
-
-        size = sizeof(struct kdbus_cmd_name_info) + strlen(name) + 1;
-        cmd = malloc0(size);
-        if (!cmd)
-                return -ENOMEM;
-
-        cmd ->size = size;
-        cmd->attach_flags = attach_flags;
-        strcpy(cmd->name, name);
-
-        r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_NAME_INFO, cmd);
-        if (r < 0)
-                return -errno;
-
-        name_info = (struct kdbus_name_info *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
-
-        asprintf(&unique, ":1.%llu", (unsigned long long) name_info->id);
-
-        c = bus_creds_new();
-        if (!c)
-                return -ENOMEM;
-
-        KDBUS_PART_FOREACH(item, name_info, items) {
-                switch (item->type) {
-                case KDBUS_ITEM_CREDS:
-                        m = (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID | SD_BUS_CREDS_PID |
-                             SD_BUS_CREDS_TID | SD_BUS_CREDS_PID_STARTTIME) & mask;
-
-                        if (m) {
-                                c->uid = item->creds.uid;
-                                c->pid = item->creds.pid;
-                                c->gid = item->creds.gid;
-                                c->tid = item->creds.tid;
-                                c->pid_starttime = item->creds.starttime;
-                                c->mask |= m;
-                        }
-                        break;
-
-                case KDBUS_ITEM_PID_COMM:
-                        if (mask & SD_BUS_CREDS_COMM) {
-                                c->comm = strdup(item->str);
-                                if (!c->comm)
-                                        return -ENOMEM;
-
-                                c->mask |= SD_BUS_CREDS_COMM;
-                        }
-                        break;
-
-                case KDBUS_ITEM_TID_COMM:
-                        if (mask & SD_BUS_CREDS_TID_COMM) {
-                                c->tid_comm = strdup(item->str);
-                                if (!c->tid_comm)
-                                        return -ENOMEM;
-
-                                c->mask |= SD_BUS_CREDS_TID_COMM;
-                        }
-                        break;
-
-                case KDBUS_ITEM_EXE:
-                        if (mask & SD_BUS_CREDS_EXE) {
-                                c->exe = strdup(item->str);
-                                if (!c->exe)
-                                        return -ENOMEM;
-
-                                c->mask |= SD_BUS_CREDS_EXE;
-                        }
-                        break;
-
-                case KDBUS_ITEM_CMDLINE:
-                        if (mask & SD_BUS_CREDS_CMDLINE) {
-                                c->cmdline_length = item->size - KDBUS_PART_HEADER_SIZE;
-                                c->cmdline = memdup(item->data, c->cmdline_length);
-                                if (!c->cmdline)
-                                        return -ENOMEM;
-
-                                c->mask |= SD_BUS_CREDS_CMDLINE;
-                        }
-                        break;
-
-                case KDBUS_ITEM_CGROUP:
-                        m = (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) & mask;
-
-                        if (m) {
-                                c->cgroup = strdup(item->str);
-                                if (!c->cgroup)
-                                        return -ENOMEM;
-
-                                c->mask |= m;
-                        }
-                        break;
-
-                case KDBUS_ITEM_CAPS:
-                        m = (SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_PERMITTED_CAPS |
-                             SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
-
-                        if (m) {
-                                c->capability_size = item->size - KDBUS_PART_HEADER_SIZE;
-                                c->capability = memdup(item->data, c->capability_size);
-                                if (!c->capability)
-                                        return -ENOMEM;
-
-                                c->mask |= m;
-                        }
-                        break;
-
-                case KDBUS_ITEM_SECLABEL:
-                        if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
-                                c->label = strdup(item->str);
-                                if (!c->label)
-                                        return -ENOMEM;
-
-                                c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
-                        }
-                        break;
-
-                case KDBUS_ITEM_AUDIT:
-                        m = (SD_BUS_CREDS_AUDIT_SESSION_ID | SD_BUS_CREDS_AUDIT_LOGIN_UID) & mask;
-
-                        if (m) {
-                                c->audit_session_id = item->audit.sessionid;
-                                c->audit_login_uid = item->audit.loginuid;
-                                c->mask |= m;
-                        }
-                        break;
-                }
-        }
-
-        r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_FREE, &cmd->offset);
-        if (r < 0)
-                return -errno;
-
-        if (creds) {
-                *creds = c;
-                c = NULL;
-        }
-
-        if (owner) {
-                *owner = unique;
-                unique = NULL;
-        }
-
-        return 0;
-}
-
-_public_ int sd_bus_get_owner(
-                sd_bus *bus,
-                const char *name,
-                uint64_t mask,
-                char **owner,
-                sd_bus_creds **creds) {
-
-        assert_return(bus, -EINVAL);
-        assert_return(name, -EINVAL);
-        assert_return(mask <= _SD_BUS_CREDS_MAX, -ENOTSUP);
-        assert_return(mask == 0 || creds, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
-        assert_return(!bus_pid_changed(bus), -ECHILD);
-
-        if (bus->is_kernel)
-                return kdbus_name_info(bus, name, mask, owner, creds);
-
-        return sd_bus_get_owner_dbus(bus, name, mask, owner, creds);
-}
-
 int bus_add_match_internal(
                 sd_bus *bus,
                 const char *match,
index 1a9c51f..d4c1929 100644 (file)
@@ -433,10 +433,10 @@ _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_b
                  * to get it from the sender or peer */
 
                 if (call->sender)
-                        return sd_bus_get_owner(call->bus, call->sender, mask, NULL, creds);
+                        return sd_bus_get_owner(call->bus, call->sender, mask, creds);
                 else
                         return sd_bus_get_peer_creds(call->bus, mask, creds);
         }
 
-        return sd_bus_creds_extend(c, mask, creds);
+        return bus_creds_extend_by_pid(c, mask, creds);
 }
index eee108b..54dcd41 100644 (file)
@@ -28,6 +28,7 @@
 #include "bus-message.h"
 #include "bus-util.h"
 #include "time-util.h"
+#include "strv.h"
 #include "bus-creds.h"
 
 enum {
@@ -48,7 +49,8 @@ void bus_creds_done(sd_bus_creds *c) {
         free(c->user_unit);
         free(c->slice);
 
-        free(c->cmdline_array);
+        strv_free(c->cmdline_array);
+        strv_free(c->well_known_names_array);
 }
 
 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
@@ -86,6 +88,8 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
                         free(c->cgroup);
                         free(c->capability);
                         free(c->label);
+                        free(c->unique_name);
+                        free(c->well_known_names);
                         free(c);
                 }
         } else {
@@ -333,34 +337,19 @@ _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
 }
 
 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
-        size_t n, i;
-        const char *p;
-        bool first;
-
         assert_return(c, -EINVAL);
         assert_return(c->cmdline, -ESRCH);
         assert_return(c->mask & SD_BUS_CREDS_CMDLINE, -ENODATA);
 
         assert(c->cmdline);
 
-        for (p = c->cmdline, n = 0; p < c->cmdline + c->cmdline_length; p++)
-                if (*p == 0)
-                        n++;
-
-        *(char***) &c->cmdline_array = new(char*, n + 1);
-        if (!c->cmdline_array)
-                return -ENOMEM;
-
-        for (p = c->cmdline, i = 0, first = true; p < c->cmdline + c->cmdline_length; p++) {
-                if (first)
-                        c->cmdline_array[i++] = (char*) p;
-
-                first = *p == 0;
+        if (!c->cmdline_array) {
+                c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
+                if (!c->cmdline_array)
+                        return -ENOMEM;
         }
 
-        c->cmdline_array[i] = NULL;
         *cmdline = c->cmdline_array;
-
         return 0;
 }
 
@@ -382,6 +371,32 @@ _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
         return 0;
 }
 
+_public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
+        assert_return(c, -EINVAL);
+        assert_return(unique_name, -EINVAL);
+        assert_return(c->mask & SD_BUS_CREDS_UNIQUE_NAME, -ENODATA);
+
+        *unique_name = c->unique_name;
+        return 0;
+}
+
+_public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
+        assert_return(c, -EINVAL);
+        assert_return(well_known_names, -EINVAL);
+        assert_return(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES, -ENODATA);
+
+        assert(c->well_known_names);
+
+        if (!c->well_known_names_array) {
+                c->well_known_names_array = strv_parse_nulstr(c->well_known_names, c->well_known_names_size);
+                if (!c->well_known_names_array)
+                        return -ENOMEM;
+        }
+
+        *well_known_names = c->well_known_names_array;
+        return 0;
+}
+
 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
         size_t sz;
 
@@ -625,11 +640,11 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
                 const char *p;
 
                 p = procfs_file_alloca(pid, "cmdline");
-                r = read_full_file(p, &c->cmdline, &c->cmdline_length);
+                r = read_full_file(p, &c->cmdline, &c->cmdline_size);
                 if (r < 0)
                         return r;
 
-                if (c->cmdline_length == 0) {
+                if (c->cmdline_size == 0) {
                         free(c->cmdline);
                         c->cmdline = NULL;
                 } else
@@ -677,12 +692,12 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
         return 0;
 }
 
-_public_ int sd_bus_creds_extend(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
+int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
         _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
         int r;
 
-        assert_return(c, -EINVAL);
-        assert_return(ret, -EINVAL);
+        assert(c);
+        assert(ret);
 
         if ((mask & ~c->mask) == 0) {
                 /* There's already all data we need. */
@@ -747,11 +762,11 @@ _public_ int sd_bus_creds_extend(sd_bus_creds *c, uint64_t mask, sd_bus_creds **
         }
 
         if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
-                n->cmdline = memdup(c->cmdline, c->cmdline_length);
+                n->cmdline = memdup(c->cmdline, c->cmdline_size);
                 if (!n->cmdline)
                         return -ENOMEM;
 
-                n->cmdline_length = c->cmdline_length;
+                n->cmdline_size = c->cmdline_size;
                 n->mask |= SD_BUS_CREDS_CMDLINE;
         }
 
@@ -782,6 +797,20 @@ _public_ int sd_bus_creds_extend(sd_bus_creds *c, uint64_t mask, sd_bus_creds **
                 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
         }
 
+        if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
+                n->unique_name = strdup(c->unique_name);
+                if (!n->unique_name)
+                        return -ENOMEM;
+        }
+
+        if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
+                n->well_known_names = memdup(c->well_known_names, c->well_known_names_size);
+                if (!n->well_known_names)
+                        return -ENOMEM;
+
+                n->well_known_names_size = c->well_known_names_size;
+        }
+
         /* Get more data */
 
         r = bus_creds_add_more(n, mask,
index e2416aa..269688a 100644 (file)
@@ -42,7 +42,7 @@ struct sd_bus_creds {
         char *exe;
 
         char *cmdline;
-        size_t cmdline_length;
+        size_t cmdline_size;
         char **cmdline_array;
 
         char *cgroup;
@@ -58,6 +58,12 @@ struct sd_bus_creds {
         uid_t audit_login_uid;
 
         char *label;
+
+        char *unique_name;
+
+        char *well_known_names;
+        size_t well_known_names_size;
+        char **well_known_names_array;
 };
 
 sd_bus_creds* bus_creds_new(void);
@@ -65,3 +71,5 @@ sd_bus_creds* bus_creds_new(void);
 void bus_creds_done(sd_bus_creds *c);
 
 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid);
+
+int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret);
index 9545e18..849a320 100644 (file)
@@ -300,7 +300,7 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f) {
         const char *u = NULL, *uu = NULL, *s = NULL, *sl = NULL;
         uid_t owner, audit_loginuid;
         uint32_t audit_sessionid;
-        char **cmdline = NULL;
+        char **cmdline = NULL, **well_known = NULL;
         int r;
 
         assert(c);
@@ -340,7 +340,7 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f) {
         if (sd_bus_creds_get_cmdline(c, &cmdline) >= 0) {
                 char **i;
 
-                fputs("  CommandLine=", f);
+                fputs("  CommandLine={", f);
                 STRV_FOREACH(i, cmdline) {
                         if (i != cmdline)
                                 fputc(' ', f);
@@ -348,7 +348,7 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f) {
                         fputs(*i, f);
                 }
 
-                fputs("\n", f);
+                fputs("}\n", f);
         }
 
         if (c->mask & SD_BUS_CREDS_CGROUP)
@@ -381,6 +381,23 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f) {
         if (audit_loginuid_is_set || audit_sessionid_is_set)
                 fputs("\n", f);
 
+        if (c->mask & SD_BUS_CREDS_UNIQUE_NAME)
+                fprintf(f, "  UniqueName=%s", c->unique_name);
+
+        if (sd_bus_creds_get_well_known_names(c, &well_known) >= 0) {
+                char **i;
+
+                fputs("  WellKnownNames={", f);
+                STRV_FOREACH(i, well_known) {
+                        if (i != well_known)
+                                fputc(' ', f);
+
+                        fputs(*i, f);
+                }
+
+                fputs("}\n", f);
+        }
+
         dump_capabilities(c, f, "EffectiveCapabilities", sd_bus_creds_has_effective_cap);
         dump_capabilities(c, f, "PermittedCapabilities", sd_bus_creds_has_permitted_cap);
         dump_capabilities(c, f, "InheritableCapabilities", sd_bus_creds_has_inheritable_cap);
index b63fe56..51e882c 100644 (file)
@@ -775,7 +775,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
 
                 case KDBUS_ITEM_CMDLINE:
                         m->creds.cmdline = d->str;
-                        m->creds.cmdline_length = l;
+                        m->creds.cmdline_size = l;
                         m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
                         break;
 
@@ -800,9 +800,14 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
                         destination = d->str;
                         break;
 
+                case KDBUS_ITEM_NAMES:
+                        m->creds.well_known_names = d->str;
+                        m->creds.well_known_names_size = l;
+                        m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES & bus->creds_mask;
+                        break;
+
                 case KDBUS_ITEM_FDS:
                 case KDBUS_ITEM_SECLABEL:
-                case KDBUS_ITEM_NAMES:
                         break;
 
                 default:
@@ -818,7 +823,8 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
                 m->sender = "org.freedesktop.DBus";
         else {
                 snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
-                m->sender = m->sender_buffer;
+                m->sender = m->creds.unique_name = m->sender_buffer;
+                m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & bus->creds_mask;
         }
 
         if (!m->destination) {
@@ -1029,6 +1035,9 @@ int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
         if (mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))
                 m |= KDBUS_ATTACH_AUDIT;
 
+        if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)
+                m |= KDBUS_ATTACH_NAMES;
+
         *kdbus_mask = m;
         return 0;
 }
index 56bf88c..639b9a6 100644 (file)
@@ -3826,6 +3826,12 @@ int bus_message_parse_fields(sd_bus_message *m) {
                                 return -EBADMSG;
 
                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
+
+                        if (r >= 0 && m->sender[0] == ':' && m->bus && m->bus->bus_client && !m->bus->is_kernel) {
+                                m->creds.unique_name = (char*) m->sender;
+                                m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
+                        }
+
                         break;
 
 
index 7649be2..f557e50 100644 (file)
@@ -82,7 +82,6 @@ static int list_bus_names(sd_bus *bus, char **argv) {
 
         STRV_FOREACH(i, l) {
                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
-                _cleanup_free_ char *owner = NULL;
                 sd_id128_t mid;
 
                 if (arg_no_unique && (*i)[0] == ':')
@@ -94,8 +93,9 @@ static int list_bus_names(sd_bus *bus, char **argv) {
 
                 printf("%-*s", (int) max_i, *i);
 
-                r = sd_bus_get_owner(bus, *i, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM, &owner, &creds);
+                r = sd_bus_get_owner(bus, *i, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|SD_BUS_CREDS_UNIQUE_NAME, &creds);
                 if (r >= 0) {
+                        const char *unique;
                         pid_t pid;
                         uid_t uid;
 
@@ -124,8 +124,9 @@ static int list_bus_names(sd_bus *bus, char **argv) {
                         } else
                                 fputs(" -               ", stdout);
 
-                        if (owner)
-                                printf(" %-20s", owner);
+                        r = sd_bus_creds_get_unique_name(creds, &unique);
+                        if (r >= 0)
+                                printf(" %-20s", unique);
                         else
                                 fputs(" -                   ", stdout);
 
index 054bc3f..389efc3 100644 (file)
@@ -157,7 +157,6 @@ global:
         sd_bus_creds_new_from_pid;
         sd_bus_creds_ref;
         sd_bus_creds_unref;
-        sd_bus_creds_extend;
         sd_bus_creds_get_mask;
         sd_bus_creds_get_uid;
         sd_bus_creds_get_gid;
@@ -181,6 +180,8 @@ global:
         sd_bus_creds_get_selinux_context;
         sd_bus_creds_get_audit_session_id;
         sd_bus_creds_get_audit_login_uid;
+        sd_bus_creds_get_unique_name;
+        sd_bus_creds_get_well_known_names;
 
         /* Error structures */
         sd_bus_error_free;
index 37b6fed..4bbeea9 100644 (file)
@@ -290,6 +290,9 @@ _public_ int sd_bus_negotiate_attach_creds(sd_bus *bus, uint64_t mask) {
         assert_return(bus->state == BUS_UNSET, -EPERM);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        /* The well knowns we need unconditionally, so that matches can work */
+        mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
+
         return kdbus_translate_attach_flags(mask, &bus->creds_mask);
 }
 
index adeee28..607c221 100644 (file)
@@ -531,7 +531,7 @@ char **strv_parse_nulstr(const char *s, size_t l) {
         assert(s || l <= 0);
 
         if (l <= 0)
-                return strv_new(NULL, NULL);
+                return new0(char*, 1);
 
         for (p = s; p < s + l; p++)
                 if (*p == 0)
index 1a269f5..648b955 100644 (file)
@@ -48,11 +48,11 @@ typedef struct {
 /* Flags */
 
 enum {
-        SD_BUS_CREDS_UID              = 1ULL << 0,
-        SD_BUS_CREDS_GID              = 1ULL << 1,
-        SD_BUS_CREDS_PID              = 1ULL << 2,
-        SD_BUS_CREDS_PID_STARTTIME    = 1ULL << 3,
-        SD_BUS_CREDS_TID              = 1ULL << 4,
+        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_GID              = 1ULL << 4,
         SD_BUS_CREDS_COMM             = 1ULL << 5,
         SD_BUS_CREDS_TID_COMM         = 1ULL << 6,
         SD_BUS_CREDS_EXE              = 1ULL << 7,
@@ -70,7 +70,9 @@ enum {
         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_MAX             = (1ULL << 22) -1,
+        SD_BUS_CREDS_UNIQUE_NAME      = 1ULL << 22,
+        SD_BUS_CREDS_WELL_KNOWN_NAMES = 1ULL << 23,
+        _SD_BUS_CREDS_MAX             = (1ULL << 24) -1,
 };
 
 /* Callbacks */
@@ -233,8 +235,8 @@ int sd_bus_message_rewind(sd_bus_message *m, int complete);
 int sd_bus_get_unique_name(sd_bus *bus, const char **unique);
 int sd_bus_request_name(sd_bus *bus, const char *name, int flags);
 int sd_bus_release_name(sd_bus *bus, const char *name);
-int sd_bus_list_names(sd_bus *bus, char ***l);
-int sd_bus_get_owner(sd_bus *bus, const char *name, uint64_t mask, char **owner, sd_bus_creds **creds); /* free/unref the result! */
+int sd_bus_list_names(sd_bus *bus, char ***l); /* free the results */
+int sd_bus_get_owner(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **creds); /* unref the result! */
 int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine);
 
 /* Convenience calls */
@@ -271,13 +273,11 @@ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c);
 sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c);
 uint64_t sd_bus_creds_get_mask(sd_bus_creds *c);
 
-int sd_bus_creds_extend(sd_bus_creds *c, uint64_t creds_mask, sd_bus_creds **ret); /* unref the result */
-
-int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid);
-int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid);
 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_gid(sd_bus_creds *c, gid_t *gid);
 int sd_bus_creds_get_comm(sd_bus_creds *c, const char **r);
 int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **r);
 int sd_bus_creds_get_exe(sd_bus_creds *c, const char **r);
@@ -295,6 +295,8 @@ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability);
 int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **r);
 int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid);
 int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *loginuid);
+int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **name);
+int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***names);
 
 /* Error structures */