]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
varlink: optionally create leading dirs when binding AF_UNIX socket
authorLennart Poettering <lennart@poettering.net>
Tue, 4 Mar 2025 14:39:46 +0000 (15:39 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 4 Mar 2025 17:07:17 +0000 (18:07 +0100)
This is such a common case, let's make it easy to do this.

src/home/homed-manager.c
src/libsystemd/sd-varlink/sd-varlink.c
src/machine/machined-varlink.c
src/systemd/sd-varlink.h

index d49693a2e0a6e9a87fe97ec56eda73b7837a3533..0a94128230b288293be8fb48fd27ec5a4f7e3738 100644 (file)
@@ -1036,8 +1036,6 @@ static int manager_bind_varlink(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to register varlink methods: %m");
 
-        (void) mkdir_p("/run/systemd/userdb", 0755);
-
         /* To make things easier to debug, when working from a homed managed home directory, let's optionally
          * use a different varlink socket name */
         suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX");
@@ -1049,7 +1047,7 @@ static int manager_bind_varlink(Manager *m) {
         } else
                 socket_path = "/run/systemd/userdb/io.systemd.Home";
 
-        r = sd_varlink_server_listen_address(m->varlink_server, socket_path, 0666);
+        r = sd_varlink_server_listen_address(m->varlink_server, socket_path, 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755);
         if (r < 0)
                 return log_error_errno(r, "Failed to bind to varlink socket: %m");
 
index cdfcb9935e85411170489027d7d2794b975e9b7e..ebefbe385291ee7a7f570db5946f53c356ce9480 100644 (file)
@@ -17,6 +17,7 @@
 #include "iovec-util.h"
 #include "json-util.h"
 #include "list.h"
+#include "mkdir.h"
 #include "path-util.h"
 #include "process-util.h"
 #include "set.h"
@@ -3643,7 +3644,18 @@ _public_ int sd_varlink_server_listen_address(sd_varlink_server *s, const char *
 
         assert_return(s, -EINVAL);
         assert_return(address, -EINVAL);
-        assert_return((m & ~0777) == 0, -EINVAL);
+        assert_return((m & ~(0777|SD_VARLINK_SERVER_MODE_MKDIR_0755)) == 0, -EINVAL);
+
+        /* Validate that the definition of our flag doesn't collide with the official mode_t bits. Thankfully
+         * the bit values of mode_t flags are fairly well established (POSIX and all), hence we should be
+         * safe here. */
+        assert_cc(((S_IFMT|07777) & SD_VARLINK_SERVER_MODE_MKDIR_0755) == 0);
+
+        if (FLAGS_SET(m, SD_VARLINK_SERVER_MODE_MKDIR_0755) && path_is_absolute(address)) {
+                r = mkdir_parents(address, 0755);
+                if (r < 0)
+                        return r;
+        }
 
         r = sockaddr_un_set_path(&sockaddr.un, address);
         if (r < 0)
index f3548f102101b647d3e4d77b0fa4d650cb7bd8ce..338a47c22c73165bc868bd26a9513de31dc0f8a7 100644 (file)
@@ -743,9 +743,7 @@ static int manager_varlink_init_userdb(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to register varlink methods: %m");
 
-        (void) mkdir_p("/run/systemd/userdb", 0755);
-
-        r = sd_varlink_server_listen_address(s, "/run/systemd/userdb/io.systemd.Machine", 0666);
+        r = sd_varlink_server_listen_address(s, "/run/systemd/userdb/io.systemd.Machine", 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755);
         if (r < 0)
                 return log_error_errno(r, "Failed to bind to varlink socket: %m");
 
@@ -808,9 +806,7 @@ static int manager_varlink_init_machine(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to register varlink methods: %m");
 
-        (void) mkdir_p("/run/systemd/machine", 0755);
-
-        r = sd_varlink_server_listen_address(s, "/run/systemd/machine/io.systemd.Machine", 0666);
+        r = sd_varlink_server_listen_address(s, "/run/systemd/machine/io.systemd.Machine", 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755);
         if (r < 0)
                 return log_error_errno(r, "Failed to bind to io.systemd.Machine varlink socket: %m");
 
index 27e63a7fba10464f66ec1aa3c5137f3559271fa5..623444a8097aa88927777a8d0a80b4ff2c3ade24 100644 (file)
@@ -233,6 +233,10 @@ int sd_varlink_server_set_info(
                 const char *version,
                 const char *url);
 
+/* OR this into sd_varlink_server_listen_address()'s mode paramater to get the leading directories created
+ * automatically with mode 0755. */
+#define SD_VARLINK_SERVER_MODE_MKDIR_0755 ((mode_t) 1 << 30)
+
 /* Add addresses or fds to listen on */
 int sd_varlink_server_listen_address(sd_varlink_server *s, const char *address, mode_t mode);
 int sd_varlink_server_listen_fd(sd_varlink_server *s, int fd);