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,
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;
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;
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),
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));
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));
}
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);
#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"
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = sd_bus_message_read(message, "s", &name);
if (r < 0)
return r;
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;
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = sd_bus_message_read(message, "s", &name);
if (r < 0)
return r;
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;
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;
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;
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;
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;
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;
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = sd_bus_message_read(message, "u", &id);
if (r < 0)
return r;
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) {
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
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;
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;
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
assert(message);
assert(m);
+ /* Anyone can call this method */
+
r = selinux_access_check(message, "status", error);
if (r < 0)
return r;
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;
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;
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;
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;
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;
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),
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)),
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),
#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"
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;
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;
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;
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;
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;
}
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) {
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) {
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);
+}
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);
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);
}
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);
} else if (streq(l, "subscribed")) {
- if (strv_extend(&j->deserialized_subscribed, v) < 0)
+ if (strv_extend(&j->deserialized_clients, v) < 0)
return log_oom();
}
}
/* 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;
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;
/* 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);
<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>
<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>
}
}
-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) {
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)
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)
* 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)
}
finish:
- context_free(&context, bus);
+ context_free(&context);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
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;
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)
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)
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)
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);
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);
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)
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)
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;
+}
}
int bus_verify_polkit(
- sd_bus *bus,
- sd_bus_message *m,
+ sd_bus_message *call,
int capability,
const char *action,
bool interactive,
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",
#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;
}
#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;
return r;
r = sd_bus_message_new_method_call(
- bus,
+ call->bus,
&pk,
"org.freedesktop.PolicyKit1",
"/org/freedesktop/PolicyKit1/Authority",
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;
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;
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;
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);
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;
}
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) {
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);
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;
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;
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) {
}
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)
(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)
(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)
}
finish:
- context_free(&context, bus);
+ context_free(&context);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
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)
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)
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)
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)
}
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)
}
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)
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;
}
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;
/* 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;
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" :
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)
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);
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);
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 */
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) {
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)
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)
} 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)
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)
}
finish:
- context_free(&context, bus);
+ context_free(&context);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}