From: Lennart Poettering Date: Tue, 4 Mar 2025 14:39:46 +0000 (+0100) Subject: varlink: optionally create leading dirs when binding AF_UNIX socket X-Git-Tag: v258-rc1~1190 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=837849561b8c453f1ff8126d63788c00af8dba47;p=thirdparty%2Fsystemd.git varlink: optionally create leading dirs when binding AF_UNIX socket This is such a common case, let's make it easy to do this. --- diff --git a/src/home/homed-manager.c b/src/home/homed-manager.c index d49693a2e0a..0a94128230b 100644 --- a/src/home/homed-manager.c +++ b/src/home/homed-manager.c @@ -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"); diff --git a/src/libsystemd/sd-varlink/sd-varlink.c b/src/libsystemd/sd-varlink/sd-varlink.c index cdfcb9935e8..ebefbe38529 100644 --- a/src/libsystemd/sd-varlink/sd-varlink.c +++ b/src/libsystemd/sd-varlink/sd-varlink.c @@ -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) diff --git a/src/machine/machined-varlink.c b/src/machine/machined-varlink.c index f3548f10210..338a47c22c7 100644 --- a/src/machine/machined-varlink.c +++ b/src/machine/machined-varlink.c @@ -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"); diff --git a/src/systemd/sd-varlink.h b/src/systemd/sd-varlink.h index 27e63a7fba1..623444a8097 100644 --- a/src/systemd/sd-varlink.h +++ b/src/systemd/sd-varlink.h @@ -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);