chiark / gitweb /
bus: process AddMatch/RemoveMatch driver call in proxy
[elogind.git] / src / bus-proxyd / bus-proxyd.c
index d08559891eaf7fb1bafb9869a866d682f54a0d81..5511ee49de805f01531d02ee41f41f0056bc1926 100644 (file)
@@ -172,7 +172,7 @@ static int rename_service(sd_bus *a, sd_bus *b) {
                              uid, name);
 
                 if (m > w)
-                        memset(arg_command_line_buffer + w, 0, m - w);
+                        memzero(arg_command_line_buffer + w, m - w);
         }
 
         log_debug("Running on behalf of PID "PID_FMT" (%s), UID "UID_FMT" (%s), %s",
@@ -216,19 +216,19 @@ static int synthesize_name_acquired(sd_bus *a, sd_bus *b, sd_bus_message *m) {
 
                 r = sd_bus_message_new_signal(
                                 b,
+                                &n,
                                 "/org/freedesktop/DBus",
                                 "org.freedesktop.DBus",
-                                "NameLost",
-                                &n);
+                                "NameLost");
 
         } else if (streq(new_owner, a->unique_name)) {
 
                 r = sd_bus_message_new_signal(
                                 b,
+                                &n,
                                 "/org/freedesktop/DBus",
                                 "org.freedesktop.DBus",
-                                "NameAcquired",
-                                &n);
+                                "NameAcquired");
         } else
                 return 0;
 
@@ -289,6 +289,47 @@ static int process_policy(sd_bus *a, sd_bus *b, sd_bus_message *m) {
         return 1;
 }
 
+static int process_driver(sd_bus *a, sd_bus *b, sd_bus_message *m) {
+        int r;
+
+        assert(a);
+        assert(b);
+        assert(m);
+
+        if (!streq_ptr(sd_bus_message_get_destination(m), "org.freedesktop.DBus"))
+                return 0;
+
+        if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "AddMatch")) {
+                const char *match;
+
+                r = sd_bus_message_read(m, "s", &match);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_add_match(a, match, NULL, NULL);
+                if (r < 0)
+                        return r;
+
+                return sd_bus_reply_method_return(m, NULL);
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "RemoveMatch")) {
+                const char *match;
+
+                r = sd_bus_message_read(m, "s", &match);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_remove_match(a, match, NULL, NULL);
+                if (r < 0)
+                        return r;
+
+                return sd_bus_reply_method_return(m, NULL);
+        } else
+                return 0;
+
+        return r;
+}
+
 static int process_hello(sd_bus *a, sd_bus *b, sd_bus_message *m, bool *got_hello) {
         _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
         bool is_hello;
@@ -359,10 +400,10 @@ static int process_hello(sd_bus *a, sd_bus *b, sd_bus_message *m, bool *got_hell
         n = sd_bus_message_unref(n);
         r = sd_bus_message_new_signal(
                         b,
+                        &n,
                         "/org/freedesktop/DBus",
                         "org.freedesktop.DBus",
-                        "NameAcquired",
-                        &n);
+                        "NameAcquired");
         if (r < 0) {
                 log_error("Failed to allocate initial NameAcquired message: %s", strerror(-r));
                 return r;
@@ -395,6 +436,36 @@ static int process_hello(sd_bus *a, sd_bus *b, sd_bus_message *m, bool *got_hell
         return 1;
 }
 
+static int patch_sender(sd_bus *a, sd_bus_message *m) {
+        char **well_known = NULL;
+        sd_bus_creds *c;
+        int r;
+
+        assert(a);
+        assert(m);
+
+        if (!a->is_kernel)
+                return 0;
+
+        /* We will change the sender of messages from the bus driver
+         * so that they originate from the bus driver. This is a
+         * speciality originating from dbus1, where the bus driver did
+         * not have a unique id, but only the well-known name. */
+
+        c = sd_bus_message_get_creds(m);
+        if (!c)
+                return 0;
+
+        r = sd_bus_creds_get_well_known_names(c, &well_known);
+        if (r < 0)
+                return r;
+
+        if (strv_contains(well_known, "org.freedesktop.DBus"))
+                m->sender = "org.freedesktop.DBus";
+
+        return 0;
+}
+
 int main(int argc, char *argv[]) {
 
         _cleanup_bus_unref_ sd_bus *a = NULL, *b = NULL;
@@ -440,6 +511,12 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
+        r = sd_bus_set_name(a, "sd-proxy");
+        if (r < 0) {
+                log_error("Failed to set bus name: %s", strerror(-r));
+                goto finish;
+        }
+
         r = sd_bus_set_address(a, arg_address);
         if (r < 0) {
                 log_error("Failed to set address to connect to: %s", strerror(-r));
@@ -606,6 +683,8 @@ int main(int argc, char *argv[]) {
                                         goto finish;
                                 }
 
+                                patch_sender(a, m);
+
                                 k = sd_bus_send(b, m, NULL);
                                 if (k < 0) {
                                         if (k == -ECONNRESET)
@@ -658,17 +737,28 @@ int main(int argc, char *argv[]) {
                                         goto finish;
                                 }
 
-                                k = sd_bus_send(a, m, NULL);
+                                k = process_driver(a, b, m);
                                 if (k < 0) {
-                                        if (r == -ECONNRESET)
-                                                r = 0;
-                                        else {
-                                                r = k;
-                                                log_error("Failed to send message: %s", strerror(-r));
-                                        }
-
+                                        r = k;
+                                        log_error("Failed to process driver calls: %s", strerror(-r));
                                         goto finish;
                                 }
+
+                                if (k > 0)
+                                        r = k;
+                                else {
+                                        k = sd_bus_send(a, m, NULL);
+                                        if (k < 0) {
+                                                if (r == -ECONNRESET)
+                                                        r = 0;
+                                                else {
+                                                        r = k;
+                                                        log_error("Failed to send message: %s", strerror(-r));
+                                                }
+
+                                                goto finish;
+                                        }
+                                }
                         }
                 }
 
@@ -736,8 +826,6 @@ int main(int argc, char *argv[]) {
                 }
         }
 
-        r = 0;
-
 finish:
         sd_bus_flush(a);
         sd_bus_flush(b);