logind-dbus.c revision 05bae4a60c32e29797597979cee2f3684eb3bc1e
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt This file is part of systemd.
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt Copyright 2011 Lennart Poettering
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt systemd is free software; you can redistribute it and/or modify it
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt under the terms of the GNU Lesser General Public License as published by
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt the Free Software Foundation; either version 2.1 of the License, or
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt (at your option) any later version.
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt systemd is distributed in the hope that it will be useful, but
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt WITHOUT ANY WARRANTY; without even the implied warranty of
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt Lesser General Public License for more details.
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt You should have received a copy of the GNU Lesser General Public License
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt along with systemd; If not, see <http://www.gnu.org/licenses/>.
be3a09b7ffe62b52658e77ae4d6638d1b0dae654Patrik Flyktint manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
be3a09b7ffe62b52658e77ae4d6638d1b0dae654Patrik Flykt _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
c62c4628d9dbc27effd36143c75abe528f561867Patrik Flykt r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_SESSION|SD_BUS_CREDS_AUGMENT, &creds);
c62c4628d9dbc27effd36143c75abe528f561867Patrik Flykt return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
c62c4628d9dbc27effd36143c75abe528f561867Patrik Flyktint manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret) {
c62c4628d9dbc27effd36143c75abe528f561867Patrik Flykt _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering /* Note that we get the owner UID of the session, not the actual client UID here! */
575ac4c62e417cb3e963f2bee627e3c10b06691dDavid Herrmann r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_OWNER_UID|SD_BUS_CREDS_AUGMENT, &creds);
c62c4628d9dbc27effd36143c75abe528f561867Patrik Flykt return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
c62c4628d9dbc27effd36143c75abe528f561867Patrik Flyktint manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret) {
c62c4628d9dbc27effd36143c75abe528f561867Patrik Flykt r = manager_get_session_from_creds(m, message, NULL, error, &session);
c62c4628d9dbc27effd36143c75abe528f561867Patrik Flykt return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "Session has no seat.");
c62c4628d9dbc27effd36143c75abe528f561867Patrik Flykt return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SEAT, "No seat '%s' known", name);
c62c4628d9dbc27effd36143c75abe528f561867Patrik Flykt const char *path,
10c9ce615d98e125bc520efa94aebaef250a4061David Herrmann return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
c62c4628d9dbc27effd36143c75abe528f561867Patrik Flykt const char *path,
18d29550b5fbc4b0de334b8212d05decdd131f1bPatrik Flykt return sd_bus_message_append(reply, "t", streq(property, "IdleSinceHint") ? t.realtime : t.monotonic);
e66040417b52be98d41ba1230f25dea65147e8eePatrik Flykt w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
e66040417b52be98d41ba1230f25dea65147e8eePatrik Flykt return sd_bus_message_append(reply, "s", inhibit_what_to_string(w));
85bd849f09aceb7f972a0697494ea22b2247a5d7Patrik Flykt const char *path,
85bd849f09aceb7f972a0697494ea22b2247a5d7Patrik Flyktstatic BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
e66040417b52be98d41ba1230f25dea65147e8eePatrik Flyktstatic int method_get_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e53fc357a9bb9d0a5362ccc4246d598cb0febd5eLennart Poettering _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
85bd849f09aceb7f972a0697494ea22b2247a5d7Patrik Flykt const char *name;
e66040417b52be98d41ba1230f25dea65147e8eePatrik Flykt r = manager_get_session_from_creds(m, message, name, error, &session);
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt return sd_bus_reply_method_return(message, "o", p);
e66040417b52be98d41ba1230f25dea65147e8eePatrik Flyktstatic int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e66040417b52be98d41ba1230f25dea65147e8eePatrik Flykt r = manager_get_session_from_creds(m, message, NULL, error, &session);
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt r = manager_get_session_by_pid(m, pid, &session);
be3a09b7ffe62b52658e77ae4d6638d1b0dae654Patrik Flykt return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
be3a09b7ffe62b52658e77ae4d6638d1b0dae654Patrik Flykt return sd_bus_reply_method_return(message, "o", p);
be3a09b7ffe62b52658e77ae4d6638d1b0dae654Patrik Flyktstatic int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
be3a09b7ffe62b52658e77ae4d6638d1b0dae654Patrik Flykt r = manager_get_user_from_creds(m, message, uid, error, &user);
be3a09b7ffe62b52658e77ae4d6638d1b0dae654Patrik Flykt return sd_bus_reply_method_return(message, "o", p);
be3a09b7ffe62b52658e77ae4d6638d1b0dae654Patrik Flyktstatic int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
c62c4628d9dbc27effd36143c75abe528f561867Patrik Flykt r = manager_get_user_from_creds(m, message, UID_INVALID, error, &user);
be3a09b7ffe62b52658e77ae4d6638d1b0dae654Patrik Flykt return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID "PID_FMT" does not belong to any known or logged in user", pid);
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt return sd_bus_reply_method_return(message, "o", p);
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flyktstatic int method_get_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt const char *name;
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt r = manager_get_seat_from_creds(m, message, name, error, &seat);
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt return sd_bus_reply_method_return(message, "o", p);
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flyktstatic int method_list_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
5c79bd79839f1e50bd3c34a0670037f7965ca5a4Patrik Flykt _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
Iterator i;
assert(m);
return -ENOMEM;
static int method_list_users(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Iterator i;
assert(m);
return -ENOMEM;
static int method_list_seats(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Iterator i;
assert(m);
return -ENOMEM;
static int method_list_inhibitors(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Iterator i;
static int method_create_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
int remote;
SessionType t;
SessionClass c;
assert(m);
r = sd_bus_message_read(message, "uusssssussbss", &uid, &leader, &service, &type, &class, &desktop, &cseat, &vtnr, &tty, &display, &remote, &remote_user, &remote_host);
if (!seat)
if (!seat)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY %s is virtual console but seat %s is not seat0", tty, seat->id);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot determine VT number from virtual console TTY %s", tty);
if (!vtnr)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified TTY and VT number do not match");
if (!seat)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but seat is not seat0");
if (vtnr != 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Console TTY specified but VT number is not 0");
if (seat) {
if (vtnr != 0)
if (t == _SESSION_TYPE_INVALID) {
t = SESSION_X11;
t = SESSION_TTY;
t = SESSION_UNSPECIFIED;
if (c == _SESSION_CLASS_INVALID) {
if (t == SESSION_UNSPECIFIED)
c = SESSION_BACKGROUND;
c = SESSION_USER;
if (leader <= 0) {
if (session) {
if (fifo_fd < 0)
return fifo_fd;
if (!path)
return -ENOMEM;
path,
return sd_bus_reply_method_return(
path,
if (audit_id > 0) {
return -ENOMEM;
audit_id = 0;
if (!id) {
return -ENOMEM;
goto fail;
goto fail;
r = -ENOMEM;
goto fail;
r = -ENOMEM;
goto fail;
r = -ENOMEM;
goto fail;
r = -ENOMEM;
goto fail;
r = -ENOMEM;
goto fail;
r = -ENOMEM;
goto fail;
if (seat) {
goto fail;
goto fail;
fail:
if (session)
if (user)
static int method_release_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
assert(m);
static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
assert(m);
static int method_activate_session_on_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(m);
return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", session_name, seat_name);
static int method_lock_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
assert(m);
static int method_lock_sessions(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(m);
static int method_kill_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(m);
if (who < 0)
static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(m);
static int method_terminate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
assert(m);
static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(m);
static int method_terminate_seat(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
assert(m);
static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *path;
int interactive;
assert(m);
errno = 0;
if (!pw)
"org.freedesktop.login1.set-user-linger",
&m->polkit_registry,
error);
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
if (!cc)
return -ENOMEM;
User *u;
user_start(u);
User *u;
return -errno;
assert(m);
return -ENOMEM;
r = udev_enumerate_add_match_parent(e, d);
r = udev_enumerate_scan_devices(e);
return -ENOMEM;
const char *id_for_seat;
assert(m);
return -ENODEV;
return -ENODEV;
if (!id_for_seat)
return -ENODEV;
return -ENOMEM;
if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
return -ENOMEM;
return trigger_device(m, d);
assert(m);
static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
int interactive, r;
assert(m);
&m->polkit_registry,
error);
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
int interactive, r;
assert(m);
&m->polkit_registry,
error);
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
r = flush_devices(m);
static int have_multiple_sessions(
Manager *m,
Iterator i;
assert(m);
static int bus_manager_log_shutdown(
Manager *m,
InhibitWhat w,
const char *unit_name) {
assert(m);
if (w != INHIBIT_SHUTDOWN)
q = NULL;
NULL);
assert(e);
assert(m);
assert(m);
if (m->lid_switch_ignore_event_source) {
usec_t u;
if (until <= u)
r = sd_event_add_time(
m->event,
until, 0,
static int execute_shutdown_or_sleep(
Manager *m,
InhibitWhat w,
const char *unit_name,
assert(m);
assert(w >= 0);
r = sd_bus_call_method(
m->bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
&reply,
c = strdup(p);
return -ENOMEM;
m->action_job = c;
m->action_what = w;
static int delay_shutdown_or_sleep(
Manager *m,
InhibitWhat w,
const char *unit_name) {
assert(m);
assert(w >= 0);
m->action_what = w;
assert(m);
assert(w >= 0);
"/org/freedesktop/login1",
signal_name[w],
active);
Manager *m,
const char *unit_name,
InhibitWhat w,
bool delayed;
assert(m);
assert(w >= 0);
send_prepare_for(m, w, true);
delayed =
m->inhibit_delay_max > 0 &&
if (delayed)
static int method_do_shutdown_or_sleep(
Manager *m,
const char *unit_name,
InhibitWhat w,
const char *action,
const char *action_multiple_sessions,
const char *action_ignore_inhibit,
const char *sleep_verb,
int interactive, r;
assert(m);
assert(w >= 0);
if (m->action_what)
return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
if (sleep_verb) {
multiple_sessions = r > 0;
if (multiple_sessions) {
r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, &m->polkit_registry, error);
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
if (blocked) {
r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, &m->polkit_registry, error);
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, &m->polkit_registry, error);
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_do_shutdown_or_sleep(
m, message,
NULL,
error);
static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_do_shutdown_or_sleep(
m, message,
NULL,
error);
static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_do_shutdown_or_sleep(
m, message,
"org.freedesktop.login1.suspend",
"org.freedesktop.login1.suspend-multiple-sessions",
"org.freedesktop.login1.suspend-ignore-inhibit",
error);
static int method_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_do_shutdown_or_sleep(
m, message,
"org.freedesktop.login1.hibernate",
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
error);
static int method_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_do_shutdown_or_sleep(
m, message,
"org.freedesktop.login1.hibernate",
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
error);
static int method_can_shutdown_or_sleep(
Manager *m,
InhibitWhat w,
const char *action,
const char *action_multiple_sessions,
const char *action_ignore_inhibit,
const char *sleep_verb,
assert(m);
assert(w >= 0);
if (sleep_verb) {
multiple_sessions = r > 0;
if (multiple_sessions) {
else if (challenge)
if (blocked) {
if (r > 0 && !result)
else if (challenge)
static int method_can_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_can_shutdown_or_sleep(
m, message,
NULL,
error);
static int method_can_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_can_shutdown_or_sleep(
m, message,
NULL,
error);
static int method_can_suspend(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_can_shutdown_or_sleep(
m, message,
"org.freedesktop.login1.suspend",
"org.freedesktop.login1.suspend-multiple-sessions",
"org.freedesktop.login1.suspend-ignore-inhibit",
error);
static int method_can_hibernate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_can_shutdown_or_sleep(
m, message,
"org.freedesktop.login1.hibernate",
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
error);
static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_can_shutdown_or_sleep(
m, message,
"org.freedesktop.login1.hibernate",
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
error);
static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
InhibitWhat w;
assert(m);
if (mm < 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delay inhibitors only supported for shutdown and sleep");
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");
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") :
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
return -ENOMEM;
i->what = w;
r = -ENOMEM;
goto fail;
if (fifo_fd < 0) {
r = fifo_fd;
goto fail;
inhibitor_start(i);
fail:
inhibitor_free(i);
SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
assert(s);
if (!s->started)
sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
r = session_send_create_reply(s, &e);
assert(m);
m->action_what = 0;
if (session) {
if (user) {
assert(m);
if (session)
if (user)
int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *path;
assert(m);
if (!path)
if (session)
if (user)
Iterator i;
int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Iterator i;
char *key;
if (!key)
"/org/freedesktop/login1",
if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
log_info("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
int manager_start_scope(
const char *scope,
const char *slice,
const char *description,
char **job) {
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
r = sd_bus_message_close_container(m);
if (job) {
char *copy;
if (!copy)
return -ENOMEM;
r = sd_bus_call_method(
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
&reply,
if (job) {
char *copy;
if (!copy)
return -ENOMEM;
r = sd_bus_call_method(
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
&reply,
if (job)
if (job) {
char *copy;
if (!copy)
return -ENOMEM;
if (!path)
return -ENOMEM;
r = sd_bus_call_method(
"org.freedesktop.systemd1",
path,
"org.freedesktop.systemd1.Scope",
NULL,
NULL);
int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
return sd_bus_call_method(
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
NULL,
const char *state;
if (!path)
return -ENOMEM;
r = sd_bus_get_property(
"org.freedesktop.systemd1",
path,
"org.freedesktop.systemd1.Unit",
&error,
&reply,
return -EINVAL;
r = sd_bus_get_property(
"org.freedesktop.systemd1",
path,
"org.freedesktop.systemd1.Job",
&error,
&reply,