diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analyze/analyze.c | 49 | ||||
-rw-r--r-- | src/basic/util.h | 1 | ||||
-rw-r--r-- | src/core/dbus-unit.c | 70 | ||||
-rw-r--r-- | src/core/dbus.c | 13 | ||||
-rw-r--r-- | src/core/dbus.h | 1 | ||||
-rw-r--r-- | src/hostname/hostnamed.c | 3 | ||||
-rw-r--r-- | src/import/importd.c | 6 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-objects.c | 22 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/sd-bus.c | 10 | ||||
-rw-r--r-- | src/libsystemd/sd-event/sd-event.c | 2 | ||||
-rw-r--r-- | src/locale/localed.c | 3 | ||||
-rw-r--r-- | src/login/logind-dbus.c | 20 | ||||
-rw-r--r-- | src/login/logind-seat-dbus.c | 1 | ||||
-rw-r--r-- | src/login/logind-session-dbus.c | 3 | ||||
-rw-r--r-- | src/login/logind-user-dbus.c | 2 | ||||
-rw-r--r-- | src/machine/image-dbus.c | 5 | ||||
-rw-r--r-- | src/machine/machine-dbus.c | 7 | ||||
-rw-r--r-- | src/machine/machined-dbus.c | 1 | ||||
-rw-r--r-- | src/shared/bus-util.c | 72 | ||||
-rw-r--r-- | src/shared/bus-util.h | 4 | ||||
-rw-r--r-- | src/timedate/timedated.c | 4 |
21 files changed, 250 insertions, 49 deletions
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index db1e7f3f37..ab7fb53269 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -1092,12 +1092,59 @@ static int graph_one(sd_bus *bus, const UnitInfo *u, char *patterns[]) { return 0; } +static int expand_patterns(sd_bus *bus, char **patterns, char ***ret) { + _cleanup_strv_free_ char **expanded_patterns = NULL; + char **pattern; + int r; + + STRV_FOREACH(pattern, patterns) { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_free_ char *unit = NULL, *unit_id = NULL; + + if (strv_extend(&expanded_patterns, *pattern) < 0) + return log_oom(); + + if (string_is_glob(*pattern)) + continue; + + unit = unit_dbus_path_from_name(*pattern); + if (!unit) + return log_oom(); + + r = sd_bus_get_property_string( + bus, + "org.freedesktop.systemd1", + unit, + "org.freedesktop.systemd1.Unit", + "Id", + &error, + &unit_id); + if (r < 0) + return log_error_errno(r, "Failed to get ID: %s", bus_error_message(&error, r)); + + if (!streq(*pattern, unit_id)) { + if (strv_extend(&expanded_patterns, unit_id) < 0) + return log_oom(); + } + } + + *ret = expanded_patterns; + expanded_patterns = NULL; /* do not free */ + + return 0; +} + static int dot(sd_bus *bus, char* patterns[]) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_strv_free_ char **expanded_patterns = NULL; int r; UnitInfo u; + r = expand_patterns(bus, patterns, &expanded_patterns); + if (r < 0) + return r; + r = sd_bus_call_method( bus, "org.freedesktop.systemd1", @@ -1120,7 +1167,7 @@ static int dot(sd_bus *bus, char* patterns[]) { while ((r = bus_parse_unit_info(reply, &u)) > 0) { - r = graph_one(bus, &u, patterns); + r = graph_one(bus, &u, expanded_patterns); if (r < 0) return r; } diff --git a/src/basic/util.h b/src/basic/util.h index f8e32360f0..0fafebd52d 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -567,6 +567,7 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, void *arg); #define _(String) gettext (String) +#define N_(String) String void init_gettext(void); bool is_locale_utf8(void); diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 31016b6c4a..f9275ed935 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -391,6 +391,29 @@ static int property_get_load_error( return sd_bus_message_append(reply, "(ss)", e.name, e.message); } +static int bus_verify_manage_units_async_full( + Unit *u, + const char *verb, + int capability, + const char *polkit_message, + sd_bus_message *call, + sd_bus_error *error) { + + const char *details[9] = { + "unit", u->id, + "verb", verb, + }; + + if (polkit_message) { + details[4] = "polkit.message"; + details[5] = polkit_message; + details[6] = "polkit.gettext_domain"; + details[7] = GETTEXT_PACKAGE; + } + + return bus_verify_polkit_async(call, capability, "org.freedesktop.systemd1.manage-units", details, false, UID_INVALID, &u->manager->polkit_registry, error); +} + int bus_unit_method_start_generic( sd_bus_message *message, Unit *u, @@ -400,6 +423,14 @@ int bus_unit_method_start_generic( const char *smode; JobMode mode; + _cleanup_free_ char *verb = NULL; + static const char *const polkit_message_for_job[_JOB_TYPE_MAX] = { + [JOB_START] = N_("Authentication is required to start '$(unit)'."), + [JOB_STOP] = N_("Authentication is required to stop '$(unit)'."), + [JOB_RELOAD] = N_("Authentication is required to reload '$(unit)'."), + [JOB_RESTART] = N_("Authentication is required to restart '$(unit)'."), + [JOB_TRY_RESTART] = N_("Authentication is required to restart '$(unit)'."), + }; int r; assert(message); @@ -418,7 +449,20 @@ int bus_unit_method_start_generic( if (mode < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s invalid", smode); - r = bus_verify_manage_units_async(u->manager, message, error); + if (reload_if_possible) + verb = strjoin("reload-or-", job_type_to_string(job_type), NULL); + else + verb = strdup(job_type_to_string(job_type)); + if (!verb) + return -ENOMEM; + + r = bus_verify_manage_units_async_full( + u, + verb, + CAP_SYS_ADMIN, + job_type < _JOB_TYPE_MAX ? polkit_message_for_job[job_type] : NULL, + message, + error); if (r < 0) return r; if (r == 0) @@ -484,7 +528,13 @@ int bus_unit_method_kill(sd_bus_message *message, void *userdata, sd_bus_error * if (signo <= 0 || signo >= _NSIG) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal number out of range."); - r = bus_verify_manage_units_async_for_kill(u->manager, message, error); + r = bus_verify_manage_units_async_full( + u, + "kill", + CAP_KILL, + N_("Authentication is required to kill '$(unit)'."), + message, + error); if (r < 0) return r; if (r == 0) @@ -508,7 +558,13 @@ int bus_unit_method_reset_failed(sd_bus_message *message, void *userdata, sd_bus if (r < 0) return r; - r = bus_verify_manage_units_async(u->manager, message, error); + r = bus_verify_manage_units_async_full( + u, + "reset-failed", + CAP_SYS_ADMIN, + N_("Authentication is required to reset the \"failed\" state of '$(unit)'."), + message, + error); if (r < 0) return r; if (r == 0) @@ -534,7 +590,13 @@ int bus_unit_method_set_properties(sd_bus_message *message, void *userdata, sd_b if (r < 0) return r; - r = bus_verify_manage_units_async(u->manager, message, error); + r = bus_verify_manage_units_async_full( + u, + "set-property", + CAP_SYS_ADMIN, + N_("Authentication is required to set properties on '$(unit)'."), + message, + error); if (r < 0) return r; if (r == 0) diff --git a/src/core/dbus.c b/src/core/dbus.c index 7ad16aa42b..0a2180c6a7 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -1198,22 +1198,17 @@ int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l) { } int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error *error) { - return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-units", false, UID_INVALID, &m->polkit_registry, error); -} - -/* Same as bus_verify_manage_unit_async(), but checks for CAP_KILL instead of CAP_SYS_ADMIN */ -int bus_verify_manage_units_async_for_kill(Manager *m, sd_bus_message *call, sd_bus_error *error) { - return bus_verify_polkit_async(call, CAP_KILL, "org.freedesktop.systemd1.manage-units", false, UID_INVALID, &m->polkit_registry, error); + return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-units", NULL, false, UID_INVALID, &m->polkit_registry, error); } int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error) { - return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-unit-files", false, UID_INVALID, &m->polkit_registry, error); + return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-unit-files", NULL, false, UID_INVALID, &m->polkit_registry, error); } int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error) { - return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.reload-daemon", false, UID_INVALID, &m->polkit_registry, error); + return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.reload-daemon", NULL, false, UID_INVALID, &m->polkit_registry, error); } int bus_verify_set_environment_async(Manager *m, sd_bus_message *call, sd_bus_error *error) { - return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.set-environment", false, UID_INVALID, &m->polkit_registry, error); + return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.set-environment", NULL, false, UID_INVALID, &m->polkit_registry, error); } diff --git a/src/core/dbus.h b/src/core/dbus.h index 4832722069..4f06ad11c4 100644 --- a/src/core/dbus.h +++ b/src/core/dbus.h @@ -37,7 +37,6 @@ int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l); int bus_foreach_bus(Manager *m, sd_bus_track *subscribed2, int (*send_message)(sd_bus *bus, void *userdata), void *userdata); int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error *error); -int bus_verify_manage_units_async_for_kill(Manager *m, sd_bus_message *call, sd_bus_error *error); int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error); int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error); int bus_verify_set_environment_async(Manager *m, sd_bus_message *call, sd_bus_error *error); diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index a78516c8b5..c423be3767 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -434,6 +434,7 @@ static int method_set_hostname(sd_bus_message *m, void *userdata, sd_bus_error * m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-hostname", + NULL, interactive, UID_INVALID, &c->polkit_registry, @@ -486,6 +487,7 @@ static int method_set_static_hostname(sd_bus_message *m, void *userdata, sd_bus_ m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-static-hostname", + NULL, interactive, UID_INVALID, &c->polkit_registry, @@ -557,6 +559,7 @@ static int set_machine_info(Context *c, sd_bus_message *m, int prop, sd_bus_mess m, CAP_SYS_ADMIN, prop == PROP_PRETTY_HOSTNAME ? "org.freedesktop.hostname1.set-static-hostname" : "org.freedesktop.hostname1.set-machine-info", + NULL, interactive, UID_INVALID, &c->polkit_registry, diff --git a/src/import/importd.c b/src/import/importd.c index 8b508eaeec..ffff94ee72 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -735,6 +735,7 @@ static int method_import_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_ msg, CAP_SYS_ADMIN, "org.freedesktop.import1.import", + NULL, false, UID_INVALID, &m->polkit_registry, @@ -799,6 +800,7 @@ static int method_export_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_ msg, CAP_SYS_ADMIN, "org.freedesktop.import1.export", + NULL, false, UID_INVALID, &m->polkit_registry, @@ -864,6 +866,7 @@ static int method_pull_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_er msg, CAP_SYS_ADMIN, "org.freedesktop.import1.pull", + NULL, false, UID_INVALID, &m->polkit_registry, @@ -945,6 +948,7 @@ static int method_pull_dkr(sd_bus_message *msg, void *userdata, sd_bus_error *er msg, CAP_SYS_ADMIN, "org.freedesktop.import1.pull", + NULL, false, UID_INVALID, &m->polkit_registry, @@ -1079,6 +1083,7 @@ static int method_cancel(sd_bus_message *msg, void *userdata, sd_bus_error *erro msg, CAP_SYS_ADMIN, "org.freedesktop.import1.pull", + NULL, false, UID_INVALID, &t->manager->polkit_registry, @@ -1108,6 +1113,7 @@ static int method_cancel_transfer(sd_bus_message *msg, void *userdata, sd_bus_er msg, CAP_SYS_ADMIN, "org.freedesktop.import1.pull", + NULL, false, UID_INVALID, &m->polkit_registry, diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c index 0593aa658a..1d061cb9cf 100644 --- a/src/libsystemd/sd-bus/bus-objects.c +++ b/src/libsystemd/sd-bus/bus-objects.c @@ -169,11 +169,18 @@ static int add_enumerated_to_set( return 0; } +enum { + /* if set, add_subtree() works recursively */ + CHILDREN_RECURSIVE = (1U << 1), + /* if set, add_subtree() scans object-manager hierarchies recursively */ + CHILDREN_SUBHIERARCHIES = (1U << 0), +}; + static int add_subtree_to_set( sd_bus *bus, const char *prefix, struct node *n, - bool skip_subhierarchies, + unsigned int flags, Set *s, sd_bus_error *error) { @@ -205,8 +212,9 @@ static int add_subtree_to_set( if (r < 0 && r != -EEXIST) return r; - if (!skip_subhierarchies || !i->object_managers) { - r = add_subtree_to_set(bus, prefix, i, skip_subhierarchies, s, error); + if ((flags & CHILDREN_RECURSIVE) && + ((flags & CHILDREN_SUBHIERARCHIES) || !i->object_managers)) { + r = add_subtree_to_set(bus, prefix, i, flags, s, error); if (r < 0) return r; if (bus->nodes_modified) @@ -221,7 +229,7 @@ static int get_child_nodes( sd_bus *bus, const char *prefix, struct node *n, - bool skip_subhierarchies, + unsigned int flags, Set **_s, sd_bus_error *error) { @@ -237,7 +245,7 @@ static int get_child_nodes( if (!s) return -ENOMEM; - r = add_subtree_to_set(bus, prefix, n, skip_subhierarchies, s, error); + r = add_subtree_to_set(bus, prefix, n, flags, s, error); if (r < 0) { set_free_free(s); return r; @@ -907,7 +915,7 @@ static int process_introspect( assert(n); assert(found_object); - r = get_child_nodes(bus, m->path, n, false, &s, &error); + r = get_child_nodes(bus, m->path, n, 0, &s, &error); if (r < 0) return bus_maybe_reply_error(m, r, &error); if (bus->nodes_modified) @@ -1173,7 +1181,7 @@ static int process_get_managed_objects( if (require_fallback || !n->object_managers) return 0; - r = get_child_nodes(bus, m->path, n, true, &s, &error); + r = get_child_nodes(bus, m->path, n, CHILDREN_RECURSIVE, &s, &error); if (r < 0) return r; if (bus->nodes_modified) diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 4ed508427e..4a9181613a 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -1241,6 +1241,8 @@ fail: int bus_set_address_user(sd_bus *b) { const char *e; + uid_t uid; + int r; assert(b); @@ -1248,6 +1250,10 @@ int bus_set_address_user(sd_bus *b) { if (e) return sd_bus_set_address(b, e); + r = cg_pid_get_owner_uid(0, &uid); + if (r < 0) + uid = getuid(); + e = secure_getenv("XDG_RUNTIME_DIR"); if (e) { _cleanup_free_ char *ee = NULL; @@ -1256,9 +1262,9 @@ int bus_set_address_user(sd_bus *b) { if (!ee) return -ENOMEM; - (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT, getuid(), ee); + (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT, uid, ee); } else - (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid()); + (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT, uid); if (!b->address) return -ENOMEM; diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index 838ee4d454..62b63ec3d9 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -1708,7 +1708,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { s->enabled = m; - r = event_make_signal_data(s->event, s->signal.sig, SIGCHLD); + r = event_make_signal_data(s->event, s->signal.sig, NULL); if (r < 0) { s->enabled = SD_EVENT_OFF; s->event->n_enabled_child_sources--; diff --git a/src/locale/localed.c b/src/locale/localed.c index 4fa84df8c0..e304588c58 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -960,6 +960,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-locale", + NULL, interactive, UID_INVALID, &c->polkit_registry, @@ -1049,6 +1050,7 @@ static int method_set_vc_keyboard(sd_bus_message *m, void *userdata, sd_bus_erro m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", + NULL, interactive, UID_INVALID, &c->polkit_registry, @@ -1180,6 +1182,7 @@ static int method_set_x11_keyboard(sd_bus_message *m, void *userdata, sd_bus_err m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", + NULL, interactive, UID_INVALID, &c->polkit_registry, diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index e433549cb9..14b6e0ddad 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -942,6 +942,7 @@ static int method_lock_sessions(sd_bus_message *message, void *userdata, sd_bus_ message, CAP_SYS_ADMIN, "org.freedesktop.login1.lock-sessions", + NULL, false, UID_INVALID, &m->polkit_registry, @@ -1096,6 +1097,7 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu message, CAP_SYS_ADMIN, "org.freedesktop.login1.set-user-linger", + NULL, interactive, UID_INVALID, &m->polkit_registry, @@ -1268,6 +1270,7 @@ static int method_attach_device(sd_bus_message *message, void *userdata, sd_bus_ message, CAP_SYS_ADMIN, "org.freedesktop.login1.attach-device", + NULL, interactive, UID_INVALID, &m->polkit_registry, @@ -1299,6 +1302,7 @@ static int method_flush_devices(sd_bus_message *message, void *userdata, sd_bus_ message, CAP_SYS_ADMIN, "org.freedesktop.login1.flush-devices", + NULL, interactive, UID_INVALID, &m->polkit_registry, @@ -1649,7 +1653,7 @@ static int verify_shutdown_creds( blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL); if (multiple_sessions && action_multiple_sessions) { - r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, UID_INVALID, &m->polkit_registry, error); + r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -1657,7 +1661,7 @@ static int verify_shutdown_creds( } if (blocked && action_ignore_inhibit) { - r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, UID_INVALID, &m->polkit_registry, error); + r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -1665,7 +1669,7 @@ static int verify_shutdown_creds( } if (!multiple_sessions && !blocked && action) { - r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, UID_INVALID, &m->polkit_registry, error); + r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, NULL, interactive, UID_INVALID, &m->polkit_registry, error); if (r < 0) return r; if (r == 0) @@ -2085,7 +2089,7 @@ static int method_can_shutdown_or_sleep( blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL); if (multiple_sessions) { - r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, UID_INVALID, &challenge, error); + r = bus_test_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, UID_INVALID, &challenge, error); if (r < 0) return r; @@ -2098,7 +2102,7 @@ static int method_can_shutdown_or_sleep( } if (blocked) { - r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, UID_INVALID, &challenge, error); + r = bus_test_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, UID_INVALID, &challenge, error); if (r < 0) return r; @@ -2114,7 +2118,7 @@ static int method_can_shutdown_or_sleep( /* If neither inhibit nor multiple sessions * apply then just check the normal policy */ - r = bus_test_polkit(message, CAP_SYS_BOOT, action, UID_INVALID, &challenge, error); + r = bus_test_polkit(message, CAP_SYS_BOOT, action, NULL, UID_INVALID, &challenge, error); if (r < 0) return r; @@ -2233,6 +2237,7 @@ static int method_set_reboot_to_firmware_setup( r = bus_verify_polkit_async(message, CAP_SYS_ADMIN, "org.freedesktop.login1.set-reboot-to-firmware-setup", + NULL, false, UID_INVALID, &m->polkit_registry, @@ -2271,6 +2276,7 @@ static int method_can_reboot_to_firmware_setup( r = bus_test_polkit(message, CAP_SYS_ADMIN, "org.freedesktop.login1.set-reboot-to-firmware-setup", + NULL, UID_INVALID, &challenge, error); @@ -2307,6 +2313,7 @@ static int method_set_wall_message( r = bus_verify_polkit_async(message, CAP_SYS_ADMIN, "org.freedesktop.login1.set-wall-message", + NULL, false, UID_INVALID, &m->polkit_registry, @@ -2378,6 +2385,7 @@ static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" : w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" : "org.freedesktop.login1.inhibit-handle-lid-switch", + NULL, false, UID_INVALID, &m->polkit_registry, diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c index ce67ffde37..346e1d2cec 100644 --- a/src/login/logind-seat-dbus.c +++ b/src/login/logind-seat-dbus.c @@ -204,6 +204,7 @@ int bus_seat_method_terminate(sd_bus_message *message, void *userdata, sd_bus_er message, CAP_KILL, "org.freedesktop.login1.manage", + NULL, false, UID_INVALID, &s->manager->polkit_registry, diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index 563153e2d9..e6b4ccd7c6 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -191,6 +191,7 @@ int bus_session_method_terminate(sd_bus_message *message, void *userdata, sd_bus message, CAP_KILL, "org.freedesktop.login1.manage", + NULL, false, s->user->uid, &s->manager->polkit_registry, @@ -232,6 +233,7 @@ int bus_session_method_lock(sd_bus_message *message, void *userdata, sd_bus_erro message, CAP_SYS_ADMIN, "org.freedesktop.login1.lock-sessions", + NULL, false, s->user->uid, &s->manager->polkit_registry, @@ -306,6 +308,7 @@ int bus_session_method_kill(sd_bus_message *message, void *userdata, sd_bus_erro message, CAP_KILL, "org.freedesktop.login1.manage", + NULL, false, s->user->uid, &s->manager->polkit_registry, diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c index 36c0e8626d..20ea2fbdc4 100644 --- a/src/login/logind-user-dbus.c +++ b/src/login/logind-user-dbus.c @@ -179,6 +179,7 @@ int bus_user_method_terminate(sd_bus_message *message, void *userdata, sd_bus_er message, CAP_KILL, "org.freedesktop.login1.manage", + NULL, false, u->uid, &u->manager->polkit_registry, @@ -207,6 +208,7 @@ int bus_user_method_kill(sd_bus_message *message, void *userdata, sd_bus_error * message, CAP_KILL, "org.freedesktop.login1.manage", + NULL, false, u->uid, &u->manager->polkit_registry, diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c index 95d7bca4bf..2453a9ff04 100644 --- a/src/machine/image-dbus.c +++ b/src/machine/image-dbus.c @@ -43,6 +43,7 @@ int bus_image_method_remove( message, CAP_SYS_ADMIN, "org.freedesktop.machine1.manage-images", + NULL, false, UID_INVALID, &m->polkit_registry, @@ -83,6 +84,7 @@ int bus_image_method_rename( message, CAP_SYS_ADMIN, "org.freedesktop.machine1.manage-images", + NULL, false, UID_INVALID, &m->polkit_registry, @@ -123,6 +125,7 @@ int bus_image_method_clone( message, CAP_SYS_ADMIN, "org.freedesktop.machine1.manage-images", + NULL, false, UID_INVALID, &m->polkit_registry, @@ -158,6 +161,7 @@ int bus_image_method_mark_read_only( message, CAP_SYS_ADMIN, "org.freedesktop.machine1.manage-images", + NULL, false, UID_INVALID, &m->polkit_registry, @@ -194,6 +198,7 @@ int bus_image_method_set_limit( message, CAP_SYS_ADMIN, "org.freedesktop.machine1.manage-images", + NULL, false, UID_INVALID, &m->polkit_registry, diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index a63b9785af..fbeace0ed6 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -124,6 +124,7 @@ int bus_machine_method_terminate(sd_bus_message *message, void *userdata, sd_bus message, CAP_KILL, "org.freedesktop.machine1.manage-machines", + NULL, false, UID_INVALID, &m->manager->polkit_registry, @@ -169,6 +170,7 @@ int bus_machine_method_kill(sd_bus_message *message, void *userdata, sd_bus_erro message, CAP_KILL, "org.freedesktop.machine1.manage-machines", + NULL, false, UID_INVALID, &m->manager->polkit_registry, @@ -488,6 +490,7 @@ int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_ message, CAP_SYS_ADMIN, m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-open-pty" : "org.freedesktop.machine1.open-pty", + NULL, false, UID_INVALID, &m->manager->polkit_registry, @@ -577,6 +580,7 @@ int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bu message, CAP_SYS_ADMIN, m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-login" : "org.freedesktop.machine1.login", + NULL, false, UID_INVALID, &m->manager->polkit_registry, @@ -675,6 +679,7 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu message, CAP_SYS_ADMIN, m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-shell" : "org.freedesktop.machine1.shell", + NULL, false, UID_INVALID, &m->manager->polkit_registry, @@ -883,6 +888,7 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu message, CAP_SYS_ADMIN, "org.freedesktop.machine1.manage-machines", + NULL, false, UID_INVALID, &m->manager->polkit_registry, @@ -1145,6 +1151,7 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro message, CAP_SYS_ADMIN, "org.freedesktop.machine1.manage-machines", + NULL, false, UID_INVALID, &m->manager->polkit_registry, diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 0d52c693e4..eef9c5fa5f 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -810,6 +810,7 @@ static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus message, CAP_SYS_ADMIN, "org.freedesktop.machine1.manage-machines", + NULL, false, UID_INVALID, &m->polkit_registry, diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 1369a61458..d9cc19700e 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -220,6 +220,7 @@ int bus_test_polkit( sd_bus_message *call, int capability, const char *action, + const char **details, uid_t good_user, bool *_challenge, sd_bus_error *e) { @@ -242,29 +243,52 @@ int bus_test_polkit( return 1; #ifdef ENABLE_POLKIT else { + _cleanup_bus_message_unref_ sd_bus_message *request = NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; int authorized = false, challenge = false; - const char *sender; + const char *sender, **k, **v; sender = sd_bus_message_get_sender(call); if (!sender) return -EBADMSG; - r = sd_bus_call_method( + r = sd_bus_message_new_method_call( call->bus, + &request, "org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority", "org.freedesktop.PolicyKit1.Authority", - "CheckAuthorization", - e, - &reply, - "(sa{sv})sa{ss}us", + "CheckAuthorization"); + if (r < 0) + return r; + + r = sd_bus_message_append( + request, + "(sa{sv})s", "system-bus-name", 1, "name", "s", sender, - action, - 0, - 0, - ""); + action); + if (r < 0) + return r; + + r = sd_bus_message_open_container(request, 'a', "{ss}"); + if (r < 0) + return r; + STRV_FOREACH_PAIR(k, v, details) { + r = sd_bus_message_append(request, "{ss}", *k, *v); + if (r < 0) + return r; + } + + r = sd_bus_message_close_container(request); + if (r < 0) + return r; + + r = sd_bus_message_append(request, "us", 0, NULL); + if (r < 0) + return r; + + r = sd_bus_call(call->bus, request, 0, e, &reply); if (r < 0) { /* Treat no PK available as access denied */ if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) { @@ -354,6 +378,7 @@ int bus_verify_polkit_async( sd_bus_message *call, int capability, const char *action, + const char **details, bool interactive, uid_t good_user, Hashmap **registry, @@ -362,7 +387,7 @@ int bus_verify_polkit_async( #ifdef ENABLE_POLKIT _cleanup_bus_message_unref_ sd_bus_message *pk = NULL; AsyncPolkitQuery *q; - const char *sender; + const char *sender, **k, **v; sd_bus_message_handler_t callback; void *userdata; int c; @@ -460,12 +485,27 @@ int bus_verify_polkit_async( r = sd_bus_message_append( pk, - "(sa{sv})sa{ss}us", + "(sa{sv})s", "system-bus-name", 1, "name", "s", sender, - action, - 0, - !!interactive, - NULL); + action); + if (r < 0) + return r; + + r = sd_bus_message_open_container(pk, 'a', "{ss}"); + if (r < 0) + return r; + + STRV_FOREACH_PAIR(k, v, details) { + r = sd_bus_message_append(pk, "{ss}", *k, *v); + if (r < 0) + return r; + } + + r = sd_bus_message_close_container(pk); + if (r < 0) + return r; + + r = sd_bus_message_append(pk, "us", !!interactive, NULL); if (r < 0) return r; diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h index 4ae216b7d9..d2b2d701ce 100644 --- a/src/shared/bus-util.h +++ b/src/shared/bus-util.h @@ -60,9 +60,9 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error); int bus_check_peercred(sd_bus *c); -int bus_test_polkit(sd_bus_message *call, int capability, const char *action, uid_t good_user, bool *_challenge, sd_bus_error *e); +int bus_test_polkit(sd_bus_message *call, int capability, const char *action, const char **details, uid_t good_user, bool *_challenge, sd_bus_error *e); -int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *action, bool interactive, uid_t good_user, Hashmap **registry, sd_bus_error *error); +int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *action, const char **details, bool interactive, uid_t good_user, Hashmap **registry, sd_bus_error *error); void bus_verify_polkit_async_registry_free(Hashmap *registry); int bus_open_system_systemd(sd_bus **_bus); diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index 42ae70fd1d..6de9e246f6 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -361,6 +361,7 @@ static int method_set_timezone(sd_bus_message *m, void *userdata, sd_bus_error * m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-timezone", + NULL, interactive, UID_INVALID, &c->polkit_registry, @@ -428,6 +429,7 @@ static int method_set_local_rtc(sd_bus_message *m, void *userdata, sd_bus_error m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-local-rtc", + NULL, interactive, UID_INVALID, &c->polkit_registry, @@ -543,6 +545,7 @@ static int method_set_time(sd_bus_message *m, void *userdata, sd_bus_error *erro m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-time", + NULL, interactive, UID_INVALID, &c->polkit_registry, @@ -601,6 +604,7 @@ static int method_set_ntp(sd_bus_message *m, void *userdata, sd_bus_error *error m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-ntp", + NULL, interactive, UID_INVALID, &c->polkit_registry, |