sd_bus_creds_ref;
sd_bus_creds_unref;
sd_bus_creds_get_mask;
+ sd_bus_creds_get_augmented_mask;
sd_bus_creds_get_uid;
sd_bus_creds_get_gid;
sd_bus_creds_get_pid;
return -ENOTCONN;
if (capability >= 0) {
+
r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds);
if (r < 0)
return r;
+ /* We cannot use augmented caps for authorization,
+ * since then data is acquired raceful from
+ * /proc. This can never actually happen, but let's
+ * better be safe than sorry, and do an extra check
+ * here. */
+ assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_EFFECTIVE_CAPS) == 0, -EPERM);
+
/* Note that not even on kdbus we might have the caps
* field, due to faked identities, or namespace
* translation issues. */
if (our_uid != 0 || !know_caps || capability < 0) {
uid_t sender_uid;
+ /* We cannot use augmented uid/euid for authorization,
+ * since then data is acquired raceful from
+ * /proc. This can never actually happen, but let's
+ * better be safe than sorry, and do an extra check
+ * here. */
+ assert_return((sd_bus_creds_get_augmented_mask(creds) & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID)) == 0, -EPERM);
+
/* Try to use the EUID, if we have it. */
r = sd_bus_creds_get_euid(creds, &sender_uid);
if (r < 0)
return c->mask;
}
+_public_ uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds *c) {
+ assert_return(c, 0);
+
+ return c->augmented;
+}
+
sd_bus_creds* bus_creds_new(void) {
sd_bus_creds *c;
if (!(mask & SD_BUS_CREDS_AUGMENT))
return 0;
- missing = mask & ~c->mask;
- if (missing == 0)
- return 0;
-
/* Try to retrieve PID from creds if it wasn't passed to us */
if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
pid = c->pid;
- if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
- tid = c->pid;
-
/* Without pid we cannot do much... */
if (pid <= 0)
return 0;
- if (pid > 0) {
- c->pid = pid;
- c->mask |= SD_BUS_CREDS_PID;
- }
+ /* Try to retrieve TID from creds if it wasn't passed to us */
+ if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
+ tid = c->tid;
+
+ /* Calculate what we shall and can add */
+ missing = mask & ~(c->mask|SD_BUS_CREDS_PID|SD_BUS_CREDS_TID|SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_DESCRIPTION|SD_BUS_CREDS_AUGMENT);
+ if (missing == 0)
+ return 0;
+
+ c->pid = pid;
+ c->mask |= SD_BUS_CREDS_PID;
if (tid > 0) {
c->tid = tid;
c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
}
+ c->augmented = missing & c->mask;
+
return 0;
}
n->mask |= SD_BUS_CREDS_DESCRIPTION;
}
+ n->augmented = c->augmented & n->mask;
+
/* Get more data */
- r = bus_creds_add_more(n, mask,
- c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
- c->mask & SD_BUS_CREDS_TID ? c->tid : 0);
+ r = bus_creds_add_more(n, mask, 0, 0);
if (r < 0)
return r;
struct sd_bus_creds {
bool allocated;
unsigned n_ref;
+
uint64_t mask;
+ uint64_t augmented;
uid_t uid;
uid_t euid;
if (r < 0)
return r;
+ /* Don't trust augmented credentials for authorization */
+ assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_EUID) == 0, -EPERM);
+
r = sd_bus_creds_get_euid(creds, &sender_uid);
if (r < 0)
return r;
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(const sd_bus_creds *c);
+uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds *c);
int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid);
int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid);