bus: include unique and well known names in credentials object

This commit is contained in:
Lennart Poettering 2013-11-30 04:14:10 +01:00
parent 2377ae1ff6
commit 49b832c5b8
14 changed files with 371 additions and 265 deletions

1
TODO
View File

@ -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

View 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) {

View 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,

View 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);
}

View 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,

View 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);

View 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);

View 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;
}

View 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;

View 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);

View 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;

View 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);
}

View 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)

View 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 */