chiark / gitweb /
bus: move ssh support into public API of libsystem-bus
authorLennart Poettering <lennart@poettering.net>
Wed, 30 Oct 2013 12:52:40 +0000 (13:52 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 30 Oct 2013 14:35:49 +0000 (15:35 +0100)
src/cgroups-agent/cgroups-agent.c
src/fsck/fsck.c
src/initctl/initctl.c
src/libsystemd-bus/bus-internal.c
src/libsystemd-bus/bus-internal.h
src/libsystemd-bus/bus-util.c
src/libsystemd-bus/bus-util.h
src/libsystemd-bus/sd-bus.c
src/machine/machinectl.c
src/systemd/sd-bus.h
src/update-utmp/update-utmp.c

index 256de1f506c814f6354b03e9bcfe602ff76c4648..d8ae55a3130e044d9d6bdb33c301b089e068fe20 100644 (file)
@@ -44,7 +44,7 @@ int main(int argc, char *argv[]) {
          * this to avoid an activation loop when we start dbus when we
          * are called when the dbus service is shut down. */
 
          * this to avoid an activation loop when we start dbus when we
          * are called when the dbus service is shut down. */
 
-        r = bus_connect_system(&bus);
+        r = bus_open_system_systemd(&bus);
         if (r < 0) {
                 log_warning("Failed to get D-Bus connection: %s", strerror(-r));
                 return EXIT_FAILURE;
         if (r < 0) {
                 log_warning("Failed to get D-Bus connection: %s", strerror(-r));
                 return EXIT_FAILURE;
index 5c21c7e41f26c2dbf5f8e1afc002caa01dd31b38..3164d6899c6c6e84888160318206828522c55b31 100644 (file)
@@ -50,7 +50,7 @@ static void start_target(const char *target) {
 
         assert(target);
 
 
         assert(target);
 
-        r = bus_connect_system(&bus);
+        r = bus_open_system_systemd(&bus);
         if (r < 0) {
                 log_error("Failed to get D-Bus connection: %s", strerror(-r));
                 return;
         if (r < 0) {
                 log_error("Failed to get D-Bus connection: %s", strerror(-r));
                 return;
index 3c5986171fe054bba27f57bb41efb4346a9e2ce8..0000d6ccd4fd5039d94dc76ab9025ac7922134a6 100644 (file)
@@ -329,7 +329,7 @@ static int server_init(Server *s, unsigned n_sockets) {
                 s->n_fifos ++;
         }
 
                 s->n_fifos ++;
         }
 
-        r = bus_connect_system(&s->bus);
+        r = bus_open_system_systemd(&s->bus);
         if (r < 0) {
                 log_error("Failed to get D-Bus connection: %s", strerror(-r));
                 r = -EIO;
         if (r < 0) {
                 log_error("Failed to get D-Bus connection: %s", strerror(-r));
                 r = -EIO;
index 942ac2b953be2286d1dbe0dcaf264c4d4895eec6..0bea8cac498918b3e2f959ac07da4e8152c5558c 100644 (file)
@@ -277,3 +277,29 @@ const char *bus_message_type_to_string(uint8_t u) {
         else
                 return NULL;
 }
         else
                 return NULL;
 }
+
+char *bus_address_escape(const char *v) {
+        const char *a;
+        char *r, *b;
+
+        r = new(char, strlen(v)*3+1);
+        if (!r)
+                return NULL;
+
+        for (a = v, b = r; *a; a++) {
+
+                if ((*a >= '0' && *a <= '9') ||
+                    (*a >= 'a' && *a <= 'z') ||
+                    (*a >= 'A' && *a <= 'Z') ||
+                    strchr("_-/.", *a))
+                        *(b++) = *a;
+                else {
+                        *(b++) = '%';
+                        *(b++) = hexchar(*a >> 4);
+                        *(b++) = hexchar(*a & 0xF);
+                }
+        }
+
+        *b = 0;
+        return r;
+}
index 5f8298bbb151e38126b3c534729ad3bbf2adbb13..2ae796191580b97db2fdc0acd24c0d85a157bd02 100644 (file)
@@ -289,6 +289,8 @@ int bus_next_address(sd_bus *bus);
 
 bool bus_pid_changed(sd_bus *bus);
 
 
 bool bus_pid_changed(sd_bus *bus);
 
+char *bus_address_escape(const char *v);
+
 #define OBJECT_PATH_FOREACH_PREFIX(prefix, path)                        \
         for (char *_slash = ({ strcpy((prefix), (path)); streq((prefix), "/") ? NULL : strrchr((prefix), '/'); }) ; \
              _slash && !(_slash[(_slash) == (prefix)] = 0);             \
 #define OBJECT_PATH_FOREACH_PREFIX(prefix, path)                        \
         for (char *_slash = ({ strcpy((prefix), (path)); streq((prefix), "/") ? NULL : strrchr((prefix), '/'); }) ; \
              _slash && !(_slash[(_slash) == (prefix)] = 0);             \
index 6a2fb04a777441cc2e6e5836823751997f5f6b65..53be009be2e6c6e11c67d32b1c70bdef815ede79 100644 (file)
@@ -380,26 +380,22 @@ void bus_verify_polkit_async_registry_free(sd_bus *bus, Hashmap *registry) {
 }
 
 static int bus_check_peercred(sd_bus *c) {
 }
 
 static int bus_check_peercred(sd_bus *c) {
-        int fd;
         struct ucred ucred;
         socklen_t l;
         struct ucred ucred;
         socklen_t l;
+        int fd;
 
         assert(c);
 
         fd = sd_bus_get_fd(c);
 
         assert(c);
 
         fd = sd_bus_get_fd(c);
-
-        assert(fd >= 0);
+        if (fd < 0)
+                return fd;
 
         l = sizeof(struct ucred);
 
         l = sizeof(struct ucred);
-        if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0) {
-                log_error("SO_PEERCRED failed: %m");
+        if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0)
                 return -errno;
                 return -errno;
-        }
 
 
-        if (l != sizeof(struct ucred)) {
-                log_error("SO_PEERCRED returned wrong size.");
+        if (l != sizeof(struct ucred))
                 return -E2BIG;
                 return -E2BIG;
-        }
 
         if (ucred.uid != 0 && ucred.uid != geteuid())
                 return -EPERM;
 
         if (ucred.uid != 0 && ucred.uid != geteuid())
                 return -EPERM;
@@ -407,79 +403,37 @@ static int bus_check_peercred(sd_bus *c) {
         return 1;
 }
 
         return 1;
 }
 
-int bus_connect_system(sd_bus **_bus) {
-        sd_bus *bus = NULL;
+int bus_open_system_systemd(sd_bus **_bus) {
+        _cleanup_bus_unref_ sd_bus *bus = NULL;
         int r;
         int r;
-        bool private = true;
 
         assert(_bus);
 
 
         assert(_bus);
 
-        if (geteuid() == 0) {
-                /* If we are root, then let's talk directly to the
-                 * system instance, instead of going via the bus */
-
-                r = sd_bus_new(&bus);
-                if (r < 0)
-                        return r;
-
-                r = sd_bus_set_address(bus, "unix:path=/run/systemd/private");
-                if (r < 0)
-                        return r;
-
-                r = sd_bus_start(bus);
-                if (r < 0)
-                        return r;
-
-        } else {
-                r = sd_bus_open_system(&bus);
-                if (r < 0)
-                        return r;
-
-                private = false;
-        }
-
-        if (private) {
-                r = bus_check_peercred(bus);
-                if (r < 0) {
-                        sd_bus_unref(bus);
-
-                        return -EACCES;
-                }
-        }
-
-        *_bus = bus;
-        return 0;
-}
-
-int bus_connect_system_ssh(const char *host, sd_bus **_bus) {
-        sd_bus *bus;
-        char *p = NULL;
-        int r;
+        if (geteuid() != 0)
+                return sd_bus_open_system(_bus);
 
 
-        assert(_bus);
-        assert(host);
-
-        asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s,argv3=systemd-stdio-bridge", host);
-        if (!p)
-                return -ENOMEM;
+        /* If we are root, then let's talk directly to the system
+         * instance, instead of going via the bus */
 
 
-       r = sd_bus_new(&bus);
-       if (r < 0)
-               return r;
+        r = sd_bus_new(&bus);
+        if (r < 0)
+                return r;
 
 
-       r = sd_bus_set_address(bus, p);
-       if (r < 0)
-               return r;
+        r = sd_bus_set_address(bus, "unix:path=/run/systemd/private");
+        if (r < 0)
+                return r;
 
 
-       r = sd_bus_set_bus_client(bus, true);
-       if (r < 0)
-               return r;
+        r = sd_bus_start(bus);
+        if (r < 0)
+                return r;
 
 
-       r = sd_bus_start(bus);
+        r = bus_check_peercred(bus);
         if (r < 0)
                 return r;
 
         *_bus = bus;
         if (r < 0)
                 return r;
 
         *_bus = bus;
+        bus = NULL;
+
         return 0;
 }
 
         return 0;
 }
 
index 5ddab2c11bfd384fcb6be8dd50a486dc23e51aeb..46e10b3c1db4cc2932391f00bd9af796c7212392 100644 (file)
@@ -37,8 +37,7 @@ int bus_verify_polkit(sd_bus *bus, sd_bus_message *m, const char *action, bool i
 int bus_verify_polkit_async(sd_bus *bus, Hashmap **registry, sd_bus_message *m, const char *action, bool interactive, sd_bus_error *error, sd_bus_message_handler_t callback, void *userdata);
 void bus_verify_polkit_async_registry_free(sd_bus *bus, Hashmap *registry);
 
 int bus_verify_polkit_async(sd_bus *bus, Hashmap **registry, sd_bus_message *m, const char *action, bool interactive, sd_bus_error *error, sd_bus_message_handler_t callback, void *userdata);
 void bus_verify_polkit_async_registry_free(sd_bus *bus, Hashmap *registry);
 
-int bus_connect_system(sd_bus **_bus);
-int bus_connect_system_ssh(const char *host, sd_bus **_bus);
+int bus_open_system_systemd(sd_bus **_bus);
 
 int bus_generic_print_property(const char *name, sd_bus_message *property, bool all);
 
 
 int bus_generic_print_property(const char *name, sd_bus_message *property, bool all);
 
index 55d964ed8f0269d20ae09fb4f5470e199f4220d5..383b035b7e99cec269c7d02e3294de3f168811eb 100644 (file)
@@ -1033,6 +1033,42 @@ fail:
         return r;
 }
 
         return r;
 }
 
+int sd_bus_open_system_remote(const char *host, sd_bus **ret) {
+        _cleanup_free_ char *e = NULL;
+        char *p = NULL;
+        sd_bus *bus;
+        int r;
+
+        assert_return(host, -EINVAL);
+        assert_return(ret, -EINVAL);
+
+        e = bus_address_escape(host);
+        if (!e)
+                return -ENOMEM;
+
+        p = strjoin("unixexec:path=ssh,argv1=-xT,argv2=", e, ",argv3=systemd-stdio-bridge", NULL);
+        if (!p)
+                return -ENOMEM;
+
+        r = sd_bus_new(&bus);
+        if (r < 0) {
+                free(p);
+                return r;
+        }
+
+        bus->address = p;
+        bus->bus_client = true;
+
+        r = sd_bus_start(bus);
+        if (r < 0) {
+                bus_free(bus);
+                return r;
+        }
+
+        *ret = bus;
+        return 0;
+}
+
 void sd_bus_close(sd_bus *bus) {
         if (!bus)
                 return;
 void sd_bus_close(sd_bus *bus) {
         if (!bus)
                 return;
index 8795565f8e5d6c02a27567217d80c7319c7bdf85..241e360d4924fdc37ff18770bd0a0904884924bc 100644 (file)
@@ -759,7 +759,7 @@ int main(int argc, char*argv[]) {
         if (arg_transport == TRANSPORT_NORMAL)
                 r = sd_bus_open_system(&bus);
         else if (arg_transport == TRANSPORT_SSH)
         if (arg_transport == TRANSPORT_NORMAL)
                 r = sd_bus_open_system(&bus);
         else if (arg_transport == TRANSPORT_SSH)
-                r = bus_connect_system_ssh(arg_host, &bus);
+                r = sd_bus_open_system_remote(arg_host, &bus);
         else
                 assert_not_reached("Uh, invalid transport...");
         if (r < 0) {
         else
                 assert_not_reached("Uh, invalid transport...");
         if (r < 0) {
index aa8caee70fefa76b17b769033b0bdbd238ccd7dd..7b6c86dd39d422430b838d79620b7474f25ec3eb 100644 (file)
@@ -58,8 +58,9 @@ typedef int (*sd_bus_node_enumerator_t) (sd_bus *bus, const char *path, char ***
 
 /* Connections */
 
 
 /* Connections */
 
-int sd_bus_open_system(sd_bus **ret);
 int sd_bus_open_user(sd_bus **ret);
 int sd_bus_open_user(sd_bus **ret);
+int sd_bus_open_system(sd_bus **ret);
+int sd_bus_open_system_remote(const char *host, sd_bus **ret);
 
 int sd_bus_new(sd_bus **ret);
 int sd_bus_set_address(sd_bus *bus, const char *address);
 
 int sd_bus_new(sd_bus **ret);
 int sd_bus_set_address(sd_bus *bus, const char *address);
index f5c143d39d0f0c8813009a14891011a399aee026..61db1e96d34a47b3fd77cd4d580277775c211ef9 100644 (file)
@@ -299,7 +299,7 @@ int main(int argc, char *argv[]) {
             errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
                 log_error("Failed to connect to audit log: %m");
 #endif
             errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
                 log_error("Failed to connect to audit log: %m");
 #endif
-        r = bus_connect_system(&c.bus);
+        r = bus_open_system_systemd(&c.bus);
         if (r < 0) {
                 log_error("Failed to get D-Bus connection: %s", strerror(-r));
                 r = -EIO;
         if (r < 0) {
                 log_error("Failed to get D-Bus connection: %s", strerror(-r));
                 r = -EIO;