chiark / gitweb /
busctl: add command to dump creds of a peer or pid
[elogind.git] / src / libsystemd-bus / bus-util.c
index 2140dbc676888c29f25a88832033bfedcae9d318..bd005262ebc9d0cb082c7f68b6ad58dac445b541 100644 (file)
@@ -20,6 +20,7 @@
 ***/
 
 #include <sys/socket.h>
+#include <sys/capability.h>
 
 #include "util.h"
 #include "strv.h"
@@ -103,6 +104,32 @@ int bus_event_loop_with_idle(sd_event *e, sd_bus *bus, const char *name, usec_t
         return 0;
 }
 
+int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
+        _cleanup_bus_message_unref_ sd_bus_message *rep = NULL;
+        int r, has_owner = 0;
+
+        assert(c);
+        assert(name);
+
+        r = sd_bus_call_method(c,
+                               "org.freedesktop.DBus",
+                               "/org/freedesktop/dbus",
+                               "org.freedesktop.DBus",
+                               "NameHasOwner",
+                               error,
+                               &rep,
+                               "s",
+                               name);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_read_basic(rep, 'b', &has_owner);
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
+
+        return has_owner;
+}
+
 int bus_verify_polkit(
                 sd_bus *bus,
                 sd_bus_message *m,
@@ -111,7 +138,7 @@ int bus_verify_polkit(
                 bool *_challenge,
                 sd_bus_error *e) {
 
-        const char *sender;
+        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
         uid_t uid;
         int r;
 
@@ -119,11 +146,11 @@ int bus_verify_polkit(
         assert(m);
         assert(action);
 
-        sender = sd_bus_message_get_sender(m);
-        if (!sender)
-                return -EBADMSG;
+        r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
+        if (r < 0)
+                return r;
 
-        r = sd_bus_get_owner_uid(bus, sender, &uid);
+        r = sd_bus_creds_get_uid(creds, &uid);
         if (r < 0)
                 return r;
 
@@ -134,6 +161,11 @@ int bus_verify_polkit(
         else {
                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
                 int authorized = false, challenge = false;
+                const char *sender;
+
+                sender = sd_bus_message_get_sender(m);
+                if (!sender)
+                        return -EBADMSG;
 
                 r = sd_bus_call_method(
                                 bus,
@@ -206,7 +238,6 @@ static void async_polkit_query_free(sd_bus *b, AsyncPolkitQuery *q) {
 
 static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
         _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
-        _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
         AsyncPolkitQuery *q = userdata;
         int r;
 
@@ -246,8 +277,9 @@ int bus_verify_polkit_async(
 #ifdef ENABLE_POLKIT
         _cleanup_bus_message_unref_ sd_bus_message *pk = NULL;
         AsyncPolkitQuery *q;
-#endif
         const char *sender;
+#endif
+        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
         uid_t uid;
         int r;
 
@@ -294,17 +326,21 @@ int bus_verify_polkit_async(
         }
 #endif
 
-        sender = sd_bus_message_get_sender(m);
-        if (!sender)
-                return -EBADMSG;
+        r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
+        if (r < 0)
+                return r;
 
-        r = sd_bus_get_owner_uid(bus, sender, &uid);
+        r = sd_bus_creds_get_uid(creds, &uid);
         if (r < 0)
                 return r;
 
         if (uid == 0)
                 return 1;
+
 #ifdef ENABLE_POLKIT
+        sender = sd_bus_message_get_sender(m);
+        if (!sender)
+                return -EBADMSG;
 
         r = hashmap_ensure_allocated(registry, trivial_hash_func, trivial_compare_func);
         if (r < 0)
@@ -441,10 +477,11 @@ int bus_open_user_systemd(sd_bus **_bus) {
         assert(_bus);
 
         e = secure_getenv("XDG_RUNTIME_DIR");
-        if (e) {
-                if (asprintf(&p, "unix:path=%s/systemd/private", e) < 0)
-                        return -ENOMEM;
-        }
+        if (!e)
+                return sd_bus_open_user(_bus);
+
+        if (asprintf(&p, "unix:path=%s/systemd/private", e) < 0)
+                return -ENOMEM;
 
         r = sd_bus_new(&bus);
         if (r < 0)