]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/login/logind-session-dbus.c
Add SetType method to login Session interface
[thirdparty/systemd.git] / src / login / logind-session-dbus.c
index 872b9a86d98074e655bb160e4a3e295e512c3570..9a8dbc87bc307239f1bba7fda6e8ebbae7bd8720 100644 (file)
@@ -1,11 +1,11 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include <errno.h>
-#include <string.h>
 
 #include "alloc-util.h"
 #include "bus-common-errors.h"
 #include "bus-label.h"
+#include "bus-polkit.h"
 #include "bus-util.h"
 #include "fd-util.h"
 #include "logind-brightness.h"
@@ -44,7 +44,7 @@ static int property_get_user(
         if (!p)
                 return -ENOMEM;
 
-        return sd_bus_message_append(reply, "(uo)", (uint32_t) s->user->uid, p);
+        return sd_bus_message_append(reply, "(uo)", (uint32_t) s->user->user_record->uid, p);
 }
 
 static int property_get_name(
@@ -62,7 +62,7 @@ static int property_get_name(
         assert(reply);
         assert(s);
 
-        return sd_bus_message_append(reply, "s", s->user->name);
+        return sd_bus_message_append(reply, "s", s->user->user_record->user_name);
 }
 
 static int property_get_seat(
@@ -169,7 +169,7 @@ int bus_session_method_terminate(sd_bus_message *message, void *userdata, sd_bus
                         "org.freedesktop.login1.manage",
                         NULL,
                         false,
-                        s->user->uid,
+                        s->user->user_record->uid,
                         &s->manager->polkit_registry,
                         error);
         if (r < 0)
@@ -191,6 +191,20 @@ int bus_session_method_activate(sd_bus_message *message, void *userdata, sd_bus_
         assert(message);
         assert(s);
 
+        r = bus_verify_polkit_async(
+                        message,
+                        CAP_SYS_ADMIN,
+                        "org.freedesktop.login1.chvt",
+                        NULL,
+                        false,
+                        UID_INVALID,
+                        &s->manager->polkit_registry,
+                        error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* Will call us back */
+
         r = session_activate(s);
         if (r < 0)
                 return r;
@@ -211,7 +225,7 @@ int bus_session_method_lock(sd_bus_message *message, void *userdata, sd_bus_erro
                         "org.freedesktop.login1.lock-sessions",
                         NULL,
                         false,
-                        s->user->uid,
+                        s->user->user_record->uid,
                         &s->manager->polkit_registry,
                         error);
         if (r < 0)
@@ -247,10 +261,14 @@ static int method_set_idle_hint(sd_bus_message *message, void *userdata, sd_bus_
         if (r < 0)
                 return r;
 
-        if (uid != 0 && uid != s->user->uid)
+        if (uid != 0 && uid != s->user->user_record->uid)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may set idle hint");
 
-        session_set_idle_hint(s, b);
+        r = session_set_idle_hint(s, b);
+        if (r == -ENOTTY)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Idle hint control is not supported on non-graphical sessions.");
+        if (r < 0)
+                return r;
 
         return sd_bus_reply_method_return(message, NULL);
 }
@@ -276,7 +294,7 @@ static int method_set_locked_hint(sd_bus_message *message, void *userdata, sd_bu
         if (r < 0)
                 return r;
 
-        if (uid != 0 && uid != s->user->uid)
+        if (uid != 0 && uid != s->user->user_record->uid)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may set locked hint");
 
         session_set_locked_hint(s, b);
@@ -315,7 +333,7 @@ int bus_session_method_kill(sd_bus_message *message, void *userdata, sd_bus_erro
                         "org.freedesktop.login1.manage",
                         NULL,
                         false,
-                        s->user->uid,
+                        s->user->user_record->uid,
                         &s->manager->polkit_registry,
                         error);
         if (r < 0)
@@ -351,7 +369,7 @@ static int method_take_control(sd_bus_message *message, void *userdata, sd_bus_e
         if (r < 0)
                 return r;
 
-        if (uid != 0 && (force || uid != s->user->uid))
+        if (uid != 0 && (force || uid != s->user->user_record->uid))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may take control");
 
         r = session_set_controller(s, sd_bus_message_get_sender(message), force, true);
@@ -375,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;
@@ -520,7 +564,7 @@ static int method_set_brightness(sd_bus_message *message, void *userdata, sd_bus
         if (r < 0)
                 return r;
 
-        if (uid != 0 && uid != s->user->uid)
+        if (uid != 0 && uid != s->user->user_record->uid)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may change brightness.");
 
         r = sd_device_new_from_subsystem_sysname(&d, subsystem, name);
@@ -556,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),
@@ -565,22 +609,106 @@ const sd_bus_vtable session_vtable[] = {
         SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("LockedHint", "b", property_get_locked_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
 
-        SD_BUS_METHOD("Terminate", NULL, NULL, bus_session_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("Activate", NULL, NULL, bus_session_method_activate, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("Lock", NULL, NULL, bus_session_method_lock, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("Unlock", NULL, NULL, bus_session_method_lock, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("SetIdleHint", "b", NULL, method_set_idle_hint, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("SetLockedHint", "b", NULL, method_set_locked_hint, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("Kill", "si", NULL, bus_session_method_kill, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("TakeControl", "b", NULL, method_take_control, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("ReleaseControl", NULL, NULL, method_release_control, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("TakeDevice", "uu", "hb", method_take_device, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("ReleaseDevice", "uu", NULL, method_release_device, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("PauseDeviceComplete", "uu", NULL, method_pause_device_complete, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("SetBrightness", "ssu", NULL, method_set_brightness, SD_BUS_VTABLE_UNPRIVILEGED),
-
-        SD_BUS_SIGNAL("PauseDevice", "uus", 0),
-        SD_BUS_SIGNAL("ResumeDevice", "uuh", 0),
+        SD_BUS_METHOD("Terminate",
+                      NULL,
+                      NULL,
+                      bus_session_method_terminate,
+                      SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("Activate",
+                      NULL,
+                      NULL,
+                      bus_session_method_activate,
+                      SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("Lock",
+                      NULL,
+                      NULL,
+                      bus_session_method_lock,
+                      SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("Unlock",
+                      NULL,
+                      NULL,
+                      bus_session_method_lock,
+                      SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("SetIdleHint",
+                                 "b",
+                                 SD_BUS_PARAM(idle),
+                                 NULL,,
+                                 method_set_idle_hint,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("SetLockedHint",
+                                 "b",
+                                 SD_BUS_PARAM(locked),
+                                 NULL,,
+                                 method_set_locked_hint,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("Kill",
+                                 "si",
+                                 SD_BUS_PARAM(who)
+                                 SD_BUS_PARAM(signal_number),
+                                 NULL,,
+                                 bus_session_method_kill,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("TakeControl",
+                                 "b",
+                                 SD_BUS_PARAM(force),
+                                 NULL,,
+                                 method_take_control,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("ReleaseControl",
+                      NULL,
+                      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)
+                                 SD_BUS_PARAM(minor),
+                                 "hb",
+                                 SD_BUS_PARAM(fd)
+                                 SD_BUS_PARAM(inactive),
+                                 method_take_device,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("ReleaseDevice",
+                                 "uu",
+                                 SD_BUS_PARAM(major)
+                                 SD_BUS_PARAM(minor),
+                                 NULL,,
+                                 method_release_device,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("PauseDeviceComplete",
+                                 "uu",
+                                 SD_BUS_PARAM(major)
+                                 SD_BUS_PARAM(minor),
+                                 NULL,,
+                                 method_pause_device_complete,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_NAMES("SetBrightness",
+                                 "ssu",
+                                 SD_BUS_PARAM(subsystem)
+                                 SD_BUS_PARAM(name)
+                                 SD_BUS_PARAM(brightness),
+                                 NULL,,
+                                 method_set_brightness,
+                                 SD_BUS_VTABLE_UNPRIVILEGED),
+
+        SD_BUS_SIGNAL_WITH_NAMES("PauseDevice",
+                                 "uus",
+                                 SD_BUS_PARAM(major)
+                                 SD_BUS_PARAM(minor)
+                                 SD_BUS_PARAM(type),
+                                 0),
+        SD_BUS_SIGNAL_WITH_NAMES("ResumeDevice",
+                                 "uuh",
+                                 SD_BUS_PARAM(major)
+                                 SD_BUS_PARAM(minor)
+                                 SD_BUS_PARAM(fd),
+                                 0),
         SD_BUS_SIGNAL("Lock", NULL, 0),
         SD_BUS_SIGNAL("Unlock", NULL, 0),
 
@@ -819,7 +947,7 @@ int session_send_create_reply(Session *s, sd_bus_error *error) {
                   "session_fd=%d seat=%s vtnr=%u",
                   s->id,
                   p,
-                  (uint32_t) s->user->uid,
+                  (uint32_t) s->user->user_record->uid,
                   s->user->runtime_path,
                   fifo_fd,
                   s->seat ? s->seat->id : "",
@@ -831,7 +959,7 @@ int session_send_create_reply(Session *s, sd_bus_error *error) {
                         p,
                         s->user->runtime_path,
                         fifo_fd,
-                        (uint32_t) s->user->uid,
+                        (uint32_t) s->user->user_record->uid,
                         s->seat ? s->seat->id : "",
                         (uint32_t) s->vtnr,
                         false);