summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Hinshaw <corey@electrickite.org>2020-02-22 22:44:42 -0500
committerLennart Poettering <lennart@poettering.net>2020-04-30 21:29:26 +0200
commitdb72aea4a952cdfdef51eda03408d7c4a11e7359 (patch)
treeb4a065c1825dcba3b3d351a17f208da89a2d6fca
parent9dcd43b14927fe6f9182a252213dbf182d9d8e01 (diff)
downloadsystemd-db72aea4a952cdfdef51eda03408d7c4a11e7359.tar.gz
Add SetType method to login Session interface
-rw-r--r--src/login/logind-dbus.c2
-rw-r--r--src/login/logind-session-dbus.c34
-rw-r--r--src/login/logind-session.c28
-rw-r--r--src/login/logind-session.h2
-rw-r--r--src/login/org.freedesktop.login1.conf4
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
@@ -292,6 +292,10 @@
<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"/>
<allow send_destination="org.freedesktop.login1"