1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
5 #include "alloc-util.h"
6 #include "bus-common-errors.h"
7 #include "bus-get-properties.h"
9 #include "bus-polkit.h"
11 #include "devnum-util.h"
13 #include "logind-brightness.h"
14 #include "logind-dbus.h"
15 #include "logind-polkit.h"
16 #include "logind-seat-dbus.h"
17 #include "logind-session-dbus.h"
18 #include "logind-session-device.h"
19 #include "logind-session.h"
20 #include "logind-user-dbus.h"
22 #include "missing_capability.h"
23 #include "path-util.h"
24 #include "signal-util.h"
26 #include "terminal-util.h"
27 #include "user-util.h"
29 static int property_get_user(
32 const char *interface
,
34 sd_bus_message
*reply
,
36 sd_bus_error
*error
) {
38 _cleanup_free_
char *p
= NULL
;
39 Session
*s
= ASSERT_PTR(userdata
);
44 p
= user_bus_path(s
->user
);
48 return sd_bus_message_append(reply
, "(uo)", (uint32_t) s
->user
->user_record
->uid
, p
);
51 static int property_get_name(
54 const char *interface
,
56 sd_bus_message
*reply
,
58 sd_bus_error
*error
) {
60 Session
*s
= ASSERT_PTR(userdata
);
65 return sd_bus_message_append(reply
, "s", s
->user
->user_record
->user_name
);
68 static int property_get_seat(
71 const char *interface
,
73 sd_bus_message
*reply
,
75 sd_bus_error
*error
) {
77 _cleanup_free_
char *p
= NULL
;
78 Session
*s
= ASSERT_PTR(userdata
);
83 p
= s
->seat
? seat_bus_path(s
->seat
) : strdup("/");
87 return sd_bus_message_append(reply
, "(so)", s
->seat
? s
->seat
->id
: "", p
);
90 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type
, session_type
, SessionType
);
91 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class
, session_class
, SessionClass
);
92 static BUS_DEFINE_PROPERTY_GET(property_get_active
, "b", Session
, session_is_active
);
93 static BUS_DEFINE_PROPERTY_GET2(property_get_state
, "s", Session
, session_get_state
, session_state_to_string
);
95 static int property_get_idle_hint(
98 const char *interface
,
100 sd_bus_message
*reply
,
102 sd_bus_error
*error
) {
104 Session
*s
= ASSERT_PTR(userdata
);
109 return sd_bus_message_append(reply
, "b", session_get_idle_hint(s
, NULL
) > 0);
112 static int property_get_idle_since_hint(
115 const char *interface
,
116 const char *property
,
117 sd_bus_message
*reply
,
119 sd_bus_error
*error
) {
121 Session
*s
= ASSERT_PTR(userdata
);
122 dual_timestamp t
= DUAL_TIMESTAMP_NULL
;
129 r
= session_get_idle_hint(s
, &t
);
133 u
= streq(property
, "IdleSinceHint") ? t
.realtime
: t
.monotonic
;
135 return sd_bus_message_append(reply
, "t", u
);
138 static int property_get_locked_hint(
141 const char *interface
,
142 const char *property
,
143 sd_bus_message
*reply
,
145 sd_bus_error
*error
) {
147 Session
*s
= ASSERT_PTR(userdata
);
152 return sd_bus_message_append(reply
, "b", session_get_locked_hint(s
) > 0);
155 int bus_session_method_terminate(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
156 Session
*s
= ASSERT_PTR(userdata
);
161 r
= bus_verify_polkit_async_full(
163 "org.freedesktop.login1.manage",
165 /* interactive= */ false,
166 s
->user
->user_record
->uid
,
167 &s
->manager
->polkit_registry
,
172 return 1; /* Will call us back */
174 r
= session_stop(s
, /* force = */ true);
178 return sd_bus_reply_method_return(message
, NULL
);
181 int bus_session_method_activate(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
182 Session
*s
= ASSERT_PTR(userdata
);
187 r
= check_polkit_chvt(message
, s
->manager
, error
);
191 return 1; /* Will call us back */
193 r
= session_activate(s
);
197 return sd_bus_reply_method_return(message
, NULL
);
200 int bus_session_method_lock(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
201 Session
*s
= ASSERT_PTR(userdata
);
206 r
= bus_verify_polkit_async_full(
208 "org.freedesktop.login1.lock-sessions",
210 /* interactive= */ false,
211 s
->user
->user_record
->uid
,
212 &s
->manager
->polkit_registry
,
217 return 1; /* Will call us back */
219 r
= session_send_lock(s
, strstr(sd_bus_message_get_member(message
), "Lock"));
223 return sd_bus_reply_method_return(message
, NULL
);
226 static int method_set_idle_hint(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
227 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
228 Session
*s
= ASSERT_PTR(userdata
);
234 r
= sd_bus_message_read(message
, "b", &b
);
238 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_EUID
, &creds
);
242 r
= sd_bus_creds_get_euid(creds
, &uid
);
246 if (uid
!= 0 && uid
!= s
->user
->user_record
->uid
)
247 return sd_bus_error_set(error
, SD_BUS_ERROR_ACCESS_DENIED
, "Only owner of session may set idle hint");
249 r
= session_set_idle_hint(s
, b
);
251 return sd_bus_error_set(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Idle hint control is not supported on non-graphical sessions.");
255 return sd_bus_reply_method_return(message
, NULL
);
258 static int method_set_locked_hint(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
259 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
260 Session
*s
= ASSERT_PTR(userdata
);
266 r
= sd_bus_message_read(message
, "b", &b
);
270 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_EUID
, &creds
);
274 r
= sd_bus_creds_get_euid(creds
, &uid
);
278 if (uid
!= 0 && uid
!= s
->user
->user_record
->uid
)
279 return sd_bus_error_set(error
, SD_BUS_ERROR_ACCESS_DENIED
, "Only owner of session may set locked hint");
281 session_set_locked_hint(s
, b
);
283 return sd_bus_reply_method_return(message
, NULL
);
286 int bus_session_method_kill(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
287 Session
*s
= ASSERT_PTR(userdata
);
295 r
= sd_bus_message_read(message
, "si", &swho
, &signo
);
302 who
= kill_who_from_string(swho
);
304 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid kill parameter '%s'", swho
);
307 if (!SIGNAL_VALID(signo
))
308 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid signal %i", signo
);
310 r
= bus_verify_polkit_async_full(
312 "org.freedesktop.login1.manage",
314 /* interactive= */ false,
315 s
->user
->user_record
->uid
,
316 &s
->manager
->polkit_registry
,
321 return 1; /* Will call us back */
323 r
= session_kill(s
, who
, signo
);
327 return sd_bus_reply_method_return(message
, NULL
);
330 static int method_take_control(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
331 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
332 Session
*s
= ASSERT_PTR(userdata
);
338 r
= sd_bus_message_read(message
, "b", &force
);
342 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_EUID
, &creds
);
346 r
= sd_bus_creds_get_euid(creds
, &uid
);
350 if (uid
!= 0 && (force
|| uid
!= s
->user
->user_record
->uid
))
351 return sd_bus_error_set(error
, SD_BUS_ERROR_ACCESS_DENIED
, "Only owner of session may take control");
353 r
= session_set_controller(s
, sd_bus_message_get_sender(message
), force
, true);
357 return sd_bus_reply_method_return(message
, NULL
);
360 static int method_release_control(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
361 Session
*s
= ASSERT_PTR(userdata
);
365 if (!session_is_controller(s
, sd_bus_message_get_sender(message
)))
366 return sd_bus_error_set(error
, BUS_ERROR_NOT_IN_CONTROL
, "You are not in control of this session");
368 session_drop_controller(s
);
370 return sd_bus_reply_method_return(message
, NULL
);
373 static int method_set_type(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
374 Session
*s
= ASSERT_PTR(userdata
);
381 r
= sd_bus_message_read(message
, "s", &t
);
385 type
= session_type_from_string(t
);
387 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
,
388 "Invalid session type '%s'", t
);
390 if (!session_is_controller(s
, sd_bus_message_get_sender(message
)))
391 return sd_bus_error_set(error
, BUS_ERROR_NOT_IN_CONTROL
, "You must be in control of this session to set type");
393 session_set_type(s
, type
);
395 return sd_bus_reply_method_return(message
, NULL
);
398 static int method_set_display(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
399 Session
*s
= ASSERT_PTR(userdata
);
405 r
= sd_bus_message_read(message
, "s", &display
);
409 if (!session_is_controller(s
, sd_bus_message_get_sender(message
)))
410 return sd_bus_error_set(error
, BUS_ERROR_NOT_IN_CONTROL
, "You must be in control of this session to set display");
412 if (!SESSION_TYPE_IS_GRAPHICAL(s
->type
))
413 return sd_bus_error_set(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Setting display is only supported for graphical sessions");
415 r
= session_set_display(s
, display
);
419 return sd_bus_reply_method_return(message
, NULL
);
422 static int method_set_tty(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
423 Session
*s
= ASSERT_PTR(userdata
);
425 _cleanup_free_
char *q
= NULL
;
429 r
= sd_bus_message_read(message
, "h", &fd
);
433 if (!session_is_controller(s
, sd_bus_message_get_sender(message
)))
434 return sd_bus_error_set(error
, BUS_ERROR_NOT_IN_CONTROL
, "You must be in control of this session to set tty");
438 flags
= fcntl(fd
, F_GETFL
, 0);
441 if ((flags
& O_ACCMODE
) != O_RDWR
)
443 if (FLAGS_SET(flags
, O_PATH
))
446 r
= getttyname_malloc(fd
, &q
);
450 r
= session_set_tty(s
, q
);
454 return sd_bus_reply_method_return(message
, NULL
);
457 static int method_take_device(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
458 Session
*s
= ASSERT_PTR(userdata
);
459 uint32_t major
, minor
;
460 _cleanup_(session_device_freep
) SessionDevice
*sd
= NULL
;
466 r
= sd_bus_message_read(message
, "uu", &major
, &minor
);
470 if (!DEVICE_MAJOR_VALID(major
) || !DEVICE_MINOR_VALID(minor
))
471 return sd_bus_error_set(error
, SD_BUS_ERROR_INVALID_ARGS
, "Device major/minor is not valid.");
473 if (!session_is_controller(s
, sd_bus_message_get_sender(message
)))
474 return sd_bus_error_set(error
, BUS_ERROR_NOT_IN_CONTROL
, "You are not in control of this session");
476 dev
= makedev(major
, minor
);
477 sd
= hashmap_get(s
->devices
, &dev
);
479 /* We don't allow retrieving a device multiple times.
480 * The related ReleaseDevice call is not ref-counted.
481 * The caller should use dup() if it requires more
482 * than one fd (it would be functionally
484 return sd_bus_error_set(error
, BUS_ERROR_DEVICE_IS_TAKEN
, "Device already taken");
486 r
= session_device_new(s
, dev
, true, &sd
);
490 r
= session_device_save(sd
);
494 r
= sd_bus_reply_method_return(message
, "hb", sd
->fd
, !sd
->active
);
504 static int method_release_device(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
505 Session
*s
= ASSERT_PTR(userdata
);
506 uint32_t major
, minor
;
513 r
= sd_bus_message_read(message
, "uu", &major
, &minor
);
517 if (!DEVICE_MAJOR_VALID(major
) || !DEVICE_MINOR_VALID(minor
))
518 return sd_bus_error_set(error
, SD_BUS_ERROR_INVALID_ARGS
, "Device major/minor is not valid.");
520 if (!session_is_controller(s
, sd_bus_message_get_sender(message
)))
521 return sd_bus_error_set(error
, BUS_ERROR_NOT_IN_CONTROL
, "You are not in control of this session");
523 dev
= makedev(major
, minor
);
524 sd
= hashmap_get(s
->devices
, &dev
);
526 return sd_bus_error_set(error
, BUS_ERROR_DEVICE_NOT_TAKEN
, "Device not taken");
528 session_device_free(sd
);
531 return sd_bus_reply_method_return(message
, NULL
);
534 static int method_pause_device_complete(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
535 Session
*s
= ASSERT_PTR(userdata
);
536 uint32_t major
, minor
;
543 r
= sd_bus_message_read(message
, "uu", &major
, &minor
);
547 if (!DEVICE_MAJOR_VALID(major
) || !DEVICE_MINOR_VALID(minor
))
548 return sd_bus_error_set(error
, SD_BUS_ERROR_INVALID_ARGS
, "Device major/minor is not valid.");
550 if (!session_is_controller(s
, sd_bus_message_get_sender(message
)))
551 return sd_bus_error_set(error
, BUS_ERROR_NOT_IN_CONTROL
, "You are not in control of this session");
553 dev
= makedev(major
, minor
);
554 sd
= hashmap_get(s
->devices
, &dev
);
556 return sd_bus_error_set(error
, BUS_ERROR_DEVICE_NOT_TAKEN
, "Device not taken");
558 session_device_complete_pause(sd
);
560 return sd_bus_reply_method_return(message
, NULL
);
563 static int method_set_brightness(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
564 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
565 _cleanup_(sd_device_unrefp
) sd_device
*d
= NULL
;
566 const char *subsystem
, *name
, *seat
;
567 Session
*s
= ASSERT_PTR(userdata
);
574 r
= sd_bus_message_read(message
, "ssu", &subsystem
, &name
, &brightness
);
578 if (!STR_IN_SET(subsystem
, "backlight", "leds"))
579 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Subsystem type %s not supported, must be one of 'backlight' or 'leds'.", subsystem
);
580 if (!filename_is_valid(name
))
581 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Not a valid device name %s, refusing.", name
);
584 return sd_bus_error_set(error
, BUS_ERROR_NOT_YOUR_DEVICE
, "Your session has no seat, refusing.");
585 if (s
->seat
->active
!= s
)
586 return sd_bus_error_set(error
, BUS_ERROR_NOT_YOUR_DEVICE
, "Session is not in foreground, refusing.");
588 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_EUID
, &creds
);
592 r
= sd_bus_creds_get_euid(creds
, &uid
);
596 if (uid
!= 0 && uid
!= s
->user
->user_record
->uid
)
597 return sd_bus_error_set(error
, SD_BUS_ERROR_ACCESS_DENIED
, "Only owner of session may change brightness.");
599 r
= sd_device_new_from_subsystem_sysname(&d
, subsystem
, name
);
601 return sd_bus_error_set_errnof(error
, r
, "Failed to open device %s:%s: %m", subsystem
, name
);
603 if (sd_device_get_property_value(d
, "ID_SEAT", &seat
) >= 0 && !streq_ptr(seat
, s
->seat
->id
))
604 return sd_bus_error_setf(error
, BUS_ERROR_NOT_YOUR_DEVICE
, "Device %s:%s does not belong to your seat %s, refusing.", subsystem
, name
, s
->seat
->id
);
606 r
= manager_write_brightness(s
->manager
, d
, brightness
, message
);
613 static int session_object_find(sd_bus
*bus
, const char *path
, const char *interface
, void *userdata
, void **found
, sd_bus_error
*error
) {
614 _cleanup_free_
char *e
= NULL
;
615 sd_bus_message
*message
;
616 Manager
*m
= ASSERT_PTR(userdata
);
626 p
= startswith(path
, "/org/freedesktop/login1/session/");
630 e
= bus_label_unescape(p
);
634 message
= sd_bus_get_current_message(bus
);
636 r
= manager_get_session_from_creds(m
, message
, e
, error
, &session
);
638 sd_bus_error_free(error
);
648 char *session_bus_path(Session
*s
) {
649 _cleanup_free_
char *t
= NULL
;
653 t
= bus_label_escape(s
->id
);
657 return strjoin("/org/freedesktop/login1/session/", t
);
660 static int session_node_enumerator(sd_bus
*bus
, const char *path
, void *userdata
, char ***nodes
, sd_bus_error
*error
) {
661 _cleanup_strv_free_
char **l
= NULL
;
662 sd_bus_message
*message
;
663 Manager
*m
= userdata
;
671 HASHMAP_FOREACH(session
, m
->sessions
) {
674 p
= session_bus_path(session
);
678 r
= strv_consume(&l
, p
);
683 message
= sd_bus_get_current_message(bus
);
685 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*creds
= NULL
;
687 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_SESSION
|SD_BUS_CREDS_OWNER_UID
|SD_BUS_CREDS_AUGMENT
, &creds
);
689 bool may_auto
= false;
692 r
= sd_bus_creds_get_session(creds
, &name
);
694 session
= hashmap_get(m
->sessions
, name
);
696 r
= strv_extend(&l
, "/org/freedesktop/login1/session/self");
707 r
= sd_bus_creds_get_owner_uid(creds
, &uid
);
711 user
= hashmap_get(m
->users
, UID_TO_PTR(uid
));
712 may_auto
= user
&& user
->display
;
717 r
= strv_extend(&l
, "/org/freedesktop/login1/session/auto");
724 *nodes
= TAKE_PTR(l
);
728 int session_send_signal(Session
*s
, bool new_session
) {
729 _cleanup_free_
char *p
= NULL
;
733 p
= session_bus_path(s
);
737 return sd_bus_emit_signal(
739 "/org/freedesktop/login1",
740 "org.freedesktop.login1.Manager",
741 new_session
? "SessionNew" : "SessionRemoved",
745 int session_send_changed(Session
*s
, const char *properties
, ...) {
746 _cleanup_free_
char *p
= NULL
;
754 p
= session_bus_path(s
);
758 l
= strv_from_stdarg_alloca(properties
);
760 return sd_bus_emit_properties_changed_strv(s
->manager
->bus
, p
, "org.freedesktop.login1.Session", l
);
763 int session_send_lock(Session
*s
, bool lock
) {
764 _cleanup_free_
char *p
= NULL
;
768 p
= session_bus_path(s
);
772 return sd_bus_emit_signal(
775 "org.freedesktop.login1.Session",
776 lock
? "Lock" : "Unlock",
780 int session_send_lock_all(Manager
*m
, bool lock
) {
786 HASHMAP_FOREACH(session
, m
->sessions
) {
789 k
= session_send_lock(session
, lock
);
797 static bool session_ready(Session
*s
) {
800 /* Returns true when the session is ready, i.e. all jobs we enqueued for it are done (regardless if successful or not) */
802 return !s
->scope_job
&&
803 !s
->user
->service_job
;
806 int session_send_create_reply(Session
*s
, sd_bus_error
*error
) {
807 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*c
= NULL
;
808 _cleanup_close_
int fifo_fd
= -EBADF
;
809 _cleanup_free_
char *p
= NULL
;
814 /* This is called after the session scope and the user service were successfully created, and finishes where
815 * bus_manager_create_session() left off. */
817 if (!s
->create_message
)
820 if (!sd_bus_error_is_set(error
) && !session_ready(s
))
823 c
= TAKE_PTR(s
->create_message
);
825 return sd_bus_reply_method_error(c
, error
);
827 fifo_fd
= session_create_fifo(s
);
831 r
= session_watch_pidfd(s
);
835 /* Update the session state file before we notify the client about the result. */
838 p
= session_bus_path(s
);
842 log_debug("Sending reply about created session: "
843 "id=%s object_path=%s uid=%u runtime_path=%s "
844 "session_fd=%d seat=%s vtnr=%u",
847 (uint32_t) s
->user
->user_record
->uid
,
848 s
->user
->runtime_path
,
850 s
->seat
? s
->seat
->id
: "",
853 return sd_bus_reply_method_return(
857 s
->user
->runtime_path
,
859 (uint32_t) s
->user
->user_record
->uid
,
860 s
->seat
? s
->seat
->id
: "",
865 static const sd_bus_vtable session_vtable
[] = {
866 SD_BUS_VTABLE_START(0),
868 SD_BUS_PROPERTY("Id", "s", NULL
, offsetof(Session
, id
), SD_BUS_VTABLE_PROPERTY_CONST
),
869 SD_BUS_PROPERTY("User", "(uo)", property_get_user
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
870 SD_BUS_PROPERTY("Name", "s", property_get_name
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
871 BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Session
, timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
872 SD_BUS_PROPERTY("VTNr", "u", NULL
, offsetof(Session
, vtnr
), SD_BUS_VTABLE_PROPERTY_CONST
),
873 SD_BUS_PROPERTY("Seat", "(so)", property_get_seat
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
874 SD_BUS_PROPERTY("TTY", "s", NULL
, offsetof(Session
, tty
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
875 SD_BUS_PROPERTY("Display", "s", NULL
, offsetof(Session
, display
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
876 SD_BUS_PROPERTY("Remote", "b", bus_property_get_bool
, offsetof(Session
, remote
), SD_BUS_VTABLE_PROPERTY_CONST
),
877 SD_BUS_PROPERTY("RemoteHost", "s", NULL
, offsetof(Session
, remote_host
), SD_BUS_VTABLE_PROPERTY_CONST
),
878 SD_BUS_PROPERTY("RemoteUser", "s", NULL
, offsetof(Session
, remote_user
), SD_BUS_VTABLE_PROPERTY_CONST
),
879 SD_BUS_PROPERTY("Service", "s", NULL
, offsetof(Session
, service
), SD_BUS_VTABLE_PROPERTY_CONST
),
880 SD_BUS_PROPERTY("Desktop", "s", NULL
, offsetof(Session
, desktop
), SD_BUS_VTABLE_PROPERTY_CONST
),
881 SD_BUS_PROPERTY("Scope", "s", NULL
, offsetof(Session
, scope
), SD_BUS_VTABLE_PROPERTY_CONST
),
882 SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid
, offsetof(Session
, leader
.pid
), SD_BUS_VTABLE_PROPERTY_CONST
),
883 SD_BUS_PROPERTY("Audit", "u", NULL
, offsetof(Session
, audit_id
), SD_BUS_VTABLE_PROPERTY_CONST
),
884 SD_BUS_PROPERTY("Type", "s", property_get_type
, offsetof(Session
, type
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
885 SD_BUS_PROPERTY("Class", "s", property_get_class
, offsetof(Session
, class), SD_BUS_VTABLE_PROPERTY_CONST
),
886 SD_BUS_PROPERTY("Active", "b", property_get_active
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
887 SD_BUS_PROPERTY("State", "s", property_get_state
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
888 SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
889 SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
890 SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
891 SD_BUS_PROPERTY("LockedHint", "b", property_get_locked_hint
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
893 SD_BUS_METHOD("Terminate",
896 bus_session_method_terminate
,
897 SD_BUS_VTABLE_UNPRIVILEGED
),
898 SD_BUS_METHOD("Activate",
901 bus_session_method_activate
,
902 SD_BUS_VTABLE_UNPRIVILEGED
),
903 SD_BUS_METHOD("Lock",
906 bus_session_method_lock
,
907 SD_BUS_VTABLE_UNPRIVILEGED
),
908 SD_BUS_METHOD("Unlock",
911 bus_session_method_lock
,
912 SD_BUS_VTABLE_UNPRIVILEGED
),
913 SD_BUS_METHOD_WITH_ARGS("SetIdleHint",
914 SD_BUS_ARGS("b", idle
),
916 method_set_idle_hint
,
917 SD_BUS_VTABLE_UNPRIVILEGED
),
918 SD_BUS_METHOD_WITH_ARGS("SetLockedHint",
919 SD_BUS_ARGS("b", locked
),
921 method_set_locked_hint
,
922 SD_BUS_VTABLE_UNPRIVILEGED
),
923 SD_BUS_METHOD_WITH_ARGS("Kill",
924 SD_BUS_ARGS("s", who
, "i", signal_number
),
926 bus_session_method_kill
,
927 SD_BUS_VTABLE_UNPRIVILEGED
),
928 SD_BUS_METHOD_WITH_ARGS("TakeControl",
929 SD_BUS_ARGS("b", force
),
932 SD_BUS_VTABLE_UNPRIVILEGED
),
933 SD_BUS_METHOD("ReleaseControl",
936 method_release_control
,
937 SD_BUS_VTABLE_UNPRIVILEGED
),
938 SD_BUS_METHOD_WITH_ARGS("SetType",
939 SD_BUS_ARGS("s", type
),
942 SD_BUS_VTABLE_UNPRIVILEGED
),
943 SD_BUS_METHOD_WITH_ARGS("SetDisplay",
944 SD_BUS_ARGS("s", display
),
947 SD_BUS_VTABLE_UNPRIVILEGED
),
948 SD_BUS_METHOD_WITH_ARGS("SetTTY",
949 SD_BUS_ARGS("h", tty_fd
),
952 SD_BUS_VTABLE_UNPRIVILEGED
),
953 SD_BUS_METHOD_WITH_ARGS("TakeDevice",
954 SD_BUS_ARGS("u", major
, "u", minor
),
955 SD_BUS_RESULT("h", fd
, "b", inactive
),
957 SD_BUS_VTABLE_UNPRIVILEGED
),
958 SD_BUS_METHOD_WITH_ARGS("ReleaseDevice",
959 SD_BUS_ARGS("u", major
, "u", minor
),
961 method_release_device
,
962 SD_BUS_VTABLE_UNPRIVILEGED
),
963 SD_BUS_METHOD_WITH_ARGS("PauseDeviceComplete",
964 SD_BUS_ARGS("u", major
, "u", minor
),
966 method_pause_device_complete
,
967 SD_BUS_VTABLE_UNPRIVILEGED
),
968 SD_BUS_METHOD_WITH_ARGS("SetBrightness",
969 SD_BUS_ARGS("s", subsystem
, "s", name
, "u", brightness
),
971 method_set_brightness
,
972 SD_BUS_VTABLE_UNPRIVILEGED
),
974 SD_BUS_SIGNAL_WITH_ARGS("PauseDevice",
975 SD_BUS_ARGS("u", major
, "u", minor
, "s", type
),
977 SD_BUS_SIGNAL_WITH_ARGS("ResumeDevice",
978 SD_BUS_ARGS("u", major
, "u", minor
, "h", fd
),
980 SD_BUS_SIGNAL("Lock", NULL
, 0),
981 SD_BUS_SIGNAL("Unlock", NULL
, 0),
986 const BusObjectImplementation session_object
= {
987 "/org/freedesktop/login1/session",
988 "org.freedesktop.login1.Session",
989 .fallback_vtables
= BUS_FALLBACK_VTABLES({session_vtable
, session_object_find
}),
990 .node_enumerator
= session_node_enumerator
,