static int bus_get_owner_creds_dbus1(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *c = NULL;
pid_t pid = 0;
- bool do_label;
+ bool do_label, do_groups;
int r;
assert(bus);
do_label = bus->label && (mask & SD_BUS_CREDS_SELINUX_CONTEXT);
+ do_groups = bus->n_groups != (size_t) -1 && (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS);
/* Avoid allocating anything if we have no chance of returning useful data */
- if (!bus->ucred_valid && !do_label)
+ if (!bus->ucred_valid && !do_label && !do_groups)
return -ENODATA;
c = bus_creds_new();
c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
}
+ if (do_groups) {
+ c->supplementary_gids = newdup(gid_t, bus->groups, bus->n_groups);
+ if (!c->supplementary_gids)
+ return -ENOMEM;
+
+ c->n_supplementary_gids = bus->n_groups;
+
+ c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
+ }
+
r = bus_creds_add_more(c, mask, pid, 0);
if (r < 0)
return r;
struct ucred ucred;
char *label;
+ gid_t *groups;
+ size_t n_groups;
uint64_t creds_mask;
int r;
assert(b);
+ assert(!b->ucred_valid);
+ assert(!b->label);
+ assert(b->n_groups == (size_t) -1);
/* Get the peer for socketpair() sockets */
b->ucred_valid = getpeercred(b->input_fd, &b->ucred) >= 0;
/* Get the SELinux context of the peer */
r = getpeersec(b->input_fd, &b->label);
- if (r < 0 && r != -EOPNOTSUPP)
+ if (r < 0 && !IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT))
log_debug_errno(r, "Failed to determine peer security context: %m");
+
+ /* Get the list of auxiliary groups of the peer */
+ r = getpeergroups(b->input_fd, &b->groups);
+ if (r < 0) {
+ if (!IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT))
+ log_debug_errno(r, "Failed to determine peer groups list: %m");
+
+ b->n_groups = (size_t) -1;
+ } else
+ b->n_groups = (size_t) r;
}
static int bus_socket_start_auth_client(sd_bus *b) {
bus_close_fds(b);
free(b->label);
+ free(b->groups);
free(b->rbuffer);
free(b->unique_name);
free(b->auth_buffer);
r->hello_flags |= KDBUS_HELLO_ACCEPT_FD;
r->attach_flags |= KDBUS_ATTACH_NAMES;
r->original_pid = getpid_cached();
+ r->n_groups = (size_t) -1;
assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0);