summaryrefslogtreecommitdiff
path: root/src/core/dbus-manager.c
diff options
context:
space:
mode:
authorStef Walter <stef@thewalter.net>2014-08-06 11:45:36 +0200
committerLennart Poettering <lennart@poettering.net>2014-08-18 18:08:28 +0200
commit283868e1dcd8ea7475850d9c6e7d4722c473dd50 (patch)
tree6334ed9b79e0c3c6242acfc050c00da4284ed7d1 /src/core/dbus-manager.c
parentf38857914ab5c9cc55aac05795e1886963a5fd04 (diff)
core: Verify systemd1 DBus method callers via polkit
DBus methods that retrieve information can be called by anyone. DBus methods that modify state of units are verified via polkit action: org.freedesktop.systemd1.manage-units DBus methods that modify state of unit files are verified via polkit action: org.freedesktop.systemd1.manage-unit-files DBus methods that reload the entire daemon state are verified via polkit action: org.freedesktop.systemd1.reload-daemon DBus methods that modify job state are callable from the clients that started the job. root (ie: CAP_SYS_ADMIN) can continue to perform all calls, property access etc. There are several DBus methods that can only be called by root. Open up the dbus1 policy for the above methods. (Heavily modified by Lennart, making use of the new bus_verify_polkit_async() version that doesn't force us to always pass the original callback around. Also, interactive auhentication must be opt-in, not unconditional, hence I turned this off.)
Diffstat (limited to 'src/core/dbus-manager.c')
-rw-r--r--src/core/dbus-manager.c153
1 files changed, 128 insertions, 25 deletions
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index e4d6369c69..008cf6b4cd 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -353,6 +353,8 @@ static int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata,
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = sd_bus_message_read(message, "s", &name);
if (r < 0)
return r;
@@ -385,6 +387,8 @@ static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *us
assert_cc(sizeof(pid_t) == sizeof(uint32_t));
+ /* Anyone can call this method */
+
r = sd_bus_message_read(message, "u", &pid);
if (r < 0)
return r;
@@ -427,6 +431,8 @@ static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = sd_bus_message_read(message, "s", &name);
if (r < 0)
return r;
@@ -455,6 +461,12 @@ static int method_start_unit_generic(sd_bus *bus, sd_bus_message *message, Manag
assert(message);
assert(m);
+ r = bus_verify_manage_unit_async(m, message, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
r = sd_bus_message_read(message, "s", &name);
if (r < 0)
return r;
@@ -504,6 +516,12 @@ static int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void
assert(message);
assert(m);
+ r = bus_verify_manage_unit_async(m, message, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
r = sd_bus_message_read(message, "s", &old_name);
if (r < 0)
return r;
@@ -525,6 +543,13 @@ static int method_kill_unit(sd_bus *bus, sd_bus_message *message, void *userdata
assert(message);
assert(m);
+ /* Like bus_verify_manage_unit_async(), but uses CAP_SYS_KILL */
+ r = bus_verify_manage_unit_async_for_kill(m, message, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
r = sd_bus_message_read(message, "s", &name);
if (r < 0)
return r;
@@ -546,6 +571,12 @@ static int method_reset_failed_unit(sd_bus *bus, sd_bus_message *message, void *
assert(message);
assert(m);
+ r = bus_verify_manage_unit_async(m, message, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
r = sd_bus_message_read(message, "s", &name);
if (r < 0)
return r;
@@ -567,6 +598,12 @@ static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void
assert(message);
assert(m);
+ r = bus_verify_manage_unit_async(m, message, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
r = sd_bus_message_read(message, "s", &name);
if (r < 0)
return r;
@@ -590,6 +627,12 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi
assert(message);
assert(m);
+ r = bus_verify_manage_unit_async(m, message, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
r = sd_bus_message_read(message, "ss", &name, &smode);
if (r < 0)
return r;
@@ -649,6 +692,8 @@ static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata,
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = sd_bus_message_read(message, "u", &id);
if (r < 0)
return r;
@@ -735,6 +780,8 @@ static int list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userd
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
@@ -821,6 +868,8 @@ static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
@@ -871,6 +920,8 @@ static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
@@ -904,6 +955,8 @@ static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userda
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
@@ -930,6 +983,8 @@ static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
@@ -1019,6 +1074,12 @@ static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, s
assert(message);
assert(m);
+ r = bus_verify_reload_daemon_async(m, message, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
r = selinux_access_check(message, "reload", error);
if (r < 0)
return r;
@@ -1047,6 +1108,12 @@ static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata
assert(message);
assert(m);
+ r = bus_verify_reload_daemon_async(m, message, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
r = selinux_access_check(message, "reload", error);
if (r < 0)
return r;
@@ -1322,6 +1389,8 @@ static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *us
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
@@ -1373,6 +1442,8 @@ static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
@@ -1400,6 +1471,8 @@ static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
@@ -1501,6 +1574,12 @@ static int method_enable_unit_files_generic(
assert(message);
assert(m);
+ r = bus_verify_manage_unit_files_async(m, message, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
r = sd_bus_message_read_strv(message, &l);
if (r < 0)
return r;
@@ -1573,6 +1652,12 @@ static int method_preset_unit_files_with_mode(sd_bus *bus, sd_bus_message *messa
assert(message);
assert(m);
+ r = bus_verify_manage_unit_files_async(m, message, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
r = sd_bus_message_read_strv(message, &l);
if (r < 0)
return r;
@@ -1629,6 +1714,12 @@ static int method_disable_unit_files_generic(
assert(message);
assert(m);
+ r = bus_verify_manage_unit_files_async(m, message, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
r = selinux_access_check(message, verb, error);
if (r < 0)
return r;
@@ -1670,6 +1761,12 @@ static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void
assert(message);
assert(m);
+ r = bus_verify_manage_unit_files_async(m, message, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
r = selinux_access_check(message, "enable", error);
if (r < 0)
return r;
@@ -1700,6 +1797,12 @@ static int method_preset_all_unit_files(sd_bus *bus, sd_bus_message *message, vo
assert(message);
assert(m);
+ r = bus_verify_manage_unit_files_async(m, message, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
r = selinux_access_check(message, "enable", error);
if (r < 0)
return r;
@@ -1767,20 +1870,20 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, 0),
- SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, 0),
- SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, 0),
- SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, 0),
- SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, 0),
- SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, 0),
- SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, 0),
- SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, 0),
- SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
- SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, 0),
- SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, 0),
- SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, 0),
+ SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, 0),
+ SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
@@ -1791,8 +1894,8 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
- SD_BUS_METHOD("Reload", NULL, NULL, method_reload, 0),
- SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, 0),
+ SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
@@ -1804,17 +1907,17 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, 0),
SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, 0),
- SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, 0),
- SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, 0),
- SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, 0),
- SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, 0),
- SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, 0),
- SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, 0),
- SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, 0),
- SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, 0),
+ SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, 0),
+ SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL("UnitNew", "so", 0),
SD_BUS_SIGNAL("UnitRemoved", "so", 0),