logind-session-dbus.c revision 19befb2d5fc087f96e40ddc432b2cc9385666209
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering This file is part of systemd.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering Copyright 2011 Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering systemd is free software; you can redistribute it and/or modify it
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering under the terms of the GNU Lesser General Public License as published by
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering (at your option) any later version.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering systemd is distributed in the hope that it will be useful, but
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering Lesser General Public License for more details.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering You should have received a copy of the GNU Lesser General Public License
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_message_append(reply, "(uo)", (uint32_t) s->user->uid, p);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_message_append(reply, "s", s->user->name);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering p = s->seat ? seat_bus_path(s->seat) : strdup("/");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_message_append(reply, "(so)", s->seat ? s->seat->id : "", p);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringstatic BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, session_type, SessionType);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringstatic BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, session_class, SessionClass);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_message_append(reply, "b", session_is_active(s));
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_message_append(reply, "s", session_state_to_string(session_get_state(s)));
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_message_append(reply, "b", session_get_idle_hint(s, NULL) > 0);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering u = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_message_append(reply, "t", u);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringstatic int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_reply_method_return(message, NULL);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringstatic int method_activate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_reply_method_return(message, NULL);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringstatic int method_lock(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering r = session_send_lock(s, streq(sd_bus_message_get_member(message), "Lock"));
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_reply_method_return(message, NULL);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poetteringstatic int method_set_idle_hint(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering r = sd_bus_message_read(message, "b", &b);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session my set idle hint");
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return sd_bus_reply_method_return(message, NULL);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poetteringstatic int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering r = sd_bus_message_read(message, "si", &swho, &signo);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return sd_bus_reply_method_return(message, NULL);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poetteringstatic int method_take_control(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering r = sd_bus_message_read(message, "b", &force);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (uid != 0 && (force || uid != s->user->uid))
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may take control");
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering r = session_set_controller(s, sd_bus_message_get_sender(message), force);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return sd_bus_reply_method_return(message, NULL);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poetteringstatic int method_release_control(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (!session_is_controller(s, sd_bus_message_get_sender(message)))
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_reply_method_return(message, NULL);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringstatic int method_take_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering r = sd_bus_message_read(message, "uu", &major, &minor);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (!session_is_controller(s, sd_bus_message_get_sender(message)))
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering /* We don't allow retrieving a device multiple times.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering * The related ReleaseDevice call is not ref-counted.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering * The caller should use dup() if it requires more
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering * than one fd (it would be functionally
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering * equivalent). */
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_DEVICE_IS_TAKEN, "Device already taken");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering r = sd_bus_reply_method_return(message, "hb", sd->fd, !sd->active);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringstatic int method_release_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering r = sd_bus_message_read(message, "uu", &major, &minor);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (!session_is_controller(s, sd_bus_message_get_sender(message)))
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_DEVICE_NOT_TAKEN, "Device not taken");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_reply_method_return(message, NULL);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringstatic int method_pause_device_complete(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering r = sd_bus_message_read(message, "uu", &major, &minor);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (!session_is_controller(s, sd_bus_message_get_sender(message)))
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_DEVICE_NOT_TAKEN, "Device not taken");
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return sd_bus_reply_method_return(message, NULL);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Session, id), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("User", "(uo)", property_get_user, 0, SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Session, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("VTNr", "u", NULL, offsetof(Session, vtnr), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("Seat", "(so)", property_get_seat, 0, SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("TTY", "s", NULL, offsetof(Session, tty), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("Display", "s", NULL, offsetof(Session, display), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("Remote", "b", bus_property_get_bool, offsetof(Session, remote), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("RemoteHost", "s", NULL, offsetof(Session, remote_host), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("RemoteUser", "s", NULL, offsetof(Session, remote_user), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Session, service), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("Desktop", "s", NULL, offsetof(Session, desktop), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("Audit", "u", NULL, offsetof(Session, audit_id), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Session, type), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Session, class), SD_BUS_VTABLE_PROPERTY_CONST),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("Active", "b", property_get_active, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_METHOD("Terminate", NULL, NULL, method_terminate, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_METHOD("Activate", NULL, NULL, method_activate, SD_BUS_VTABLE_UNPRIVILEGED),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_METHOD("Lock", NULL, NULL, method_lock, 0),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_METHOD("Unlock", NULL, NULL, method_lock, 0),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_METHOD("SetIdleHint", "b", NULL, method_set_idle_hint, SD_BUS_VTABLE_UNPRIVILEGED),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering SD_BUS_METHOD("Kill", "si", NULL, method_kill, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
SD_BUS_METHOD("PauseDeviceComplete", "uu", NULL, method_pause_device_complete, SD_BUS_VTABLE_UNPRIVILEGED),
int session_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
assert(m);
if (!message)
e = bus_label_unescape(p);
return -ENOMEM;
if (!session)
assert(s);
return NULL;
int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
Iterator i;
return -ENOMEM;
r = strv_consume(&l, p);
*nodes = l;
l = NULL;
assert(s);
p = session_bus_path(s);
return -ENOMEM;
return sd_bus_emit_signal(
"/org/freedesktop/login1",
assert(s);
if (!s->started)
p = session_bus_path(s);
return -ENOMEM;
return sd_bus_emit_properties_changed_strv(s->manager->bus, p, "org.freedesktop.login1.Session", l);
assert(s);
p = session_bus_path(s);
return -ENOMEM;
return sd_bus_emit_signal(
NULL);
Iterator i;
assert(m);
assert(s);
if (!s->create_message)
c = s->create_message;
if (error)
if (fifo_fd < 0)
return fifo_fd;
session_save(s);
p = session_bus_path(s);
return -ENOMEM;
s->id,
return sd_bus_reply_method_return(
s->id,