chiark / gitweb /
logind: implement SetUserLinger() D-Bus call
authorLennart Poettering <lennart@poettering.net>
Tue, 28 Jun 2011 01:52:22 +0000 (03:52 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 28 Jun 2011 01:52:22 +0000 (03:52 +0200)
Makefile.am
src/logind-dbus.c
src/logind-seat.c
src/logind-session.c
src/logind-user.c
src/logind.h
src/org.freedesktop.login1.policy

index dc1a87ed5c138a886b290fa6a60b4ab391777ede..4107787445233343fbc0f673c195bbab87cb7c93 100644 (file)
@@ -870,7 +870,8 @@ systemd_logind_SOURCES = \
         src/logind-acl.c \
         src/dbus-common.c \
         src/dbus-loop.c \
-        src/cgroup-util.c
+        src/cgroup-util.c \
+        src/polkit.c
 
 systemd_logind_CFLAGS = \
        $(AM_CFLAGS) \
index 9b199de20af052c17a1a5f6b6a7de08e9ea8bb00..320bb35efd48b38d88f07cb6e34a081859eed7db 100644 (file)
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
+#include <pwd.h>
 
 #include "logind.h"
 #include "dbus-common.h"
 #include "strv.h"
+#include "polkit.h"
 
 #define BUS_MANAGER_INTERFACE                                           \
         " <interface name=\"org.freedesktop.login1.Manager\">\n"        \
         "  <method name=\"TerminateSeat\">\n"                           \
         "   <arg name=\"id\" type=\"s\" direction=\"in\"/>\n"           \
         "  </method>\n"                                                 \
+        "  <method name=\"SetUserLinger\">\n"                           \
+        "   <arg name=\"uid\" type=\"u\" direction=\"in\"/>\n"          \
+        "   <arg name=\"b\" type=\"b\" direction=\"in\"/>\n"            \
+        "   <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n"  \
+        "  </method>\n"                                                 \
         "  <signal name=\"SessionNew\">\n"                              \
         "   <arg name=\"id\" type=\"s\"/>\n"                            \
         "   <arg name=\"path\" type=\"o\"/>\n"                          \
@@ -888,6 +895,57 @@ static DBusHandlerResult manager_message_handler(
                 if (!reply)
                         goto oom;
 
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "SetUserLinger")) {
+                uint32_t uid;
+                struct passwd *pw;
+                dbus_bool_t b, interactive;
+                char *path;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_UINT32, &uid,
+                                    DBUS_TYPE_BOOLEAN, &b,
+                                    DBUS_TYPE_BOOLEAN, &interactive,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                errno = 0;
+                pw = getpwuid(uid);
+                if (!pw)
+                        return bus_send_error_reply(connection, message, NULL, errno ? -errno : -EINVAL);
+
+                r = verify_polkit(connection, message, "org.freedesktop.login1.set-user-linger", interactive, &error);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+                r = safe_mkdir("/var/lib/systemd/linger", 0755, 0, 0);
+                if (r < 0)
+                        return bus_send_error_reply(connection, message, &error, r);
+
+                path = strappend("/var/lib/systemd/linger/", pw->pw_name);
+                if (!path)
+                        goto oom;
+
+                if (b) {
+                        r = touch(path);
+                        free(path);
+
+                        if (r < 0)
+                                return bus_send_error_reply(connection, message, &error, r);
+                } else {
+                        r = unlink(path);
+                        free(path);
+
+                        if (r < 0 && errno != ENOENT)
+                                return bus_send_error_reply(connection, message, &error, -errno);
+                }
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+
         } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
                 char *introspection = NULL;
                 FILE *f;
index ed67bc9eea8d4fc89a354e97d02cd67e941c6545..11b3a65b64354700746515bb653d146834d3df9e 100644 (file)
@@ -253,11 +253,15 @@ int seat_set_active(Seat *s, Session *session) {
 
         seat_save(s);
 
-        if (session)
+        if (session) {
                 session_save(session);
+                user_save(session->user);
+        }
 
-        if (old_active)
+        if (old_active) {
                 session_save(old_active);
+                user_save(old_active->user);
+        }
 
         return 0;
 }
@@ -340,11 +344,11 @@ int seat_start(Seat *s) {
         /* Read current VT */
         seat_read_active_vt(s);
 
+        s->started = true;
+
         /* Save seat data */
         seat_save(s);
 
-        s->started = true;
-
         seat_send_signal(s, true);
 
         return 0;
index 8e35e09069c4b503035375238d2eee4ae2dca04d..d68423bdcfbf80bb741d9d8e169bb4e75327fde9 100644 (file)
@@ -328,7 +328,6 @@ int session_activate(Session *s) {
         return seat_apply_acls(s->seat, old_active);
 }
 
-
 static int session_link_x11_socket(Session *s) {
         char *t, *f, *c;
         size_t k;
@@ -520,10 +519,13 @@ int session_start(Session *s) {
 
         /* Save session data */
         session_save(s);
+        user_save(s->user);
 
         session_send_signal(s, true);
 
         if (s->seat) {
+                seat_save(s->seat);
+
                 if (s->seat->active == s)
                         seat_send_changed(s->seat, "Sessions\0ActiveSession\0");
                 else
index a4f78869a31d1078342fdaa847c5ab506b537448..177e88200a9f49d4309a1dd621eb496faffe2aa5 100644 (file)
@@ -285,13 +285,13 @@ int user_start(User *u) {
         if (r < 0)
                 return r;
 
-        /* Save new user data */
-        user_save(u);
-
         dual_timestamp_get(&u->timestamp);
 
         u->started = true;
 
+        /* Save new user data */
+        user_save(u);
+
         user_send_signal(u, true);
 
         return 0;
index 8c9bbf10802ee9803303f0fab250c91b0a7354fd..88a7c1808c74c3d24d5caa449a18cb6e20693fdb 100644 (file)
@@ -38,7 +38,6 @@
  * direct client API
  * add configuration file
  * D-Bus method: AttachDevices(seat, devices[]);
- * D-Bus method: SetLinger(user, bool b);
  *
  * non-local X11 server
  * reboot/shutdown halt management
index b81e4888ffa288e2af0c6f4e0b75e535c05f6d15..da66998e516c54d47eb7925d14d8851b33c919e3 100644 (file)
@@ -16,7 +16,7 @@
         <vendor>The systemd Project</vendor>
         <vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
 
-        <action id="org.freedesktop.login1.enable-user-linger">
+        <action id="org.freedesktop.login1.set-user-linger">
                 <description>Allow non-logged-in users to run programs</description>
                 <message>Authentication is required to allow a non-logged-in user to run programs</message>
                 <defaults>