From db72aea4a952cdfdef51eda03408d7c4a11e7359 Mon Sep 17 00:00:00 2001 From: Corey Hinshaw Date: Sat, 22 Feb 2020 22:44:42 -0500 Subject: Add SetType method to login Session interface --- src/login/logind-dbus.c | 2 +- src/login/logind-session-dbus.c | 34 +++++++++++++++++++++++++++++++++- src/login/logind-session.c | 28 ++++++++++++++++++++++++++++ src/login/logind-session.h | 2 ++ src/login/org.freedesktop.login1.conf | 4 ++++ 5 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 985c58cc63..136ccf1dd9 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -885,7 +885,7 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus if (r < 0) goto fail; - session->type = t; + session->original_type = session->type = t; session->class = c; session->remote = remote; session->vtnr = vtnr; diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c index 69bf0986f2..9a8dbc87bc 100644 --- a/src/login/logind-session-dbus.c +++ b/src/login/logind-session-dbus.c @@ -393,6 +393,32 @@ static int method_release_control(sd_bus_message *message, void *userdata, sd_bu return sd_bus_reply_method_return(message, NULL); } +static int method_set_type(sd_bus_message *message, void *userdata, sd_bus_error *error) { + Session *s = userdata; + const char *t; + SessionType type; + int r; + + assert(message); + assert(s); + + r = sd_bus_message_read(message, "s", &t); + if (r < 0) + return r; + + type = session_type_from_string(t); + if (type < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, + "Invalid session type '%s'", t); + + if (!session_is_controller(s, sd_bus_message_get_sender(message))) + return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You must be in control of this session to set type"); + + session_set_type(s, type); + + return sd_bus_reply_method_return(message, NULL); +} + static int method_take_device(sd_bus_message *message, void *userdata, sd_bus_error *error) { Session *s = userdata; uint32_t major, minor; @@ -574,7 +600,7 @@ const sd_bus_vtable session_vtable[] = { SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Audit", "u", NULL, offsetof(Session, audit_id), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Session, type), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Session, type), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Session, class), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Active", "b", property_get_active, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("State", "s", property_get_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), @@ -633,6 +659,12 @@ const sd_bus_vtable session_vtable[] = { NULL, method_release_control, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("SetType", + "s", + SD_BUS_PARAM(type), + NULL,, + method_set_type, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_NAMES("TakeDevice", "uu", SD_BUS_PARAM(major) diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 48505122a9..5c4149e1bd 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -240,6 +240,9 @@ int session_save(Session *s) { if (s->type >= 0) fprintf(f, "TYPE=%s\n", session_type_to_string(s->type)); + if (s->original_type >= 0) + fprintf(f, "ORIGINAL_TYPE=%s\n", session_type_to_string(s->original_type)); + if (s->class >= 0) fprintf(f, "CLASS=%s\n", session_class_to_string(s->class)); @@ -402,6 +405,7 @@ int session_load(Session *s) { *position = NULL, *leader = NULL, *type = NULL, + *original_type = NULL, *class = NULL, *uid = NULL, *realtime = NULL, @@ -433,6 +437,7 @@ int session_load(Session *s) { "POSITION", &position, "LEADER", &leader, "TYPE", &type, + "ORIGINAL_TYPE", &original_type, "CLASS", &class, "UID", &uid, "REALTIME", &realtime, @@ -529,6 +534,16 @@ int session_load(Session *s) { s->type = t; } + if (original_type) { + SessionType ot; + + ot = session_type_from_string(original_type); + if (ot >= 0) + s->original_type = ot; + } else + /* Pre-v246 compat: initialize original_type if not set in the state file */ + s->original_type = s->type; + if (class) { SessionClass c; @@ -1018,6 +1033,18 @@ void session_set_locked_hint(Session *s, bool b) { session_send_changed(s, "LockedHint", NULL); } +void session_set_type(Session *s, SessionType t) { + assert(s); + + if (s->type == t) + return; + + s->type = t; + session_save(s); + + session_send_changed(s, "Type", NULL); +} + static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents, void *userdata) { Session *s = userdata; @@ -1385,6 +1412,7 @@ void session_drop_controller(Session *s) { return; s->track = sd_bus_track_unref(s->track); + session_set_type(s, s->original_type); session_release_controller(s, false); session_save(s); session_restore_vt(s); diff --git a/src/login/logind-session.h b/src/login/logind-session.h index c51392bef6..b87c731672 100644 --- a/src/login/logind-session.h +++ b/src/login/logind-session.h @@ -61,6 +61,7 @@ struct Session { const char *id; unsigned position; SessionType type; + SessionType original_type; SessionClass class; char *state_file; @@ -135,6 +136,7 @@ int session_get_idle_hint(Session *s, dual_timestamp *t); int session_set_idle_hint(Session *s, bool b); int session_get_locked_hint(Session *s); void session_set_locked_hint(Session *s, bool b); +void session_set_type(Session *s, SessionType t); int session_create_fifo(Session *s); int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error); int session_stop(Session *s, bool force); diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf index 124a25810e..df46e417c8 100644 --- a/src/login/org.freedesktop.login1.conf +++ b/src/login/org.freedesktop.login1.conf @@ -290,6 +290,10 @@ send_interface="org.freedesktop.login1.Session" send_member="ReleaseControl"/> + + -- cgit v1.2.1