X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Fbus-util.c;h=c7e51a11b2ae5b3ddea0f71fb8ff337f4b687916;hp=dc8727c8fbe704725e03b77d7dc79357e9f8e555;hb=da4b83e77bc603745cf4a365d7f013301ef7fa89;hpb=3b22396a4b2767a98172f6915929c47738cb0a1e diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index dc8727c8f..c7e51a11b 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -19,26 +19,40 @@ along with systemd; If not, see . ***/ -// #include +#include -// #include "sd-daemon.h" -// #include "sd-event.h" -// #include "util.h" -#include "strv.h" -// #include "macro.h" -// #include "def.h" -// #include "path-util.h" -// #include "missing.h" -// #include "set.h" -// #include "signal-util.h" -#include "unit-name.h" +#include "sd-bus.h" +#include "sd-daemon.h" +#include "sd-event.h" -// #include "sd-bus.h" -// #include "bus-error.h" -// #include "bus-label.h" +#include "alloc-util.h" +#include "bus-error.h" +#include "bus-internal.h" +#include "bus-label.h" #include "bus-message.h" #include "bus-util.h" -#include "bus-internal.h" +#include "cgroup-util.h" +#include "def.h" +//#include "env-util.h" +#include "escape.h" +#include "fd-util.h" +#include "macro.h" +#include "missing.h" +#include "parse-util.h" +#include "path-util.h" +#include "proc-cmdline.h" +#include "process-util.h" +//#include "rlimit-util.h" +#include "set.h" +#include "signal-util.h" +#include "stdio-util.h" +#include "string-util.h" +#include "strv.h" +#include "syslog-util.h" +#include "unit-name.h" +#include "user-util.h" +#include "utf8.h" +#include "util.h" /// UNNEEDED by elogind #if 0 @@ -577,14 +591,14 @@ int bus_check_peercred(sd_bus *c) { return 1; } -int bus_open_system_systemd(sd_bus **_bus) { +int bus_connect_system_systemd(sd_bus **_bus) { _cleanup_bus_unref_ sd_bus *bus = NULL; int r; assert(_bus); if (geteuid() != 0) - return sd_bus_open_system(_bus); + 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 @@ -619,7 +633,7 @@ int bus_open_system_systemd(sd_bus **_bus) { r = sd_bus_start(bus); if (r < 0) - return sd_bus_open_system(_bus); + return sd_bus_default_system(_bus); r = bus_check_peercred(bus); if (r < 0) @@ -631,7 +645,7 @@ int bus_open_system_systemd(sd_bus **_bus) { return 0; } -int bus_open_user_systemd(sd_bus **_bus) { +int bus_connect_user_systemd(sd_bus **_bus) { _cleanup_bus_unref_ sd_bus *bus = NULL; _cleanup_free_ char *ee = NULL; const char *e; @@ -661,7 +675,7 @@ int bus_open_user_systemd(sd_bus **_bus) { e = secure_getenv("XDG_RUNTIME_DIR"); if (!e) - return sd_bus_open_user(_bus); + return sd_bus_default_user(_bus); ee = bus_address_escape(e); if (!ee) @@ -677,7 +691,7 @@ int bus_open_user_systemd(sd_bus **_bus) { r = sd_bus_start(bus); if (r < 0) - return sd_bus_open_user(_bus); + return sd_bus_default_user(_bus); r = bus_check_peercred(bus); if (r < 0) @@ -1216,7 +1230,7 @@ int bus_map_all_properties( return bus_message_map_all_properties(m, map, userdata); } -int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) { +int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) { int r; assert(transport >= 0); @@ -1256,7 +1270,7 @@ int bus_open_transport(BusTransport transport, const char *host, bool user, sd_b /// UNNEEDED by elogind #if 0 -int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) { +int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) { int r; assert(transport >= 0); @@ -1270,9 +1284,9 @@ int bus_open_transport_systemd(BusTransport transport, const char *host, bool us case BUS_TRANSPORT_LOCAL: if (user) - r = bus_open_user_systemd(bus); + r = bus_connect_user_systemd(bus); else - r = bus_open_system_systemd(bus); + r = bus_connect_system_systemd(bus); break; @@ -1431,6 +1445,17 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen return bus_log_create_error(r); return 0; + } else if (streq(field, "EnvironmentFile")) { + r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "EnvironmentFiles"); + if (r < 0) + return r; + + r = sd_bus_message_append(m, "v", "a(sb)", 1, + eq[0] == '-' ? eq + 1 : eq, + eq[0] == '-'); + if (r < 0) + return r; + return 0; } r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field); @@ -1438,9 +1463,11 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen return bus_log_create_error(r); if (STR_IN_SET(field, - "CPUAccounting", "MemoryAccounting", "BlockIOAccounting", + "CPUAccounting", "MemoryAccounting", "BlockIOAccounting", "TasksAccounting", "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies", - "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit")) { + "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit", + "PrivateTmp", "PrivateDevices", "PrivateNetwork", "NoNewPrivileges", + "SyslogLevelPrefix", "Delegate")) { r = parse_boolean(eq); if (r < 0) { @@ -1451,20 +1478,50 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen r = sd_bus_message_append(m, "v", "b", r); } else if (streq(field, "MemoryLimit")) { - off_t bytes; + uint64_t bytes; + if (isempty(eq) || streq(eq, "infinity")) + bytes = (uint64_t) -1; + else { r = parse_size(eq, 1024, &bytes); if (r < 0) { log_error("Failed to parse bytes specification %s", assignment); return -EINVAL; } + } + + r = sd_bus_message_append(m, "v", "t", bytes); - r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes); + } else if (streq(field, "TasksMax")) { + uint64_t n; - } else if (STR_IN_SET(field, "CPUShares", "BlockIOWeight")) { + if (isempty(eq) || streq(eq, "infinity")) + n = (uint64_t) -1; + else { + r = safe_atou64(eq, &n); + if (r < 0) { + log_error("Failed to parse maximum tasks specification %s", assignment); + return -EINVAL; + } + } + + r = sd_bus_message_append(m, "v", "t", n); + + } else if (STR_IN_SET(field, "CPUShares", "StartupCPUShares")) { uint64_t u; - r = safe_atou64(eq, &u); + r = cg_cpu_shares_parse(eq, &u); + if (r < 0) { + log_error("Failed to parse %s value %s.", field, eq); + return -EINVAL; + } + + r = sd_bus_message_append(m, "v", "t", u); + + } else if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight")) { + uint64_t u; + + r = cg_cpu_shares_parse(eq, &u); if (r < 0) { log_error("Failed to parse %s value %s.", field, eq); return -EINVAL; @@ -1476,10 +1533,34 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen "User", "Group", "DevicePolicy", "KillMode", "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath", "StandardInput", "StandardOutput", "StandardError", - "Description", "Slice", "Type")) + "Description", "Slice", "Type", "WorkingDirectory", + "RootDirectory", "SyslogIdentifier", "ProtectSystem", + "ProtectHome")) r = sd_bus_message_append(m, "v", "s", eq); - else if (streq(field, "DeviceAllow")) { + else if (streq(field, "SyslogLevel")) { + int level; + + level = log_level_from_string(eq); + if (level < 0) { + log_error("Failed to parse %s value %s.", field, eq); + return -EINVAL; + } + + r = sd_bus_message_append(m, "v", "i", level); + + } else if (streq(field, "SyslogFacility")) { + int facility; + + facility = log_facility_unshifted_from_string(eq); + if (facility < 0) { + log_error("Failed to parse %s value %s.", field, eq); + return -EINVAL; + } + + r = sd_bus_message_append(m, "v", "i", facility); + + } else if (streq(field, "DeviceAllow")) { if (isempty(eq)) r = sd_bus_message_append(m, "v", "a(ss)", 0); @@ -1509,7 +1590,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen r = sd_bus_message_append(m, "v", "a(st)", 0); else { const char *path, *bandwidth, *e; - off_t bytes; + uint64_t bytes; e = strchr(eq, ' '); if (e) { @@ -1531,7 +1612,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen return -EINVAL; } - r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes); + r = sd_bus_message_append(m, "v", "a(st)", 1, path, bytes); } } else if (streq(field, "BlockIODeviceWeight")) { @@ -1590,9 +1671,52 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen r = sd_bus_message_append(m, "v", "i", i); - } else if (streq(field, "Environment")) { + } else if (STR_IN_SET(field, "Environment", "PassEnvironment")) { + const char *p; + + r = sd_bus_message_open_container(m, 'v', "as"); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_open_container(m, 'a', "s"); + if (r < 0) + return bus_log_create_error(r); + + p = eq; + + for (;;) { + _cleanup_free_ char *word = NULL; + + r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE); + if (r < 0) { + log_error("Failed to parse Environment value %s", eq); + return -EINVAL; + } + if (r == 0) + break; + + if (streq(field, "Environment")) { + if (!env_assignment_is_valid(word)) { + log_error("Invalid environment assignment: %s", word); + return -EINVAL; + } + } else { /* PassEnvironment */ + if (!env_name_is_valid(word)) { + log_error("Invalid environment variable name: %s", word); + return -EINVAL; + } + } + + r = sd_bus_message_append_basic(m, 's', word); + if (r < 0) + return bus_log_create_error(r); + } + + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); - r = sd_bus_message_append(m, "v", "as", 1, eq); + r = sd_bus_message_close_container(m); } else if (streq(field, "KillSignal")) { int sig; @@ -1615,6 +1739,113 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen } r = sd_bus_message_append(m, "v", "t", u); + } else if (streq(field, "TimerSlackNSec")) { + nsec_t n; + + r = parse_nsec(eq, &n); + if (r < 0) { + log_error("Failed to parse %s value %s", field, eq); + return -EINVAL; + } + + r = sd_bus_message_append(m, "v", "t", n); + } else if (streq(field, "OOMScoreAdjust")) { + int oa; + + r = safe_atoi(eq, &oa); + if (r < 0) { + log_error("Failed to parse %s value %s", field, eq); + return -EINVAL; + } + + if (!oom_score_adjust_is_valid(oa)) { + log_error("OOM score adjust value out of range"); + return -EINVAL; + } + + r = sd_bus_message_append(m, "v", "i", oa); + } else if (STR_IN_SET(field, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories")) { + const char *p; + + r = sd_bus_message_open_container(m, 'v', "as"); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_open_container(m, 'a', "s"); + if (r < 0) + return bus_log_create_error(r); + + p = eq; + + for (;;) { + _cleanup_free_ char *word = NULL; + int offset; + + r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); + if (r < 0) { + log_error("Failed to parse %s value %s", field, eq); + return -EINVAL; + } + if (r == 0) + break; + + if (!utf8_is_valid(word)) { + log_error("Failed to parse %s value %s", field, eq); + return -EINVAL; + } + + offset = word[0] == '-'; + if (!path_is_absolute(word + offset)) { + log_error("Failed to parse %s value %s", field, eq); + return -EINVAL; + } + + path_kill_slashes(word + offset); + + r = sd_bus_message_append_basic(m, 's', word); + if (r < 0) + return bus_log_create_error(r); + } + + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_close_container(m); + + } else if (streq(field, "RuntimeDirectory")) { + const char *p; + + r = sd_bus_message_open_container(m, 'v', "as"); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_open_container(m, 'a', "s"); + if (r < 0) + return bus_log_create_error(r); + + p = eq; + + for (;;) { + _cleanup_free_ char *word = NULL; + + r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); + if (r < 0) + return log_error_errno(r, "Failed to parse %s value %s", field, eq); + + if (r == 0) + break; + + r = sd_bus_message_append_basic(m, 's', word); + if (r < 0) + return bus_log_create_error(r); + } + + r = sd_bus_message_close_container(m); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_close_container(m); } else { log_error("Unknown assignment %s.", assignment); @@ -1905,7 +2136,6 @@ int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet) { } d->name = mfree(d->name); - d->result = mfree(d->result); } @@ -2125,3 +2355,45 @@ bool is_kdbus_available(void) { return ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0; } + +/// UNNEEDED by elogind +#if 0 +int bus_property_get_rlimit( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + struct rlimit *rl; + uint64_t u; + rlim_t x; + + assert(bus); + assert(reply); + assert(userdata); + + rl = *(struct rlimit**) userdata; + if (rl) + x = rl->rlim_max; + else { + struct rlimit buf = {}; + int z; + + z = rlimit_from_string(strstr(property, "Limit")); + assert(z >= 0); + + getrlimit(z, &buf); + x = buf.rlim_max; + } + + /* rlim_t might have different sizes, let's map + * RLIMIT_INFINITY to (uint64_t) -1, so that it is the same on + * all archs */ + u = x == RLIM_INFINITY ? (uint64_t) -1 : (uint64_t) x; + + return sd_bus_message_append(reply, "t", u); +} +#endif // 0