summaryrefslogtreecommitdiffstats
path: root/src/libsystemd/sd-bus/sd-bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd/sd-bus/sd-bus.c')
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c102
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 */