mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-10-26 08:55:18 +03:00
core: pass details to polkit for some unit actions
The following details are passed: - unit: the primary name of the unit upon which the action was invoked (i.e. after resolving any aliases); - verb: one of 'start', 'stop', 'reload', 'restart', 'try-restart', 'reload-or-restart', 'reload-or-try-restart', 'kill', 'reset-failed', or 'set-property', corresponding to the systemctl verb used to invoke the action. Typical use of these details in a polkit policy rule might be: // Allow alice to manage example.service; // fall back to implicit authorization otherwise. polkit.addRule(function(action, subject) { if (action.id == "org.freedesktop.systemd1.manage-units" && action.lookup("unit") == "example.service" && subject.user == "alice") { return polkit.Result.YES; } }); We also supply a custom polkit message that includes the unit's name and the requested operation.
This commit is contained in:
parent
403ed0e5c9
commit
88ced61bf9
@ -5,3 +5,4 @@ src/locale/org.freedesktop.locale1.policy.in
|
||||
src/login/org.freedesktop.login1.policy.in
|
||||
src/machine/org.freedesktop.machine1.policy.in
|
||||
src/timedate/org.freedesktop.timedate1.policy.in
|
||||
src/core/dbus-unit.c
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -1201,11 +1201,6 @@ int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error
|
||||
return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-units", NULL, 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", 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", NULL, false, UID_INVALID, &m->polkit_registry, error);
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user