_public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) {
int r;
- if (!bus)
- return -EINVAL;
- if (!unique)
- return -EINVAL;
- if (bus_pid_changed(bus))
- return -ECHILD;
+ assert_return(bus, -EINVAL);
+ assert_return(unique, -EINVAL);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
r = bus_ensure_running(bus);
if (r < 0)
uint32_t ret;
int r;
- if (!bus)
- return -EINVAL;
- if (!name)
- return -EINVAL;
- if (!bus->bus_client)
- return -EINVAL;
- if (!BUS_IS_OPEN(bus->state))
- return -ENOTCONN;
- if (bus_pid_changed(bus))
- return -ECHILD;
+ assert_return(bus, -EINVAL);
+ assert_return(name, -EINVAL);
+ assert_return(bus->bus_client, -EINVAL);
+ assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
if (bus->is_kernel) {
struct kdbus_cmd_name *n;
#endif
r = ioctl(bus->input_fd, KDBUS_CMD_NAME_ACQUIRE, n);
- if (r < 0)
+ if (r < 0) {
+ if (errno == -EALREADY)
+ return SD_BUS_NAME_ALREADY_OWNER;
+
+ if (errno == -EEXIST)
+ return SD_BUS_NAME_EXISTS;
+
return -errno;
+ }
- return n->flags;
+ if (n->flags & KDBUS_NAME_IN_QUEUE)
+ return SD_BUS_NAME_IN_QUEUE;
+
+ return SD_BUS_NAME_PRIMARY_OWNER;
} else {
r = sd_bus_call_method(
bus,
uint32_t ret;
int r;
- if (!bus)
- return -EINVAL;
- if (!name)
- return -EINVAL;
- if (!bus->bus_client)
- return -EINVAL;
- if (!BUS_IS_OPEN(bus->state))
- return -ENOTCONN;
- if (bus_pid_changed(bus))
- return -ECHILD;
+ assert_return(bus, -EINVAL);
+ assert_return(name, -EINVAL);
+ assert_return(bus->bus_client, -EINVAL);
+ assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
if (bus->is_kernel) {
struct kdbus_cmd_name *n;
char **x = NULL;
int r;
- if (!bus)
- return -EINVAL;
- if (!l)
- return -EINVAL;
- if (!BUS_IS_OPEN(bus->state))
- return -ENOTCONN;
- if (bus_pid_changed(bus))
- return -ECHILD;
+ assert_return(bus, -EINVAL);
+ assert_return(l, -EINVAL);
+ assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.DBus",
- "/",
- "org.freedesktop.DBus",
- "ListNames",
- NULL,
- &reply1,
- NULL);
- if (r < 0)
- return r;
+ if (bus->is_kernel) {
+ _cleanup_free_ struct kdbus_cmd_names *names = NULL;
+ struct kdbus_cmd_name *name;
+ size_t size;
+
+ /* assume 8k size first. If that doesn't suffice, kdbus will tell us
+ * how big the buffer needs to be. */
+ size = 8192;
+
+ for(;;) {
+ names = realloc(names, size);
+ if (!names)
+ return -ENOMEM;
+
+ names->size = size;
+ names->flags = KDBUS_NAME_LIST_UNIQUE_NAMES;
+
+ r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_NAME_LIST, names);
+ if (r < 0) {
+ if (errno == ENOBUFS && size != names->size) {
+ size = names->size;
+ continue;
+ }
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.DBus",
- "/",
- "org.freedesktop.DBus",
- "ListActivatableNames",
- NULL,
- &reply2,
- NULL);
- if (r < 0)
- return r;
+ return -errno;
+ }
- r = bus_message_read_strv_extend(reply1, &x);
- if (r < 0) {
- strv_free(x);
- return r;
- }
+ break;
+ }
- r = bus_message_read_strv_extend(reply2, &x);
- if (r < 0) {
- strv_free(x);
- return r;
+ KDBUS_PART_FOREACH(name, names, names) {
+ char *n;
+
+ if (name->size > sizeof(*name))
+ n = name->name;
+ else
+ asprintf(&n, ":1.%llu", (unsigned long long) name->id);
+
+ r = strv_extend(&x, n);
+ if (r < 0)
+ return -ENOMEM;
+ }
+
+ *l = x;
+ } else {
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/",
+ "org.freedesktop.DBus",
+ "ListNames",
+ NULL,
+ &reply1,
+ NULL);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/",
+ "org.freedesktop.DBus",
+ "ListActivatableNames",
+ NULL,
+ &reply2,
+ NULL);
+ if (r < 0)
+ return r;
+
+ r = bus_message_read_strv_extend(reply1, &x);
+ if (r < 0) {
+ strv_free(x);
+ return r;
+ }
+
+ r = bus_message_read_strv_extend(reply2, &x);
+ if (r < 0) {
+ strv_free(x);
+ return r;
+ }
+
+ *l = strv_uniq(x);
}
- *l = strv_uniq(x);
return 0;
}
-_public_ int sd_bus_get_owner(sd_bus *bus, const char *name, char **owner) {
+_public_ int sd_bus_get_owner(
+ sd_bus *bus,
+ const char *name,
+ uint64_t mask,
+ char **owner,
+ sd_bus_creds **creds) {
+
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- const char *found;
+ _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
+ _cleanup_free_ char *unique = NULL;
+ pid_t pid = 0;
int r;
- if (!bus)
- return -EINVAL;
- if (!name)
- return -EINVAL;
- if (!BUS_IS_OPEN(bus->state))
- return -ENOTCONN;
- if (bus_pid_changed(bus))
- return -ECHILD;
+ 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);
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.DBus",
- "/",
- "org.freedesktop.DBus",
- "GetNameOwner",
- NULL,
- &reply,
- "s",
- name);
- if (r < 0)
- return 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;
- r = sd_bus_message_read(reply, "s", &found);
- if (r < 0)
- return r;
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/",
+ "org.freedesktop.DBus",
+ "GetNameOwner",
+ NULL,
+ &reply,
+ "s",
+ name);
+ if (r < 0)
+ return r;
- if (owner) {
- char *t;
+ r = sd_bus_message_read(reply, "s", &found);
+ if (r < 0)
+ return r;
- t = strdup(found);
- if (!t)
+ unique = strdup(found);
+ if (!unique)
return -ENOMEM;
- *owner = t;
+ reply = sd_bus_message_unref(reply);
}
- return 0;
-}
-
-_public_ int sd_bus_get_owner_uid(sd_bus *bus, const char *name, uid_t *uid) {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- uint32_t u;
- int r;
+ if (mask != 0) {
+ c = bus_creds_new();
+ if (!c)
+ return -ENOMEM;
- if (!bus)
- return -EINVAL;
- if (!name)
- return -EINVAL;
- if (!uid)
- return -EINVAL;
- if (!BUS_IS_OPEN(bus->state))
- return -ENOTCONN;
- if (bus_pid_changed(bus))
- return -ECHILD;
-
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.DBus",
- "/",
- "org.freedesktop.DBus",
- "GetConnectionUnixUser",
- NULL,
- &reply,
- "s",
- name);
- if (r < 0)
- return r;
+ if ((mask & SD_BUS_CREDS_PID) ||
+ mask & ~(SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|SD_BUS_CREDS_SELINUX_CONTEXT)) {
+ uint32_t u;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixProcessID",
+ NULL,
+ &reply,
+ "s",
+ name);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read(reply, "u", &u);
+ if (r < 0)
+ return r;
+
+ pid = u;
+ if (mask & SD_BUS_CREDS_PID) {
+ c->pid = u;
+ c->mask |= SD_BUS_CREDS_PID;
+ }
- r = sd_bus_message_read(reply, "u", &u);
- if (r < 0)
- return r;
+ reply = sd_bus_message_unref(reply);
+ }
- *uid = (uid_t) u;
- return 0;
-}
+ if (mask & SD_BUS_CREDS_UID) {
+ uint32_t u;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixUser",
+ NULL,
+ &reply,
+ "s",
+ name);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read(reply, "u", &u);
+ if (r < 0)
+ return r;
+
+ c->uid = u;
+ c->mask |= SD_BUS_CREDS_UID;
+
+ reply = sd_bus_message_unref(reply);
+ }
-_public_ int sd_bus_get_owner_pid(sd_bus *bus, const char *name, pid_t *pid) {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- uint32_t u;
- int r;
+ if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
+ const void *p;
+ size_t sz;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/",
+ "org.freedesktop.DBus",
+ "GetConnectionSELinuxSecurityContext",
+ NULL,
+ &reply,
+ "s",
+ name);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read_array(reply, 'y', &p, &sz);
+ if (r < 0)
+ return r;
+
+ c->label = strndup(p, sz);
+ if (!c->label)
+ return -ENOMEM;
+
+ c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+ }
- if (!bus)
- return -EINVAL;
- if (!name)
- return -EINVAL;
- if (!pid)
- return -EINVAL;
- if (!BUS_IS_OPEN(bus->state))
- return -ENOTCONN;
- if (bus_pid_changed(bus))
- return -ECHILD;
-
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.DBus",
- "/",
- "org.freedesktop.DBus",
- "GetConnectionUnixProcessID",
- NULL,
- &reply,
- "s",
- name);
- if (r < 0)
- return r;
+ r = bus_creds_add_more(c, mask, pid, 0);
+ if (r < 0)
+ return r;
+ }
- r = sd_bus_message_read(reply, "u", &u);
- if (r < 0)
- return r;
+ if (creds) {
+ *creds = c;
+ c = NULL;
+ }
- if (u == 0)
- return -EIO;
+ if (owner) {
+ *owner = unique;
+ unique = NULL;
+ }
- *pid = (uid_t) u;
return 0;
}
item->type = KDBUS_MATCH_BLOOM;
memcpy(item->data64, bloom, BLOOM_SIZE);
- item = KDBUS_ITEM_NEXT(item);
+ item = KDBUS_PART_NEXT(item);
}
if (sender) {
}
_public_ int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+ _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
const char *mid;
int r;
- if (!bus)
- return -EINVAL;
- if (!name)
- return -EINVAL;
- if (!BUS_IS_OPEN(bus->state))
- return -ENOTCONN;
- if (bus_pid_changed(bus))
- return -ECHILD;
+ assert_return(bus, -EINVAL);
+ assert_return(name, -EINVAL);
+ assert_return(machine, -EINVAL);
+ assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
if (streq_ptr(name, bus->unique_name))
return sd_id128_get_machine(machine);
- r = sd_bus_call_method(bus,
- name,
- "/",
- "org.freedesktop.DBus.Peer",
- "GetMachineId",
- NULL,
- &reply,
- NULL);
+ r = sd_bus_message_new_method_call(
+ bus,
+ name,
+ "/",
+ "org.freedesktop.DBus.Peer",
+ "GetMachineId", &m);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_set_no_auto_start(m, true);
+ if (r < 0)
+ return r;
+ r = sd_bus_call(bus, m, 0, NULL, &reply);
if (r < 0)
return r;