chiark / gitweb /
sd-bus: when augmenting creds, remember which ones were augmented
[elogind.git] / src / libelogind / sd-bus / bus-creds.c
index 39cbdba9c32dcd83f846987650721870df53c322..f86bd27ffc66ec28649cded930de8a1d34543086 100644 (file)
@@ -130,6 +130,12 @@ _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
         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;
 
@@ -230,7 +236,6 @@ _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
         return 0;
 }
 
-
 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
         assert_return(c, -EINVAL);
         assert_return(egid, -EINVAL);
@@ -563,10 +568,11 @@ static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
         assert(capability >= 0);
         assert(c->capability);
 
-        sz = DIV_ROUND_UP(cap_last_cap(), 32U);
-        if ((unsigned)capability > cap_last_cap())
+        if ((unsigned) capability > cap_last_cap())
                 return 0;
 
+        sz = DIV_ROUND_UP(cap_last_cap(), 32U);
+
         return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
 }
 
@@ -663,25 +669,25 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
         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;
@@ -720,10 +726,15 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
                                                 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
                                                         return -EIO;
 
-                                                c->uid = (uid_t) uid;
-                                                c->euid = (uid_t) euid;
-                                                c->suid = (uid_t) suid;
-                                                c->fsuid = (uid_t) fsuid;
+                                                if (missing & SD_BUS_CREDS_UID)
+                                                        c->uid = (uid_t) uid;
+                                                if (missing & SD_BUS_CREDS_EUID)
+                                                        c->euid = (uid_t) euid;
+                                                if (missing & SD_BUS_CREDS_SUID)
+                                                        c->suid = (uid_t) suid;
+                                                if (missing & SD_BUS_CREDS_FSUID)
+                                                        c->fsuid = (uid_t) fsuid;
+
                                                 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
                                                 continue;
                                         }
@@ -738,10 +749,15 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
                                                 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
                                                         return -EIO;
 
-                                                c->gid = (gid_t) gid;
-                                                c->egid = (gid_t) egid;
-                                                c->sgid = (gid_t) sgid;
-                                                c->fsgid = (gid_t) fsgid;
+                                                if (missing & SD_BUS_CREDS_GID)
+                                                        c->gid = (gid_t) gid;
+                                                if (missing & SD_BUS_CREDS_EGID)
+                                                        c->egid = (gid_t) egid;
+                                                if (missing & SD_BUS_CREDS_SGID)
+                                                        c->sgid = (gid_t) sgid;
+                                                if (missing & SD_BUS_CREDS_FSGID)
+                                                        c->fsgid = (gid_t) fsgid;
+
                                                 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
                                                 continue;
                                         }
@@ -893,17 +909,22 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
 
         if (missing & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID)) {
 
-                r = cg_pid_get_path(NULL, pid, &c->cgroup);
-                if (r < 0) {
-                        if (r != -EPERM && r != -EACCES)
-                                return r;
-                } else {
+                if (!c->cgroup) {
+                        r = cg_pid_get_path(NULL, pid, &c->cgroup);
+                        if (r < 0) {
+                                if (r != -EPERM && r != -EACCES)
+                                        return r;
+                        }
+                }
+
+                if (!c->cgroup_root) {
                         r = cg_get_root_path(&c->cgroup_root);
                         if (r < 0)
                                 return r;
+                }
 
+                if (c->cgroup)
                         c->mask |= missing & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID);
-                }
         }
 
         if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
@@ -924,6 +945,8 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
                         c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
         }
 
+        c->augmented = missing & c->mask;
+
         return 0;
 }
 
@@ -948,6 +971,16 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
 
         /* Copy the original data over */
 
+        if (c->mask & mask & SD_BUS_CREDS_PID) {
+                n->pid = c->pid;
+                n->mask |= SD_BUS_CREDS_PID;
+        }
+
+        if (c->mask & mask & SD_BUS_CREDS_TID) {
+                n->tid = c->tid;
+                n->mask |= SD_BUS_CREDS_TID;
+        }
+
         if (c->mask & mask & SD_BUS_CREDS_UID) {
                 n->uid = c->uid;
                 n->mask |= SD_BUS_CREDS_UID;
@@ -996,16 +1029,6 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
                 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
         }
 
-        if (c->mask & mask & SD_BUS_CREDS_PID) {
-                n->pid = c->pid;
-                n->mask |= SD_BUS_CREDS_PID;
-        }
-
-        if (c->mask & mask & SD_BUS_CREDS_TID) {
-                n->tid = c->tid;
-                n->mask |= SD_BUS_CREDS_TID;
-        }
-
         if (c->mask & mask & SD_BUS_CREDS_COMM) {
                 n->comm = strdup(c->comm);
                 if (!n->comm)
@@ -1086,6 +1109,8 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
                 n->well_known_names = strv_copy(c->well_known_names);
                 if (!n->well_known_names)
                         return -ENOMEM;
+                n->well_known_names_driver = c->well_known_names_driver;
+                n->well_known_names_local = c->well_known_names_local;
                 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
         }
 
@@ -1096,11 +1121,11 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
                 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;