summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libsystemd/sd-bus/bus-control.c78
-rw-r--r--src/libsystemd/sd-bus/bus-internal.h2
-rw-r--r--src/libsystemd/sd-bus/bus-socket.c11
3 files changed, 89 insertions, 2 deletions
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index 864acd73ac..287cde6d41 100644
--- a/src/libsystemd/sd-bus/bus-control.c
+++ b/src/libsystemd/sd-bus/bus-control.c
@@ -722,9 +722,51 @@ _public_ int sd_bus_get_name_creds(
return 0;
}
+static int parse_sockaddr_string(const char *t, char **ret_comm, char **ret_description) {
+ _cleanup_free_ char *comm = NULL, *description = NULL;
+ const char *e, *sl;
+
+ assert(t);
+ assert(ret_comm);
+ assert(ret_description);
+
+ e = strstrafter(t, "/bus/");
+ if (!e) {
+ log_debug("Didn't find /bus/ substring in peer socket address, ignoring.");
+ goto not_found;
+ }
+
+ sl = strchr(e, '/');
+ if (!sl) {
+ log_debug("Didn't find / substring after /bus/ in peer socket address, ignoring.");
+ goto not_found;
+ }
+
+ if (sl - e > 0) {
+ comm = strndup(e, sl - e);
+ if (!comm)
+ return -ENOMEM;
+ }
+
+ sl++;
+ if (!isempty(sl)) {
+ description = strdup(sl);
+ if (!description)
+ return -ENOMEM;
+ }
+
+ *ret_comm = TAKE_PTR(comm);
+ *ret_description = TAKE_PTR(description);
+ return 0;
+
+not_found:
+ *ret_comm = *ret_description = NULL;
+ return 0;
+}
+
_public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL;
- bool do_label, do_groups;
+ bool do_label, do_groups, do_sockaddr_peer;
pid_t pid = 0;
int r;
@@ -742,9 +784,12 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r
do_label = bus->label && (mask & SD_BUS_CREDS_SELINUX_CONTEXT);
do_groups = bus->n_groups != SIZE_MAX && (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS);
+ do_sockaddr_peer = bus->sockaddr_size_peer >= offsetof(struct sockaddr_un, sun_path) + 1 &&
+ bus->sockaddr_peer.sa.sa_family == AF_UNIX &&
+ bus->sockaddr_peer.un.sun_path[0] == 0;
/* Avoid allocating anything if we have no chance of returning useful data */
- if (!bus->ucred_valid && !do_label && !do_groups)
+ if (!bus->ucred_valid && !do_label && !do_groups && !do_sockaddr_peer)
return -ENODATA;
c = bus_creds_new();
@@ -786,6 +831,35 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r
c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
}
+ if (do_sockaddr_peer) {
+ _cleanup_free_ char *t = NULL;
+
+ assert(bus->sockaddr_size_peer >= offsetof(struct sockaddr_un, sun_path) + 1);
+ assert(bus->sockaddr_peer.sa.sa_family == AF_UNIX);
+ assert(bus->sockaddr_peer.un.sun_path[0] == 0);
+
+ /* So this is an abstract namespace socket, good. Now let's find the data we are interested in */
+ r = make_cstring(bus->sockaddr_peer.un.sun_path + 1,
+ bus->sockaddr_size_peer - offsetof(struct sockaddr_un, sun_path) - 1,
+ MAKE_CSTRING_ALLOW_TRAILING_NUL,
+ &t);
+ if (r == -ENOMEM)
+ return r;
+ if (r < 0)
+ log_debug_errno(r, "Can't extract string from peer socket address, ignoring: %m");
+ else {
+ r = parse_sockaddr_string(t, &c->comm, &c->description);
+ if (r < 0)
+ return r;
+
+ if (c->comm)
+ c->mask |= SD_BUS_CREDS_COMM & mask;
+
+ if (c->description)
+ c->mask |= SD_BUS_CREDS_DESCRIPTION & mask;
+ }
+ }
+
r = bus_creds_add_more(c, mask, pid, 0);
if (r < 0 && r != -ESRCH) /* If the process vanished, then don't complain, just return what we got */
return r;
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
index 0e44897e0e..1cf6974bff 100644
--- a/src/libsystemd/sd-bus/bus-internal.h
+++ b/src/libsystemd/sd-bus/bus-internal.h
@@ -267,6 +267,8 @@ struct sd_bus {
char *label;
gid_t *groups;
size_t n_groups;
+ union sockaddr_union sockaddr_peer;
+ socklen_t sockaddr_size_peer;
uint64_t creds_mask;
diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
index 11f4aa9669..741d54cabd 100644
--- a/src/libsystemd/sd-bus/bus-socket.c
+++ b/src/libsystemd/sd-bus/bus-socket.c
@@ -652,6 +652,17 @@ static void bus_get_peercred(sd_bus *b) {
b->n_groups = (size_t) r;
else if (!IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT))
log_debug_errno(r, "Failed to determine peer's group list: %m");
+
+ /* Let's query the peers socket address, it might carry information such as the peer's comm or
+ * description string */
+ zero(b->sockaddr_peer);
+ b->sockaddr_size_peer = 0;
+
+ socklen_t l = sizeof(b->sockaddr_peer) - 1; /* Leave space for a NUL */
+ if (getpeername(b->input_fd, &b->sockaddr_peer.sa, &l) < 0)
+ log_debug_errno(errno, "Failed to get peer's socket address, ignoring: %m");
+ else
+ b->sockaddr_size_peer = l;
}
static int bus_socket_start_auth_client(sd_bus *b) {