chiark / gitweb /
Merge remote-tracking branch 'origin/master'
authorLennart Poettering <lennart@poettering.net>
Mon, 18 Aug 2014 16:12:55 +0000 (18:12 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 18 Aug 2014 16:12:55 +0000 (18:12 +0200)
25 files changed:
src/core/dbus-job.c
src/core/dbus-job.h
src/core/dbus-manager.c
src/core/dbus-scope.c
src/core/dbus-unit.c
src/core/dbus.c
src/core/dbus.h
src/core/job.c
src/core/job.h
src/core/manager.h
src/core/org.freedesktop.systemd1.conf
src/core/org.freedesktop.systemd1.policy.in.in
src/hostname/hostnamed.c
src/libsystemd/sd-bus/bus-internal.h
src/libsystemd/sd-bus/bus-match.c
src/libsystemd/sd-bus/bus-objects.c
src/libsystemd/sd-bus/bus-slot.c
src/libsystemd/sd-bus/bus-util.c
src/libsystemd/sd-bus/bus-util.h
src/libsystemd/sd-bus/sd-bus.c
src/locale/localed.c
src/login/logind-dbus.c
src/login/logind.c
src/systemd/sd-bus.h
src/timedate/timedated.c

index 8e4ffc9..eb7257d 100644 (file)
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, job_type, JobType);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_state, job_state, JobState);
 
+static int verify_sys_admin_or_owner_sync(sd_bus_message *message, Job *j, sd_bus_error *error) {
+        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+        int r;
+
+        if (sd_bus_track_contains(j->clients, sd_bus_message_get_sender(message)))
+                return 0; /* One of the job owners is calling us */
+
+        r = sd_bus_query_sender_privilege(message, CAP_SYS_ADMIN);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Access denied to perform action");
+
+        /* Root has called us */
+        return 0;
+}
+
 static int property_get_unit(
                 sd_bus *bus,
                 const char *path,
@@ -52,7 +69,7 @@ static int property_get_unit(
         return sd_bus_message_append(reply, "(so)", j->unit->id, p);
 }
 
-static int method_cancel(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+int bus_job_method_cancel(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
         Job *j = userdata;
         int r;
 
@@ -60,6 +77,10 @@ static int method_cancel(sd_bus *bus, sd_bus_message *message, void *userdata, s
         assert(message);
         assert(j);
 
+        r = verify_sys_admin_or_owner_sync(message, j, error);
+        if (r < 0)
+                return r;
+
         r = selinux_unit_access_check(j->unit, message, "stop", error);
         if (r < 0)
                 return r;
@@ -71,7 +92,7 @@ static int method_cancel(sd_bus *bus, sd_bus_message *message, void *userdata, s
 
 const sd_bus_vtable bus_job_vtable[] = {
         SD_BUS_VTABLE_START(0),
-        SD_BUS_METHOD("Cancel", NULL, NULL, method_cancel, 0),
+        SD_BUS_METHOD("Cancel", NULL, NULL, bus_job_method_cancel, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_PROPERTY("Id", "u", NULL, offsetof(Job, id), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Unit", "(so)", property_get_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("JobType", "s", property_get_type, offsetof(Job, type), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -132,7 +153,7 @@ void bus_job_send_change_signal(Job *j) {
                 j->in_dbus_queue = false;
         }
 
-        r = bus_foreach_bus(j->manager, j->subscribed, j->sent_dbus_new_signal ? send_changed_signal : send_new_signal, j);
+        r = bus_foreach_bus(j->manager, j->clients, j->sent_dbus_new_signal ? send_changed_signal : send_new_signal, j);
         if (r < 0)
                 log_debug("Failed to send job change signal for %u: %s", j->id, strerror(-r));
 
@@ -176,7 +197,7 @@ void bus_job_send_removed_signal(Job *j) {
         if (!j->sent_dbus_new_signal)
                 bus_job_send_change_signal(j);
 
-        r = bus_foreach_bus(j->manager, j->subscribed, send_removed_signal, j);
+        r = bus_foreach_bus(j->manager, j->clients, send_removed_signal, j);
         if (r < 0)
                 log_debug("Failed to send job remove signal for %u: %s", j->id, strerror(-r));
 }
index d1d0f6d..6c2fc07 100644 (file)
@@ -26,5 +26,7 @@
 
 extern const sd_bus_vtable bus_job_vtable[];
 
+int bus_job_method_cancel(sd_bus *bus, sd_bus_message *message, void *job, sd_bus_error *error);
+
 void bus_job_send_change_signal(Job *j);
 void bus_job_send_removed_signal(Job *j);
index ffef0c7..008cf6b 100644 (file)
@@ -34,6 +34,7 @@
 #include "architecture.h"
 #include "env-util.h"
 #include "dbus.h"
+#include "dbus-job.h"
 #include "dbus-manager.h"
 #include "dbus-unit.h"
 #include "dbus-snapshot.h"
@@ -352,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;
@@ -384,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;
@@ -426,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;
@@ -454,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;
@@ -503,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;
@@ -524,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;
@@ -545,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;
@@ -566,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;
@@ -589,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;
@@ -648,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;
@@ -685,13 +731,7 @@ static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdat
         if (!j)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
 
-        r = selinux_unit_access_check(j->unit, message, "stop", error);
-        if (r < 0)
-                return r;
-
-        job_finish_and_invalidate(j, JOB_CANCELED, true);
-
-        return sd_bus_reply_method_return(message, NULL);
+        return bus_job_method_cancel(bus, message, j, error);
 }
 
 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -740,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;
@@ -826,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;
@@ -876,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;
@@ -909,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;
@@ -935,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;
@@ -1024,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;
@@ -1052,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;
@@ -1327,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;
@@ -1378,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;
@@ -1405,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;
@@ -1506,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;
@@ -1578,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;
@@ -1634,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;
@@ -1675,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;
@@ -1705,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;
@@ -1772,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),
@@ -1796,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)),
@@ -1809,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),
index fbb4ff5..a762223 100644 (file)
@@ -25,6 +25,7 @@
 #include "dbus-cgroup.h"
 #include "dbus-kill.h"
 #include "dbus-scope.h"
+#include "dbus.h"
 #include "bus-util.h"
 #include "bus-internal.h"
 #include "bus-errors.h"
@@ -37,6 +38,12 @@ static int bus_scope_abandon(sd_bus *bus, sd_bus_message *message, void *userdat
         assert(message);
         assert(s);
 
+        r = bus_verify_manage_unit_async(UNIT(s)->manager, 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 = scope_abandon(s);
         if (sd_bus_error_is_set(error))
                 return r;
index 8f23fe7..8fe83ae 100644 (file)
@@ -421,6 +421,12 @@ int bus_unit_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, s
         assert(message);
         assert(u);
 
+        r = bus_verify_manage_unit_async_for_kill(u->manager, 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, "si", &swho, &signo);
         if (r < 0)
                 return r;
@@ -455,6 +461,12 @@ int bus_unit_method_reset_failed(sd_bus *bus, sd_bus_message *message, void *use
         assert(message);
         assert(u);
 
+        r = bus_verify_manage_unit_async(u->manager, 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_unit_access_check(u, message, "reload", error);
         if (r < 0)
                 return r;
@@ -472,6 +484,12 @@ int bus_unit_method_set_properties(sd_bus *bus, sd_bus_message *message, void *u
         assert(message);
         assert(u);
 
+        r = bus_verify_manage_unit_async(u->manager, 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, "b", &runtime);
         if (r < 0)
                 return r;
@@ -758,13 +776,13 @@ int bus_unit_queue_job(
                 return r;
 
         if (bus == u->manager->api_bus) {
-                if (!j->subscribed) {
-                        r = sd_bus_track_new(bus, &j->subscribed, NULL, NULL);
+                if (!j->clients) {
+                        r = sd_bus_track_new(bus, &j->clients, NULL, NULL);
                         if (r < 0)
                                 return r;
                 }
 
-                r = sd_bus_track_add_sender(j->subscribed, message);
+                r = sd_bus_track_add_sender(j->clients, message);
                 if (r < 0)
                         return r;
         }
index fb8e496..e7eee3c 100644 (file)
@@ -1048,8 +1048,8 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
                 m->subscribed = sd_bus_track_unref(m->subscribed);
 
         HASHMAP_FOREACH(j, m->jobs, i)
-                if (j->subscribed && sd_bus_track_get_bus(j->subscribed) == *bus)
-                        j->subscribed = sd_bus_track_unref(j->subscribed);
+                if (j->clients && sd_bus_track_get_bus(j->clients) == *bus)
+                        j->clients = sd_bus_track_unref(j->clients);
 
         /* Get rid of queued message on this bus */
         if (m->queued_message_bus == *bus) {
@@ -1092,6 +1092,8 @@ void bus_done(Manager *m) {
                 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
 
         m->private_listen_fd = safe_close(m->private_listen_fd);
+
+        bus_verify_polkit_async_registry_free(m->polkit_registry);
 }
 
 int bus_fdset_add_all(Manager *m, FDSet *fds) {
@@ -1215,3 +1217,20 @@ int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l) {
 
         return r;
 }
+
+int bus_verify_manage_unit_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, &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_unit_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, &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, &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, &m->polkit_registry, error);
+}
index bfb236e..d04f532 100644 (file)
@@ -35,3 +35,8 @@ int bus_track_deserialize_item(char ***l, const char *line);
 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_unit_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
+int bus_verify_manage_unit_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);
index dc4f441..5e4987f 100644 (file)
@@ -90,8 +90,8 @@ void job_free(Job *j) {
 
         sd_event_source_unref(j->timer_event_source);
 
-        sd_bus_track_unref(j->subscribed);
-        strv_free(j->deserialized_subscribed);
+        sd_bus_track_unref(j->clients);
+        strv_free(j->deserialized_clients);
 
         free(j);
 }
@@ -937,7 +937,7 @@ int job_serialize(Job *j, FILE *f, FDSet *fds) {
         if (j->begin_usec > 0)
                 fprintf(f, "job-begin="USEC_FMT"\n", j->begin_usec);
 
-        bus_track_serialize(j->subscribed, f);
+        bus_track_serialize(j->clients, f);
 
         /* End marker */
         fputc('\n', f);
@@ -1043,7 +1043,7 @@ int job_deserialize(Job *j, FILE *f, FDSet *fds) {
 
                 } else if (streq(l, "subscribed")) {
 
-                        if (strv_extend(&j->deserialized_subscribed, v) < 0)
+                        if (strv_extend(&j->deserialized_clients, v) < 0)
                                 return log_oom();
                 }
         }
@@ -1056,7 +1056,7 @@ int job_coldplug(Job *j) {
 
         /* After deserialization is complete and the bus connection
          * set up again, let's start watching our subscribers again */
-        r = bus_track_coldplug(j->manager, &j->subscribed, &j->deserialized_subscribed);
+        r = bus_track_coldplug(j->manager, &j->clients, &j->deserialized_clients);
         if (r < 0)
                 return r;
 
index 30d41d9..1e7c61b 100644 (file)
@@ -145,9 +145,15 @@ struct Job {
         sd_event_source *timer_event_source;
         usec_t begin_usec;
 
-        /* There can be more than one client, because of job merging. */
-        sd_bus_track *subscribed;
-        char **deserialized_subscribed;
+        /*
+         * This tracks where to send signals, and also which clients
+         * are allowed to call DBus methods on the job (other than
+         * root).
+         *
+         * There can be more than one client, because of job merging.
+         */
+        sd_bus_track *clients;
+        char **deserialized_clients;
 
         JobResult result;
 
index aa6c76f..7cb76f7 100644 (file)
@@ -276,6 +276,9 @@ struct Manager {
 
         /* Reference to the kdbus bus control fd */
         int kdbus_fd;
+
+        /* Used for processing polkit authorization responses */
+        Hashmap *polkit_registry;
 };
 
 int manager_new(SystemdRunningAs running_as, bool test_run, Manager **m);
index 9dfca81..3e13825 100644 (file)
@@ -28,6 +28,8 @@
         <policy context="default">
                 <deny send_destination="org.freedesktop.systemd1"/>
 
+                <!-- Completely open to anyone -->
+
                 <allow send_destination="org.freedesktop.systemd1"
                        send_interface="org.freedesktop.DBus.Introspectable"/>
 
                        send_interface="org.freedesktop.systemd1.Manager"
                        send_member="GetDefaultTarget"/>
 
+                <!-- Managed via polkit or other criteria -->
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="StartUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="StartUnitReplace"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="StopUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="ReloadUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="RestartUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="TryRestartUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="ReloadOrRestartUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="ReloadOrTryRestartUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="KillUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="ResetFailedUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="SetUnitProperties"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="StartTransientUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="CancelJob"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="Reload"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="Reexecute"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="EnableUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="DisableUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="ReenableUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="LinkUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="PresetUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="PresetUnitFilesWithMode"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="MaskUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="UnmaskUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="SetDefaultTarget"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="PresetAllUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Job"
+                       send_member="Cancel"/>
+
                 <allow receive_sender="org.freedesktop.systemd1"/>
         </policy>
 
index 51bdafa..387677d 100644 (file)
                 <annotate key="org.freedesktop.policykit.exec.path">@bindir@/systemd-stdio-bridge</annotate>
         </action>
 
+        <action id="org.freedesktop.systemd1.manage-units">
+                <_description>Manage system services or units</_description>
+                <_message>Authentication is required to manage system services or units.</_message>
+                <defaults>
+                        <allow_any>auth_admin</allow_any>
+                        <allow_inactive>auth_admin</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.systemd1.manage-unit-files">
+                <_description>Manage system service or unit files</_description>
+                <_message>Authentication is required to manage system service or unit files.</_message>
+                <defaults>
+                        <allow_any>auth_admin</allow_any>
+                        <allow_inactive>auth_admin</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.systemd1.reload-daemon">
+                <_description>Reload the systemd state</_description>
+                <_message>Authentication is required to reload the systemd state.</_message>
+                <defaults>
+                        <allow_any>auth_admin</allow_any>
+                        <allow_inactive>auth_admin</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
 </policyconfig>
index dae73b3..d31fef7 100644 (file)
@@ -69,11 +69,11 @@ static void context_reset(Context *c) {
         }
 }
 
-static void context_free(Context *c, sd_bus *bus) {
+static void context_free(Context *c) {
         assert(c);
 
         context_reset(c);
-        bus_verify_polkit_async_registry_free(bus, c->polkit_registry);
+        bus_verify_polkit_async_registry_free(c->polkit_registry);
 }
 
 static int context_read_data(Context *c) {
@@ -426,7 +426,7 @@ static int method_set_hostname(sd_bus *bus, sd_bus_message *m, void *userdata, s
         if (streq_ptr(name, c->data[PROP_HOSTNAME]))
                 return sd_bus_reply_method_return(m, NULL);
 
-        r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-hostname", interactive, error, method_set_hostname, c);
+        r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-hostname", interactive, &c->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -468,7 +468,7 @@ static int method_set_static_hostname(sd_bus *bus, sd_bus_message *m, void *user
         if (streq_ptr(name, c->data[PROP_STATIC_HOSTNAME]))
                 return sd_bus_reply_method_return(m, NULL);
 
-        r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-static-hostname", interactive, error, method_set_static_hostname, c);
+        r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-static-hostname", interactive, &c->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -533,10 +533,10 @@ static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop
          * same time as the static one, use the same policy action for
          * both... */
 
-        r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_ADMIN,
+        r = bus_verify_polkit_async(m, CAP_SYS_ADMIN,
                                     prop == PROP_PRETTY_HOSTNAME ?
                                     "org.freedesktop.hostname1.set-static-hostname" :
-                                    "org.freedesktop.hostname1.set-machine-info", interactive, error, cb, c);
+                                    "org.freedesktop.hostname1.set-machine-info", interactive, &c->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -723,7 +723,7 @@ int main(int argc, char *argv[]) {
         }
 
 finish:
-        context_free(&context, bus);
+        context_free(&context);
 
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index 618e82c..f2ccdfd 100644 (file)
@@ -298,6 +298,8 @@ struct sd_bus {
 
         sd_bus_message *current_message;
         sd_bus_slot *current_slot;
+        sd_bus_message_handler_t current_handler;
+        void *current_userdata;
 
         sd_bus **default_bus_ptr;
         pid_t tid;
index 9e0769c..88b61a7 100644 (file)
@@ -294,11 +294,17 @@ int bus_match_run(
                         sd_bus_slot *slot;
 
                         slot = container_of(node->leaf.callback, sd_bus_slot, match_callback);
-                        if (bus)
+                        if (bus) {
                                 bus->current_slot = sd_bus_slot_ref(slot);
+                                bus->current_handler = node->leaf.callback->callback;
+                                bus->current_userdata = slot->userdata;
+                        }
                         r = node->leaf.callback->callback(bus, m, slot->userdata, &error_buffer);
-                        if (bus)
+                        if (bus) {
+                                bus->current_userdata = NULL;
+                                bus->current_handler = NULL;
                                 bus->current_slot = sd_bus_slot_unref(slot);
+                        }
 
                         r = bus_maybe_reply_error(m, r, &error_buffer);
                         if (r != 0)
index 00e8e96..3a2de65 100644 (file)
@@ -51,7 +51,9 @@ static int node_vtable_get_userdata(
         u = s->userdata;
         if (c->find) {
                 bus->current_slot = sd_bus_slot_ref(s);
+                bus->current_userdata = u;
                 r = c->find(bus, path, c->interface, u, &u, error);
+                bus->current_userdata = NULL;
                 bus->current_slot = sd_bus_slot_unref(s);
 
                 if (r < 0)
@@ -123,7 +125,9 @@ static int add_enumerated_to_set(
                 slot = container_of(c, sd_bus_slot, node_enumerator);
 
                 bus->current_slot = sd_bus_slot_ref(slot);
+                bus->current_userdata = slot->userdata;
                 r = c->callback(bus, prefix, slot->userdata, &children, error);
+                bus->current_userdata = NULL;
                 bus->current_slot = sd_bus_slot_unref(slot);
 
                 if (r < 0)
@@ -273,7 +277,11 @@ static int node_callbacks_run(
                 slot = container_of(c, sd_bus_slot, node_callback);
 
                 bus->current_slot = sd_bus_slot_ref(slot);
+                bus->current_handler = c->callback;
+                bus->current_userdata = slot->userdata;
                 r = c->callback(bus, m, slot->userdata, &error_buffer);
+                bus->current_userdata = NULL;
+                bus->current_handler = NULL;
                 bus->current_slot = sd_bus_slot_unref(slot);
 
                 r = bus_maybe_reply_error(m, r, &error_buffer);
@@ -387,7 +395,11 @@ static int method_callbacks_run(
                 slot = container_of(c->parent, sd_bus_slot, node_vtable);
 
                 bus->current_slot = sd_bus_slot_ref(slot);
+                bus->current_handler = c->vtable->x.method.handler;
+                bus->current_userdata = u;
                 r = c->vtable->x.method.handler(bus, m, u, &error);
+                bus->current_userdata = NULL;
+                bus->current_handler = NULL;
                 bus->current_slot = sd_bus_slot_unref(slot);
 
                 return bus_maybe_reply_error(m, r, &error);
@@ -426,7 +438,9 @@ static int invoke_property_get(
         if (v->x.property.get) {
 
                 bus->current_slot = sd_bus_slot_ref(slot);
+                bus->current_userdata = userdata;
                 r = v->x.property.get(bus, path, interface, property, reply, userdata, error);
+                bus->current_userdata = NULL;
                 bus->current_slot = sd_bus_slot_unref(slot);
 
                 if (r < 0)
@@ -488,7 +502,9 @@ static int invoke_property_set(
         if (v->x.property.set) {
 
                 bus->current_slot = sd_bus_slot_ref(slot);
+                bus->current_userdata = userdata;
                 r = v->x.property.set(bus, path, interface, property, value, userdata, error);
+                bus->current_userdata = NULL;
                 bus->current_slot = sd_bus_slot_unref(slot);
 
                 if (r < 0)
index 5e92751..d6793c2 100644 (file)
@@ -245,3 +245,23 @@ _public_ sd_bus_message *sd_bus_slot_get_current_message(sd_bus_slot *slot) {
 
         return slot->bus->current_message;
 }
+
+_public_ sd_bus_message_handler_t sd_bus_slot_get_current_handler(sd_bus_slot *slot) {
+        assert_return(slot, NULL);
+        assert_return(slot->type >= 0, NULL);
+
+        if (slot->bus->current_slot != slot)
+                return NULL;
+
+        return slot->bus->current_handler;
+}
+
+_public_ void* sd_bus_slot_get_current_userdata(sd_bus_slot *slot) {
+        assert_return(slot, NULL);
+        assert_return(slot->type >= 0, NULL);
+
+        if (slot->bus->current_slot != slot)
+                return NULL;
+
+        return slot->bus->current_userdata;
+}
index 0ab11c3..44facc6 100644 (file)
@@ -184,8 +184,7 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
 }
 
 int bus_verify_polkit(
-                sd_bus *bus,
-                sd_bus_message *m,
+                sd_bus_message *call,
                 int capability,
                 const char *action,
                 bool interactive,
@@ -194,28 +193,26 @@ int bus_verify_polkit(
 
         int r;
 
-        assert(bus);
-        assert(m);
+        assert(call);
         assert(action);
 
-        r = sd_bus_query_sender_privilege(m, capability);
+        r = sd_bus_query_sender_privilege(call, capability);
         if (r < 0)
                 return r;
-        if (r > 0)
+        else if (r > 0)
                 return 1;
-
 #ifdef ENABLE_POLKIT
         else {
                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
                 int authorized = false, challenge = false;
                 const char *sender;
 
-                sender = sd_bus_message_get_sender(m);
+                sender = sd_bus_message_get_sender(call);
                 if (!sender)
                         return -EBADMSG;
 
                 r = sd_bus_call_method(
-                                bus,
+                                call->bus,
                                 "org.freedesktop.PolicyKit1",
                                 "/org/freedesktop/PolicyKit1/Authority",
                                 "org.freedesktop.PolicyKit1.Authority",
@@ -316,30 +313,29 @@ finish:
 #endif
 
 int bus_verify_polkit_async(
-                sd_bus *bus,
-                Hashmap **registry,
-                sd_bus_message *m,
+                sd_bus_message *call,
                 int capability,
                 const char *action,
                 bool interactive,
-                sd_bus_error *error,
-                sd_bus_message_handler_t callback,
-                void *userdata) {
+                Hashmap **registry,
+                sd_bus_error *error) {
 
 #ifdef ENABLE_POLKIT
         _cleanup_bus_message_unref_ sd_bus_message *pk = NULL;
+        _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
         AsyncPolkitQuery *q;
         const char *sender;
+        sd_bus_message_handler_t callback;
+        void *userdata;
 #endif
         int r;
 
-        assert(bus);
-        assert(registry);
-        assert(m);
+        assert(call);
         assert(action);
+        assert(registry);
 
 #ifdef ENABLE_POLKIT
-        q = hashmap_get(*registry, m);
+        q = hashmap_get(*registry, call);
         if (q) {
                 int authorized, challenge;
 
@@ -376,14 +372,23 @@ int bus_verify_polkit_async(
         }
 #endif
 
-        r = sd_bus_query_sender_privilege(m, capability);
+        r = sd_bus_query_sender_privilege(call, capability);
         if (r < 0)
                 return r;
-        if (r > 0)
+        else if (r > 0)
                 return 1;
 
 #ifdef ENABLE_POLKIT
-        sender = sd_bus_message_get_sender(m);
+        if (sd_bus_get_current_message(call->bus) != call)
+                return -EINVAL;
+
+        callback = sd_bus_get_current_handler(call->bus);
+        if (!callback)
+                return -EINVAL;
+
+        userdata = sd_bus_get_current_userdata(call->bus);
+
+        sender = sd_bus_message_get_sender(call);
         if (!sender)
                 return -EBADMSG;
 
@@ -392,7 +397,7 @@ int bus_verify_polkit_async(
                 return r;
 
         r = sd_bus_message_new_method_call(
-                        bus,
+                        call->bus,
                         &pk,
                         "org.freedesktop.PolicyKit1",
                         "/org/freedesktop/PolicyKit1/Authority",
@@ -416,11 +421,11 @@ int bus_verify_polkit_async(
         if (!q)
                 return -ENOMEM;
 
-        q->request = sd_bus_message_ref(m);
+        q->request = sd_bus_message_ref(call);
         q->callback = callback;
         q->userdata = userdata;
 
-        r = hashmap_put(*registry, m, q);
+        r = hashmap_put(*registry, call, q);
         if (r < 0) {
                 async_polkit_query_free(q);
                 return r;
@@ -428,7 +433,7 @@ int bus_verify_polkit_async(
 
         q->registry = *registry;
 
-        r = sd_bus_call_async(bus, &q->slot, pk, async_polkit_callback, q, 0);
+        r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0);
         if (r < 0) {
                 async_polkit_query_free(q);
                 return r;
@@ -440,7 +445,7 @@ int bus_verify_polkit_async(
         return -EACCES;
 }
 
-void bus_verify_polkit_async_registry_free(sd_bus *bus, Hashmap *registry) {
+void bus_verify_polkit_async_registry_free(Hashmap *registry) {
 #ifdef ENABLE_POLKIT
         AsyncPolkitQuery *q;
 
index f760a1e..faf1775 100644 (file)
@@ -62,10 +62,10 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error);
 
 int bus_check_peercred(sd_bus *c);
 
-int bus_verify_polkit(sd_bus *bus, sd_bus_message *m, int capability, const char *action, bool interactive, bool *_challenge, sd_bus_error *e);
+int bus_verify_polkit(sd_bus_message *call, int capability, const char *action, bool interactive, bool *_challenge, sd_bus_error *e);
 
-int bus_verify_polkit_async(sd_bus *bus, Hashmap **registry, sd_bus_message *m, int capability, const char *action, bool interactive, sd_bus_error *error, sd_bus_message_handler_t callback, void *userdata);
-void bus_verify_polkit_async_registry_free(sd_bus *bus, Hashmap *registry);
+int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *action, bool interactive, Hashmap **registry, sd_bus_error *error);
+void bus_verify_polkit_async_registry_free(Hashmap *registry);
 
 int bus_open_system_systemd(sd_bus **_bus);
 int bus_open_user_systemd(sd_bus **_bus);
index 0fadd16..83233fd 100644 (file)
@@ -2102,7 +2102,11 @@ static int process_timeout(sd_bus *bus) {
 
         bus->current_message = m;
         bus->current_slot = sd_bus_slot_ref(slot);
+        bus->current_handler = c->callback;
+        bus->current_userdata = slot->userdata;
         r = c->callback(bus, m, slot->userdata, &error_buffer);
+        bus->current_userdata = NULL;
+        bus->current_handler = NULL;
         bus->current_slot = sd_bus_slot_unref(slot);
         bus->current_message = NULL;
 
@@ -2194,7 +2198,11 @@ static int process_reply(sd_bus *bus, sd_bus_message *m) {
         }
 
         bus->current_slot = sd_bus_slot_ref(slot);
+        bus->current_handler = c->callback;
+        bus->current_userdata = slot->userdata;
         r = c->callback(bus, m, slot->userdata, &error_buffer);
+        bus->current_userdata = NULL;
+        bus->current_handler = NULL;
         bus->current_slot = sd_bus_slot_unref(slot);
 
         if (slot->floating) {
@@ -2235,7 +2243,11 @@ static int process_filter(sd_bus *bus, sd_bus_message *m) {
                         slot = container_of(l, sd_bus_slot, filter_callback);
 
                         bus->current_slot = sd_bus_slot_ref(slot);
+                        bus->current_handler = l->callback;
+                        bus->current_userdata = slot->userdata;
                         r = l->callback(bus, m, slot->userdata, &error_buffer);
+                        bus->current_userdata = NULL;
+                        bus->current_handler = NULL;
                         bus->current_slot = sd_bus_slot_unref(slot);
 
                         r = bus_maybe_reply_error(m, r, &error_buffer);
@@ -2512,7 +2524,11 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) {
 
                 bus->current_message = m;
                 bus->current_slot = sd_bus_slot_ref(slot);
+                bus->current_handler = c->callback;
+                bus->current_userdata = slot->userdata;
                 r = c->callback(bus, m, slot->userdata, &error_buffer);
+                bus->current_userdata = NULL;
+                bus->current_handler = NULL;
                 bus->current_slot = sd_bus_slot_unref(slot);
                 bus->current_message = NULL;
 
@@ -3113,6 +3129,18 @@ _public_ sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus) {
         return bus->current_slot;
 }
 
+_public_ sd_bus_message_handler_t sd_bus_get_current_handler(sd_bus *bus) {
+        assert_return(bus, NULL);
+
+        return bus->current_handler;
+}
+
+_public_ void* sd_bus_get_current_userdata(sd_bus *bus) {
+        assert_return(bus, NULL);
+
+        return bus->current_userdata;
+}
+
 static int bus_default(int (*bus_open)(sd_bus **), sd_bus **default_bus, sd_bus **ret) {
         sd_bus *b = NULL;
         int r;
index 0870667..508a000 100644 (file)
@@ -132,12 +132,12 @@ static void context_free_locale(Context *c) {
                 free_and_replace(&c->locale[p], NULL);
 }
 
-static void context_free(Context *c, sd_bus *bus) {
+static void context_free(Context *c) {
         context_free_locale(c);
         context_free_x11(c);
         context_free_vconsole(c);
 
-        bus_verify_polkit_async_registry_free(bus, c->polkit_registry);
+        bus_verify_polkit_async_registry_free(c->polkit_registry);
 };
 
 static void locale_simplify(Context *c) {
@@ -877,9 +877,7 @@ static int method_set_locale(sd_bus *bus, sd_bus_message *m, void *userdata, sd_
         }
 
         if (modified) {
-                r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_ADMIN,
-                                            "org.freedesktop.locale1.set-locale", interactive,
-                                            error, method_set_locale, c);
+                r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-locale", interactive, &c->polkit_registry, error);
                 if (r < 0)
                         return r;
                 if (r == 0)
@@ -955,9 +953,7 @@ static int method_set_vc_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata
                     (keymap_toggle && (!filename_is_safe(keymap_toggle) || !string_is_safe(keymap_toggle))))
                         return sd_bus_error_set_errnof(error, -EINVAL, "Received invalid keymap data");
 
-                r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_ADMIN,
-                                "org.freedesktop.locale1.set-keyboard",
-                                interactive, error, method_set_vc_keyboard, c);
+                r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", interactive, &c->polkit_registry, error);
                 if (r < 0)
                         return r;
                 if (r == 0)
@@ -1027,9 +1023,7 @@ static int method_set_x11_keyboard(sd_bus *bus, sd_bus_message *m, void *userdat
                     (options && !string_is_safe(options)))
                         return sd_bus_error_set_errnof(error, -EINVAL, "Received invalid keyboard data");
 
-                r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_ADMIN,
-                                "org.freedesktop.locale1.set-keyboard",
-                                interactive, error, method_set_x11_keyboard, c);
+                r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", interactive, &c->polkit_registry, error);
                 if (r < 0)
                         return r;
                 if (r == 0)
@@ -1161,7 +1155,7 @@ int main(int argc, char *argv[]) {
         }
 
 finish:
-        context_free(&context, bus);
+        context_free(&context);
 
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index bcfcba2..acef511 100644 (file)
@@ -1029,14 +1029,13 @@ static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *us
         if (!pw)
                 return errno ? -errno : -ENOENT;
 
-        r = bus_verify_polkit_async(bus,
-                                    &m->polkit_registry,
-                                    message,
-                                    CAP_SYS_ADMIN,
-                                    "org.freedesktop.login1.set-user-linger",
-                                    interactive,
-                                    error,
-                                    method_set_user_linger, m);
+        r = bus_verify_polkit_async(
+                        message,
+                        CAP_SYS_ADMIN,
+                        "org.freedesktop.login1.set-user-linger",
+                        interactive,
+                        &m->polkit_registry,
+                        error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -1202,14 +1201,13 @@ static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *user
         if (!seat_name_is_valid(seat))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
 
-        r = bus_verify_polkit_async(bus,
-                                    &m->polkit_registry,
-                                    message,
-                                    CAP_SYS_ADMIN,
-                                    "org.freedesktop.login1.attach-device",
-                                    interactive,
-                                    error,
-                                    method_attach_device, m);
+        r = bus_verify_polkit_async(
+                        message,
+                        CAP_SYS_ADMIN,
+                        "org.freedesktop.login1.attach-device",
+                        interactive,
+                        &m->polkit_registry,
+                        error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -1234,14 +1232,13 @@ static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *user
         if (r < 0)
                 return r;
 
-        r = bus_verify_polkit_async(bus,
-                                    &m->polkit_registry,
-                                    message,
-                                    CAP_SYS_ADMIN,
-                                    "org.freedesktop.login1.flush-devices",
-                                    interactive,
-                                    error,
-                                    method_flush_devices, m);
+        r = bus_verify_polkit_async(
+                        message,
+                        CAP_SYS_ADMIN,
+                        "org.freedesktop.login1.flush-devices",
+                        interactive,
+                        &m->polkit_registry,
+                        error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -1535,8 +1532,7 @@ static int method_do_shutdown_or_sleep(
         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
 
         if (multiple_sessions) {
-                r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message, CAP_SYS_BOOT,
-                                            action_multiple_sessions, interactive, error, method, m);
+                r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, &m->polkit_registry, error);
                 if (r < 0)
                         return r;
                 if (r == 0)
@@ -1544,8 +1540,7 @@ static int method_do_shutdown_or_sleep(
         }
 
         if (blocked) {
-                r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message, CAP_SYS_BOOT,
-                                            action_ignore_inhibit, interactive, error, method, m);
+                r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, &m->polkit_registry, error);
                 if (r < 0)
                         return r;
                 if (r == 0)
@@ -1553,8 +1548,7 @@ static int method_do_shutdown_or_sleep(
         }
 
         if (!multiple_sessions && !blocked) {
-                r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message, CAP_SYS_BOOT,
-                                            action, interactive, error, method, m);
+                r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, &m->polkit_registry, error);
                 if (r < 0)
                         return r;
                 if (r == 0)
@@ -1691,7 +1685,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_verify_polkit(m->bus, message, CAP_SYS_BOOT, action_multiple_sessions, false, &challenge, error);
+                r = bus_verify_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, false, &challenge, error);
                 if (r < 0)
                         return r;
 
@@ -1704,7 +1698,7 @@ static int method_can_shutdown_or_sleep(
         }
 
         if (blocked) {
-                r = bus_verify_polkit(m->bus, message, CAP_SYS_BOOT, action_ignore_inhibit, false, &challenge, error);
+                r = bus_verify_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, false, &challenge, error);
                 if (r < 0)
                         return r;
 
@@ -1720,7 +1714,7 @@ static int method_can_shutdown_or_sleep(
                 /* If neither inhibit nor multiple sessions
                  * apply then just check the normal policy */
 
-                r = bus_verify_polkit(m->bus, message, CAP_SYS_BOOT, action, false, &challenge, error);
+                r = bus_verify_polkit(message, CAP_SYS_BOOT, action, false, &challenge, error);
                 if (r < 0)
                         return r;
 
@@ -1840,7 +1834,7 @@ static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata,
         if (m->action_what & w)
                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
 
-        r = bus_verify_polkit_async(bus, &m->polkit_registry, message, CAP_SYS_BOOT,
+        r = bus_verify_polkit_async(message, CAP_SYS_BOOT,
                                     w == INHIBIT_SHUTDOWN             ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
                                     w == INHIBIT_SLEEP                ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep"    : "org.freedesktop.login1.inhibit-delay-sleep") :
                                     w == INHIBIT_IDLE                 ? "org.freedesktop.login1.inhibit-block-idle" :
@@ -1848,7 +1842,7 @@ static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata,
                                     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",
-                                    false, error, method_inhibit, m);
+                                    false, &m->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
index 8ec8105..006c56a 100644 (file)
@@ -163,7 +163,7 @@ void manager_free(Manager *m) {
         if (m->udev)
                 udev_unref(m->udev);
 
-        bus_verify_polkit_async_registry_free(m->bus, m->polkit_registry);
+        bus_verify_polkit_async_registry_free(m->polkit_registry);
 
         sd_bus_unref(m->bus);
         sd_event_unref(m->event);
index c601093..1e23a93 100644 (file)
@@ -148,8 +148,10 @@ int sd_bus_process(sd_bus *bus, sd_bus_message **r);
 int sd_bus_process_priority(sd_bus *bus, int64_t max_priority, sd_bus_message **r);
 int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec);
 int sd_bus_flush(sd_bus *bus);
-sd_bus_message* sd_bus_get_current_message(sd_bus *bus);
 sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus);
+sd_bus_message* sd_bus_get_current_message(sd_bus *bus);
+sd_bus_message_handler_t sd_bus_get_current_handler(sd_bus *bus);
+void* sd_bus_get_current_userdata(sd_bus *bus);
 
 int sd_bus_attach_event(sd_bus *bus, sd_event *e, int priority);
 int sd_bus_detach_event(sd_bus *bus);
@@ -175,6 +177,8 @@ void *sd_bus_slot_get_userdata(sd_bus_slot *slot);
 void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata);
 
 sd_bus_message* sd_bus_slot_get_current_message(sd_bus_slot *slot);
+sd_bus_message_handler_t sd_bus_slot_get_current_handler(sd_bus_slot *bus);
+void *sd_bus_slot_get_current_userdata(sd_bus_slot *slot);
 
 /* Message object */
 
index f037175..fa3f947 100644 (file)
@@ -52,11 +52,11 @@ typedef struct Context {
         Hashmap *polkit_registry;
 } Context;
 
-static void context_free(Context *c, sd_bus *bus) {
+static void context_free(Context *c) {
         assert(c);
 
         free(c->zone);
-        bus_verify_polkit_async_registry_free(bus, c->polkit_registry);
+        bus_verify_polkit_async_registry_free(c->polkit_registry);
 }
 
 static int context_read_data(Context *c) {
@@ -395,7 +395,7 @@ static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata, s
         if (streq_ptr(z, c->zone))
                 return sd_bus_reply_method_return(m, NULL);
 
-        r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-timezone", interactive, error, method_set_timezone, c);
+        r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-timezone", interactive, &c->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -456,7 +456,7 @@ static int method_set_local_rtc(sd_bus *bus, sd_bus_message *m, void *userdata,
         if (lrtc == c->local_rtc)
                 return sd_bus_reply_method_return(m, NULL);
 
-        r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-local-rtc", interactive, error, method_set_local_rtc, c);
+        r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-local-rtc", interactive, &c->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -561,7 +561,7 @@ static int method_set_time(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bu
         } else
                 timespec_store(&ts, (usec_t) utc);
 
-        r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-time", interactive, error, method_set_time, c);
+        r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-time", interactive, &c->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -601,7 +601,7 @@ static int method_set_ntp(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus
         if ((bool)ntp == c->use_ntp)
                 return sd_bus_reply_method_return(m, NULL);
 
-        r = bus_verify_polkit_async(bus, &c->polkit_registry, m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-ntp", interactive, error, method_set_ntp, c);
+        r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-ntp", interactive, &c->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -727,7 +727,7 @@ int main(int argc, char *argv[]) {
         }
 
 finish:
-        context_free(&context, bus);
+        context_free(&context);
 
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }