X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fsystemd.git;a=blobdiff_plain;f=src%2Fshared%2Fbus-util.c;h=c6844f5ec2c1833a7c82be6d97e9d5889c185811;hp=8cfa9363474e4d3bff0eb273794879a905191abb;hb=53e1b683907c2f12330f00feb9630150196f064d;hpb=d643a60a9e0be4bea0495f4f1a3792eb2300e48d diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 8cfa9363474..c6844f5ec2c 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ /*** This file is part of systemd. @@ -39,10 +40,14 @@ #include "bus-label.h" #include "bus-message.h" #include "bus-util.h" +#include "cap-list.h" +#include "cgroup-util.h" #include "def.h" #include "escape.h" #include "fd-util.h" #include "missing.h" +#include "mount-util.h" +#include "nsflags.h" #include "parse-util.h" #include "proc-cmdline.h" #include "rlimit-util.h" @@ -251,7 +256,7 @@ int bus_test_polkit( return r; else if (r > 0) return 1; -#ifdef ENABLE_POLKIT +#if ENABLE_POLKIT else { _cleanup_(sd_bus_message_unrefp) sd_bus_message *request = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; @@ -330,7 +335,7 @@ int bus_test_polkit( return -EACCES; } -#ifdef ENABLE_POLKIT +#if ENABLE_POLKIT typedef struct AsyncPolkitQuery { sd_bus_message *request, *reply; @@ -394,7 +399,7 @@ int bus_verify_polkit_async( Hashmap **registry, sd_bus_error *error) { -#ifdef ENABLE_POLKIT +#if ENABLE_POLKIT _cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL; AsyncPolkitQuery *q; const char *sender, **k, **v; @@ -412,7 +417,7 @@ int bus_verify_polkit_async( if (r != 0) return r; -#ifdef ENABLE_POLKIT +#if ENABLE_POLKIT q = hashmap_get(*registry, call); if (q) { int authorized, challenge; @@ -459,7 +464,7 @@ int bus_verify_polkit_async( else if (r > 0) return 1; -#ifdef ENABLE_POLKIT +#if ENABLE_POLKIT if (sd_bus_get_current_message(call->bus) != call) return -EINVAL; @@ -548,7 +553,7 @@ int bus_verify_polkit_async( } void bus_verify_polkit_async_registry_free(Hashmap *registry) { -#ifdef ENABLE_POLKIT +#if ENABLE_POLKIT AsyncPolkitQuery *q; while ((q = hashmap_steal_first(registry))) @@ -591,28 +596,8 @@ int bus_connect_system_systemd(sd_bus **_bus) { if (geteuid() != 0) return sd_bus_default_system(_bus); - /* If we are root and kdbus is not available, 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, KERNEL_SYSTEM_BUS_ADDRESS); - if (r < 0) - return r; - - bus->bus_client = true; - - r = sd_bus_start(bus); - if (r >= 0) { - *_bus = bus; - bus = NULL; - return 0; - } - - bus = sd_bus_unref(bus); + /* 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) @@ -642,28 +627,8 @@ int bus_connect_user_systemd(sd_bus **_bus) { const char *e; int r; - /* Try via kdbus first, and then directly */ - assert(_bus); - r = sd_bus_new(&bus); - if (r < 0) - return r; - - if (asprintf(&bus->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid()) < 0) - return -ENOMEM; - - bus->bus_client = true; - - r = sd_bus_start(bus); - if (r >= 0) { - *_bus = bus; - bus = NULL; - return 0; - } - - bus = sd_bus_unref(bus); - e = secure_getenv("XDG_RUNTIME_DIR"); if (!e) return sd_bus_default_user(_bus); @@ -676,7 +641,7 @@ int bus_connect_user_systemd(sd_bus **_bus) { if (r < 0) return r; - bus->address = strjoin("unix:path=", ee, "/systemd/private", NULL); + bus->address = strjoin("unix:path=", ee, "/systemd/private"); if (!bus->address) return -ENOMEM; @@ -724,13 +689,12 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b return r; if (all || !isempty(s)) { - _cleanup_free_ char *escaped = NULL; - - escaped = xescape(s, "\n"); - if (!escaped) - return -ENOMEM; + bool good; - print_property(name, "%s", escaped); + /* This property has a single value, so we need to take + * care not to print a new line, everything else is OK. */ + good = !strchr(s, '\n'); + print_property(name, "%s", good ? s : "[unprintable]"); } return 1; @@ -769,7 +733,57 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b char timespan[FORMAT_TIMESPAN_MAX]; print_property(name, "%s", format_timespan(timespan, sizeof(timespan), u, 0)); - } else + } else if (streq(name, "RestrictNamespaces")) { + _cleanup_free_ char *s = NULL; + const char *result; + + if ((u & NAMESPACE_FLAGS_ALL) == 0) + result = "yes"; + else if ((u & NAMESPACE_FLAGS_ALL) == NAMESPACE_FLAGS_ALL) + result = "no"; + else { + r = namespace_flag_to_string_many(u, &s); + if (r < 0) + return r; + + result = s; + } + + print_property(name, "%s", result); + + } else if (streq(name, "MountFlags")) { + const char *result; + + result = mount_propagation_flags_to_string(u); + if (!result) + return -EINVAL; + + print_property(name, "%s", result); + + } else if (STR_IN_SET(name, "CapabilityBoundingSet", "AmbientCapabilities")) { + _cleanup_free_ char *s = NULL; + + r = capability_set_to_string_alloc(u, &s); + if (r < 0) + return r; + + print_property(name, "%s", s); + + } else if ((STR_IN_SET(name, "CPUWeight", "StartupCPUWeight", "IOWeight", "StartupIOWeight") && u == CGROUP_WEIGHT_INVALID) || + (STR_IN_SET(name, "CPUShares", "StartupCPUShares") && u == CGROUP_CPU_SHARES_INVALID) || + (STR_IN_SET(name, "BlockIOWeight", "StartupBlockIOWeight") && u == CGROUP_BLKIO_WEIGHT_INVALID) || + (STR_IN_SET(name, "MemoryCurrent", "TasksCurrent") && u == (uint64_t) -1) || + (endswith(name, "NSec") && u == (uint64_t) -1)) + + print_property(name, "%s", "[not set]"); + + else if ((STR_IN_SET(name, "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit") && u == CGROUP_LIMIT_MAX) || + (STR_IN_SET(name, "TasksMax", "DefaultTasksMax") && u == (uint64_t) -1) || + (startswith(name, "Limit") && u == (uint64_t) -1) || + (startswith(name, "DefaultLimit") && u == (uint64_t) -1)) + + print_property(name, "%s", "infinity"); + else print_property(name, "%"PRIu64, u); return 1; @@ -796,7 +810,17 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b if (strstr(name, "UMask") || strstr(name, "Mode")) print_property(name, "%04o", u); - else + else if (streq(name, "UID")) { + if (u == UID_INVALID) + print_property(name, "%s", "[not set]"); + else + print_property(name, "%"PRIu32, u); + } else if (streq(name, "GID")) { + if (u == GID_INVALID) + print_property(name, "%s", "[not set]"); + else + print_property(name, "%"PRIu32, u); + } else print_property(name, "%"PRIu32, u); return 1; @@ -834,16 +858,16 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b return r; while ((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) { - _cleanup_free_ char *escaped = NULL; + bool good; if (first && !value) printf("%s=", name); - escaped = xescape(str, "\n "); - if (!escaped) - return -ENOMEM; + /* This property has multiple space-separated values, so + * neither spaces not newlines can be allowed in a value. */ + good = str[strcspn(str, " \n")] == '\0'; - printf("%s%s", first ? "" : " ", escaped); + printf("%s%s", first ? "" : " ", good ? str : "[unprintable]"); first = false; } @@ -1016,19 +1040,19 @@ static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_ return r; switch (type) { + case SD_BUS_TYPE_STRING: { - const char *s; char **p = userdata; + const char *s; r = sd_bus_message_read_basic(m, type, &s); if (r < 0) - break; + return r; if (isempty(s)) - break; + s = NULL; - r = free_and_strdup(p, s); - break; + return free_and_strdup(p, s); } case SD_BUS_TYPE_ARRAY: { @@ -1037,80 +1061,70 @@ static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_ r = bus_message_read_strv_extend(m, &l); if (r < 0) - break; + return r; strv_free(*p); *p = l; l = NULL; - - break; + return 0; } case SD_BUS_TYPE_BOOLEAN: { unsigned b; - bool *p = userdata; + int *p = userdata; r = sd_bus_message_read_basic(m, type, &b); if (r < 0) - break; + return r; *p = b; - - break; + return 0; } + case SD_BUS_TYPE_INT32: case SD_BUS_TYPE_UINT32: { - uint32_t u; - uint32_t *p = userdata; + uint32_t u, *p = userdata; r = sd_bus_message_read_basic(m, type, &u); if (r < 0) - break; + return r; *p = u; - - break; + return 0; } + case SD_BUS_TYPE_INT64: case SD_BUS_TYPE_UINT64: { - uint64_t t; - uint64_t *p = userdata; + uint64_t t, *p = userdata; r = sd_bus_message_read_basic(m, type, &t); if (r < 0) - break; + return r; *p = t; - - break; + return 0; } case SD_BUS_TYPE_DOUBLE: { - double d; - double *p = userdata; + double d, *p = userdata; r = sd_bus_message_read_basic(m, type, &d); if (r < 0) - break; + return r; *p = d; + return 0; + }} - break; - } - - default: - break; - } - - return r; + return -EOPNOTSUPP; } int bus_message_map_all_properties( sd_bus_message *m, const struct bus_properties_map *map, + sd_bus_error *error, void *userdata) { - _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r; assert(m); @@ -1148,9 +1162,9 @@ int bus_message_map_all_properties( v = (uint8_t *)userdata + prop->offset; if (map[i].set) - r = prop->set(sd_bus_message_get_bus(m), member, m, &error, v); + r = prop->set(sd_bus_message_get_bus(m), member, m, error, v); else - r = map_basic(sd_bus_message_get_bus(m), member, m, &error, v); + r = map_basic(sd_bus_message_get_bus(m), member, m, error, v); if (r < 0) return r; @@ -1176,6 +1190,7 @@ int bus_message_map_all_properties( int bus_message_map_properties_changed( sd_bus_message *m, const struct bus_properties_map *map, + sd_bus_error *error, void *userdata) { const char *member; @@ -1184,7 +1199,7 @@ int bus_message_map_properties_changed( assert(m); assert(map); - r = bus_message_map_all_properties(m, map, userdata); + r = bus_message_map_all_properties(m, map, error, userdata); if (r < 0) return r; @@ -1214,10 +1229,10 @@ int bus_map_all_properties( const char *destination, const char *path, const struct bus_properties_map *map, + sd_bus_error *error, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; - _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r; assert(bus); @@ -1231,21 +1246,22 @@ int bus_map_all_properties( path, "org.freedesktop.DBus.Properties", "GetAll", - &error, + error, &m, "s", ""); if (r < 0) return r; - return bus_message_map_all_properties(m, map, userdata); + return bus_message_map_all_properties(m, map, error, userdata); } -int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) { +int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **ret) { + _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; int r; assert(transport >= 0); assert(transport < _BUS_TRANSPORT_MAX); - assert(bus); + assert(ret); assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL); assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP); @@ -1254,25 +1270,34 @@ int bus_connect_transport(BusTransport transport, const char *host, bool user, s case BUS_TRANSPORT_LOCAL: if (user) - r = sd_bus_default_user(bus); + r = sd_bus_default_user(&bus); else - r = sd_bus_default_system(bus); + r = sd_bus_default_system(&bus); break; case BUS_TRANSPORT_REMOTE: - r = sd_bus_open_system_remote(bus, host); + r = sd_bus_open_system_remote(&bus, host); break; case BUS_TRANSPORT_MACHINE: - r = sd_bus_open_system_machine(bus, host); + r = sd_bus_open_system_machine(&bus, host); break; default: assert_not_reached("Hmm, unknown transport type."); } + if (r < 0) + return r; - return r; + r = sd_bus_set_exit_on_disconnect(bus, true); + if (r < 0) + return r; + + *ret = bus; + bus = NULL; + + return 0; } int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) { @@ -1324,6 +1349,23 @@ int bus_property_get_bool( return sd_bus_message_append_basic(reply, 'b', &b); } +int bus_property_get_id128( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + sd_id128_t *id = userdata; + + if (sd_id128_is_null(*id)) /* Add an empty array if the ID is zero */ + return sd_bus_message_append(reply, "ay", 0); + else + return sd_bus_message_append_array(reply, 'y', id->bytes, 16); +} + #if __SIZEOF_SIZE_T__ != 8 int bus_property_get_size( sd_bus *bus, @@ -1443,7 +1485,7 @@ int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, if (!external_label) return -ENOMEM; - p = strjoin(prefix, "/", sender_label, "/", external_label, NULL); + p = strjoin(prefix, "/", sender_label, "/", external_label); if (!p) return -ENOMEM; @@ -1505,40 +1547,6 @@ int bus_path_decode_unique(const char *path, const char *prefix, char **ret_send return 1; } -bool is_kdbus_wanted(void) { - _cleanup_free_ char *value = NULL; -#ifdef ENABLE_KDBUS - const bool configured = true; -#else - const bool configured = false; -#endif - - int r; - - if (get_proc_cmdline_key("kdbus", NULL) > 0) - return true; - - r = get_proc_cmdline_key("kdbus=", &value); - if (r <= 0) - return configured; - - return parse_boolean(value) == 1; -} - -bool is_kdbus_available(void) { - _cleanup_close_ int fd = -1; - struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE }; - - if (!is_kdbus_wanted()) - return false; - - fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY); - if (fd < 0) - return false; - - return ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0; -} - int bus_property_get_rlimit( sd_bus *bus, const char *path, @@ -1582,3 +1590,22 @@ int bus_property_get_rlimit( return sd_bus_message_append(reply, "t", u); } + +int bus_track_add_name_many(sd_bus_track *t, char **l) { + int r = 0; + char **i; + + assert(t); + + /* Continues adding after failure, and returns the first failure. */ + + STRV_FOREACH(i, l) { + int k; + + k = sd_bus_track_add_name(t, *i); + if (k < 0 && r >= 0) + r = k; + } + + return r; +}