diff options
Diffstat (limited to 'src/libsystemd/sd-bus/sd-bus.c')
-rw-r--r-- | src/libsystemd/sd-bus/sd-bus.c | 102 |
1 files changed, 67 insertions, 35 deletions
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 8befc97..1a642cb 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -30,6 +30,7 @@ #include "constants.h" #include "errno-util.h" #include "fd-util.h" +#include "format-util.h" #include "glyph-util.h" #include "hexdecoct.h" #include "hostname-util.h" @@ -151,6 +152,14 @@ void bus_close_inotify_fd(sd_bus *b) { b->n_inotify_watches = 0; } +static void bus_close_fds(sd_bus *b) { + assert(b); + + bus_close_io_fds(b); + bus_close_inotify_fd(b); + b->pidfd = safe_close(b->pidfd); +} + static void bus_reset_queues(sd_bus *b) { assert(b); @@ -191,8 +200,7 @@ static sd_bus* bus_free(sd_bus *b) { if (b->default_bus_ptr) *b->default_bus_ptr = NULL; - bus_close_io_fds(b); - bus_close_inotify_fd(b); + bus_close_fds(b); free(b->label); free(b->groups); @@ -256,7 +264,10 @@ _public_ int sd_bus_new(sd_bus **ret) { .n_groups = SIZE_MAX, .close_on_exit = true, .ucred = UCRED_INVALID, + .pidfd = -EBADF, .runtime_scope = _RUNTIME_SCOPE_INVALID, + .connect_as_uid = UID_INVALID, + .connect_as_gid = GID_INVALID, }; /* We guarantee that wqueue always has space for at least one entry */ @@ -321,7 +332,7 @@ _public_ int sd_bus_set_bus_client(sd_bus *bus, int b) { assert_return(!bus->patch_sender, -EPERM); assert_return(!bus_origin_changed(bus), -ECHILD); - bus->bus_client = !!b; + bus->bus_client = b; return 0; } @@ -331,7 +342,7 @@ _public_ int sd_bus_set_monitor(sd_bus *bus, int b) { assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_origin_changed(bus), -ECHILD); - bus->is_monitor = !!b; + bus->is_monitor = b; return 0; } @@ -341,7 +352,7 @@ _public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) { assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_origin_changed(bus), -ECHILD); - bus->accept_fd = !!b; + bus->accept_fd = b; return 0; } @@ -353,7 +364,7 @@ _public_ int sd_bus_negotiate_timestamp(sd_bus *bus, int b) { /* This is not actually supported by any of our transports these days, but we do honour it for synthetic * replies, and maybe one day classic D-Bus learns this too */ - bus->attach_timestamp = !!b; + bus->attach_timestamp = b; return 0; } @@ -380,7 +391,7 @@ _public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) { assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_origin_changed(bus), -ECHILD); - bus->is_server = !!b; + bus->is_server = b; bus->server_id = server_id; return 0; } @@ -391,7 +402,7 @@ _public_ int sd_bus_set_anonymous(sd_bus *bus, int b) { assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_origin_changed(bus), -ECHILD); - bus->anonymous_auth = !!b; + bus->anonymous_auth = b; return 0; } @@ -401,7 +412,7 @@ _public_ int sd_bus_set_trusted(sd_bus *bus, int b) { assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_origin_changed(bus), -ECHILD); - bus->trusted = !!b; + bus->trusted = b; return 0; } @@ -419,7 +430,7 @@ _public_ int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b) { assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_origin_changed(bus), -ECHILD); - bus->allow_interactive_authorization = !!b; + bus->allow_interactive_authorization = b; return 0; } @@ -437,7 +448,7 @@ _public_ int sd_bus_set_watch_bind(sd_bus *bus, int b) { assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_origin_changed(bus), -ECHILD); - bus->watch_bind = !!b; + bus->watch_bind = b; return 0; } @@ -455,7 +466,7 @@ _public_ int sd_bus_set_connected_signal(sd_bus *bus, int b) { assert_return(bus->state == BUS_UNSET, -EPERM); assert_return(!bus_origin_changed(bus), -ECHILD); - bus->connected_signal = !!b; + bus->connected_signal = b; return 0; } @@ -640,7 +651,7 @@ int bus_start_running(sd_bus *bus) { static int parse_address_key(const char **p, const char *key, char **value) { _cleanup_free_ char *r = NULL; - size_t l, n = 0; + size_t n = 0; const char *a; assert(p); @@ -648,17 +659,14 @@ static int parse_address_key(const char **p, const char *key, char **value) { assert(value); if (key) { - l = strlen(key); - if (strncmp(*p, key, l) != 0) - return 0; - - if ((*p)[l] != '=') + a = startswith(*p, key); + if (!a || *a != '=') return 0; if (*value) return -EINVAL; - a = *p + l + 1; + a++; } else a = *p; @@ -717,7 +725,7 @@ static void skip_address_key(const char **p) { } static int parse_unix_address(sd_bus *b, const char **p, char **guid) { - _cleanup_free_ char *path = NULL, *abstract = NULL; + _cleanup_free_ char *path = NULL, *abstract = NULL, *uids = NULL, *gids = NULL; size_t l; int r; @@ -745,6 +753,18 @@ static int parse_unix_address(sd_bus *b, const char **p, char **guid) { else if (r > 0) continue; + r = parse_address_key(p, "uid", &uids); + if (r < 0) + return r; + else if (r > 0) + continue; + + r = parse_address_key(p, "gid", &gids); + if (r < 0) + return r; + else if (r > 0) + continue; + skip_address_key(p); } @@ -781,6 +801,17 @@ static int parse_unix_address(sd_bus *b, const char **p, char **guid) { b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + 1 + l; } + if (uids) { + r = parse_uid(uids, &b->connect_as_uid); + if (r < 0) + return r; + } + if (gids) { + r = parse_gid(gids, &b->connect_as_gid); + if (r < 0) + return r; + } + b->is_local = true; return 0; @@ -1102,8 +1133,7 @@ static int bus_start_address(sd_bus *b) { assert(b); for (;;) { - bus_close_io_fds(b); - bus_close_inotify_fd(b); + bus_close_fds(b); bus_kill_exec(b); @@ -1486,9 +1516,15 @@ interpret_port_as_machine_old_syntax: return -ENOMEM; } - a = strjoin("unixexec:path=ssh,argv1=-xT", p ? ",argv2=-p,argv3=" : "", strempty(p), - ",argv", p ? "4" : "2", "=--,argv", p ? "5" : "3", "=", e, - ",argv", p ? "6" : "4", "=systemd-stdio-bridge", c); + const char *ssh = secure_getenv("SYSTEMD_SSH") ?: "ssh"; + _cleanup_free_ char *ssh_escaped = bus_address_escape(ssh); + if (!ssh_escaped) + return -ENOMEM; + + a = strjoin("unixexec:path=", ssh_escaped, ",argv1=-xT", + p ? ",argv2=-p,argv3=" : "", strempty(p), + ",argv", p ? "4" : "2", "=--,argv", p ? "5" : "3", "=", e, + ",argv", p ? "6" : "4", "=systemd-stdio-bridge", c); if (!a) return -ENOMEM; @@ -1668,10 +1704,7 @@ static int user_and_machine_equivalent(const char *user_and_machine) { return true; /* Otherwise, we have to figure out our user id and name, and compare things with that. */ - char buf[DECIMAL_STR_MAX(uid_t)]; - xsprintf(buf, UID_FMT, uid); - - f = startswith(user_and_machine, buf); + f = startswith(user_and_machine, FORMAT_UID(uid)); if (!f) { un = getusername_malloc(); if (!un) @@ -1775,8 +1808,7 @@ _public_ void sd_bus_close(sd_bus *bus) { * the bus object and the bus may be freed */ bus_reset_queues(bus); - bus_close_io_fds(bus); - bus_close_inotify_fd(bus); + bus_close_fds(bus); } _public_ sd_bus *sd_bus_close_unref(sd_bus *bus) { @@ -4123,13 +4155,13 @@ _public_ int sd_bus_path_decode_many(const char *path, const char *path_template for (template_pos = path_template; *template_pos; ) { const char *sep; - size_t length; + size_t length, path_length; char *label; /* verify everything until the next '%' matches verbatim */ sep = strchrnul(template_pos, '%'); length = sep - template_pos; - if (strncmp(path_pos, template_pos, length)) + if (!strneq(path_pos, template_pos, length)) return 0; path_pos += length; @@ -4150,8 +4182,8 @@ _public_ int sd_bus_path_decode_many(const char *path, const char *path_template /* verify the suffixes match */ sep = strchrnul(path_pos, '/'); - if (sep - path_pos < (ssize_t)length || - strncmp(sep - length, template_pos, length)) + path_length = sep - path_pos; + if (length > path_length || !strneq(sep - length, template_pos, length)) return 0; template_pos += length; /* skip over matched label */ |