]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Add SetType method to login Session interface
authorCorey Hinshaw <corey@electrickite.org>
Sun, 23 Feb 2020 03:44:42 +0000 (22:44 -0500)
committerLennart Poettering <lennart@poettering.net>
Thu, 30 Apr 2020 19:29:26 +0000 (21:29 +0200)
src/login/logind-dbus.c
src/login/logind-session-dbus.c
src/login/logind-session.c
src/login/logind-session.h
src/login/org.freedesktop.login1.conf

index 985c58cc63ff068fb7498ac8cfa5a40c60e07e71..136ccf1dd9bc7155eacd938a5cabfc7d3747ac69 100644 (file)
@@ -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;
index 69bf0986f2f2cfda950209309dda2f276f7ed4f6..9a8dbc87bc307239f1bba7fda6e8ebbae7bd8720 100644 (file)
@@ -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)
index 48505122a9decf670e04c1ea6401cc97131b8e1d..5c4149e1bd377328496ab2c423fe7b47bdeb3562 100644 (file)
@@ -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);
index c51392bef655ef533c8d5ed95313aeabab69d269..b87c7316721353360db6a7df0c3b4198e8726d8f 100644 (file)
@@ -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);
index 124a25810e313f2ab13c4d13f4b0fd4ad494dcc2..df46e417c8fc7baa59a02b878de4bacb4c1a5fd3 100644 (file)
                        send_interface="org.freedesktop.login1.Session"
                        send_member="ReleaseControl"/>
 
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Session"
+                       send_member="SetType"/>
+
                 <allow send_destination="org.freedesktop.login1"
                        send_interface="org.freedesktop.login1.Session"
                        send_member="TakeDevice"/>