diff options
author | Stef Walter <stef@thewalter.net> | 2014-08-06 11:45:36 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-08-18 18:08:28 +0200 |
commit | 283868e1dcd8ea7475850d9c6e7d4722c473dd50 (patch) | |
tree | 6334ed9b79e0c3c6242acfc050c00da4284ed7d1 /src/core/dbus-manager.c | |
parent | f38857914ab5c9cc55aac05795e1886963a5fd04 (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.c | 153 |
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), |