summaryrefslogtreecommitdiff
path: root/src/libsystemd-bus/bus-control.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd-bus/bus-control.c')
-rw-r--r--src/libsystemd-bus/bus-control.c154
1 files changed, 94 insertions, 60 deletions
diff --git a/src/libsystemd-bus/bus-control.c b/src/libsystemd-bus/bus-control.c
index f217269f79..43e2848ecc 100644
--- a/src/libsystemd-bus/bus-control.c
+++ b/src/libsystemd-bus/bus-control.c
@@ -260,80 +260,114 @@ _public_ int sd_bus_get_owner(sd_bus *bus, const char *name, char **owner) {
return 0;
}
-_public_ int sd_bus_get_owner_uid(sd_bus *bus, const char *name, uid_t *uid) {
+_public_ int sd_bus_get_owner_creds(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **creds) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- uint32_t u;
+ _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
+ pid_t pid = 0;
int r;
- 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;
+ assert_return(bus, -EINVAL);
+ assert_return(name, -EINVAL);
+ assert_return(mask <= _SD_BUS_CREDS_MAX, -ENOTSUP);
+ assert_return(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",
- "GetConnectionUnixUser",
- NULL,
- &reply,
- "s",
- name);
- if (r < 0)
- return r;
+ c = bus_creds_new();
+ if (!c)
+ return -ENOMEM;
- r = sd_bus_message_read(reply, "u", &u);
- 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;
- *uid = (uid_t) u;
- return 0;
-}
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixProcessID",
+ NULL,
+ &reply,
+ "s",
+ name);
+ if (r < 0)
+ return r;
-_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;
+ r = sd_bus_message_read(reply, "u", &u);
+ if (r < 0)
+ return r;
- 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;
+ pid = u;
+ if (mask & SD_BUS_CREDS_PID) {
+ c->pid = u;
+ c->mask |= SD_BUS_CREDS_PID;
+ }
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.DBus",
- "/",
- "org.freedesktop.DBus",
- "GetConnectionUnixProcessID",
- NULL,
- &reply,
- "s",
- name);
- if (r < 0)
- return r;
+ reply = sd_bus_message_unref(reply);
+ }
+
+ 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);
+ }
+
+ 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;
+ }
- r = sd_bus_message_read(reply, "u", &u);
+ r = bus_creds_add_more(c, mask, pid, 0);
if (r < 0)
return r;
- if (u == 0)
- return -EIO;
+ *creds = c;
+ c = NULL;
- *pid = (uid_t) u;
return 0;
}