summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-11-30 04:14:10 +0100
committerLennart Poettering <lennart@poettering.net>2013-11-30 14:46:14 +0100
commit49b832c5b810f4d8bb59249ff25472fd670503dc (patch)
treeff71bd5e8318578db77f85d21843a273b60fce4b
parent2377ae1ff6ee2987a300d4df17320c2d9c61d23d (diff)
bus: include unique and well known names in credentials object
-rw-r--r--TODO1
-rw-r--r--src/core/service.c2
-rw-r--r--src/libsystemd-bus/bus-control.c449
-rw-r--r--src/libsystemd-bus/bus-convenience.c4
-rw-r--r--src/libsystemd-bus/bus-creds.c83
-rw-r--r--src/libsystemd-bus/bus-creds.h10
-rw-r--r--src/libsystemd-bus/bus-dump.c23
-rw-r--r--src/libsystemd-bus/bus-kernel.c15
-rw-r--r--src/libsystemd-bus/bus-message.c6
-rw-r--r--src/libsystemd-bus/busctl.c9
-rw-r--r--src/libsystemd-bus/libsystemd-bus.sym3
-rw-r--r--src/libsystemd-bus/sd-bus.c3
-rw-r--r--src/shared/strv.c2
-rw-r--r--src/systemd/sd-bus.h26
14 files changed, 371 insertions, 265 deletions
diff --git a/TODO b/TODO
index 127994a809..ff162ea3f7 100644
--- 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
diff --git a/src/core/service.c b/src/core/service.c
index 10bf7cb5a6..fcfeda7382 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -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) {
diff --git a/src/libsystemd-bus/bus-control.c b/src/libsystemd-bus/bus-control.c
index 1d1f6d0f39..9e815a6c94 100644
--- a/src/libsystemd-bus/bus-control.c
+++ b/src/libsystemd-bus/bus-control.c
@@ -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,
diff --git a/src/libsystemd-bus/bus-convenience.c b/src/libsystemd-bus/bus-convenience.c
index 1a9c51fdc7..d4c1929ff7 100644
--- a/src/libsystemd-bus/bus-convenience.c
+++ b/src/libsystemd-bus/bus-convenience.c
@@ -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);
}
diff --git a/src/libsystemd-bus/bus-creds.c b/src/libsystemd-bus/bus-creds.c
index eee108b0be..54dcd41b14 100644
--- a/src/libsystemd-bus/bus-creds.c
+++ b/src/libsystemd-bus/bus-creds.c
@@ -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,
diff --git a/src/libsystemd-bus/bus-creds.h b/src/libsystemd-bus/bus-creds.h
index e2416aa501..269688a488 100644
--- a/src/libsystemd-bus/bus-creds.h
+++ b/src/libsystemd-bus/bus-creds.h
@@ -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);
diff --git a/src/libsystemd-bus/bus-dump.c b/src/libsystemd-bus/bus-dump.c
index 9545e181d8..849a3200df 100644
--- a/src/libsystemd-bus/bus-dump.c
+++ b/src/libsystemd-bus/bus-dump.c
@@ -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);
diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c
index b63fe56c41..51e882c73d 100644
--- a/src/libsystemd-bus/bus-kernel.c
+++ b/src/libsystemd-bus/bus-kernel.c
@@ -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;
}
diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c
index 56bf88c394..639b9a6214 100644
--- a/src/libsystemd-bus/bus-message.c
+++ b/src/libsystemd-bus/bus-message.c
@@ -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;
diff --git a/src/libsystemd-bus/busctl.c b/src/libsystemd-bus/busctl.c
index 7649be29f4..f557e50036 100644
--- a/src/libsystemd-bus/busctl.c
+++ b/src/libsystemd-bus/busctl.c
@@ -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);
diff --git a/src/libsystemd-bus/libsystemd-bus.sym b/src/libsystemd-bus/libsystemd-bus.sym
index 054bc3ff0b..389efc3273 100644
--- a/src/libsystemd-bus/libsystemd-bus.sym
+++ b/src/libsystemd-bus/libsystemd-bus.sym
@@ -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;
diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index 37b6fedf03..4bbeea92f3 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -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);
}
diff --git a/src/shared/strv.c b/src/shared/strv.c
index adeee282b7..607c221ae6 100644
--- a/src/shared/strv.c
+++ b/src/shared/strv.c
@@ -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)
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 1a269f53b1..648b955cf0 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -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 */