chiark / gitweb /
sd-bus: update to current kernel version, by splitting off the extended KDBUS_ITEM_PI...
[elogind.git] / src / libsystemd / sd-bus / bus-convenience.c
index 8081a2f..ae0f4fa 100644 (file)
@@ -476,6 +476,7 @@ _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_b
 _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability) {
         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
         uid_t our_uid;
+        bool know_caps = false;
         int r;
 
         assert_return(call, -EINVAL);
@@ -486,21 +487,21 @@ _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability)
         if (!BUS_IS_OPEN(call->bus->state))
                 return -ENOTCONN;
 
-        /* We only trust the effective capability set if this is
-         * kdbus. On classic dbus1 we cannot retrieve the value
-         * without races. Since this function is supposed to be useful
-         * for authentication decision we hence avoid requesting and
-         * using that information. */
-        if (call->bus->is_kernel && capability >= 0) {
-                r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds);
+        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;
 
+                /* Note that not even on kdbus we might have the caps
+                 * field, due to faked identities, or namespace
+                 * translation issues. */
                 r = sd_bus_creds_has_effective_cap(creds, capability);
                 if (r > 0)
                         return 1;
+                if (r == 0)
+                        know_caps = true;
         } else {
-                r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID, &creds);
+                r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID, &creds);
                 if (r < 0)
                         return r;
         }
@@ -508,10 +509,14 @@ _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability)
         /* Now, check the UID, but only if the capability check wasn't
          * sufficient */
         our_uid = getuid();
-        if (our_uid != 0 || !call->bus->is_kernel || capability < 0) {
+        if (our_uid != 0 || !know_caps || capability < 0) {
                 uid_t sender_uid;
 
-                r = sd_bus_creds_get_uid(creds, &sender_uid);
+                /* Try to use the EUID, if we have it. */
+                r = sd_bus_creds_get_euid(creds, &sender_uid);
+                if (r < 0)
+                        r = sd_bus_creds_get_uid(creds, &sender_uid);
+
                 if (r >= 0) {
                         /* Sender has same UID as us, then let's grant access */
                         if (sender_uid == our_uid)