diff options
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | src/logind-dbus.c | 58 | ||||
-rw-r--r-- | src/logind-seat.c | 12 | ||||
-rw-r--r-- | src/logind-session.c | 4 | ||||
-rw-r--r-- | src/logind-user.c | 6 | ||||
-rw-r--r-- | src/logind.h | 1 | ||||
-rw-r--r-- | src/org.freedesktop.login1.policy | 2 |
7 files changed, 75 insertions, 11 deletions
diff --git a/Makefile.am b/Makefile.am index dc1a87ed5c..4107787445 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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) \ diff --git a/src/logind-dbus.c b/src/logind-dbus.c index 9b199de20a..320bb35efd 100644 --- a/src/logind-dbus.c +++ b/src/logind-dbus.c @@ -22,10 +22,12 @@ #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" \ @@ -82,6 +84,11 @@ " <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; diff --git a/src/logind-seat.c b/src/logind-seat.c index ed67bc9eea..11b3a65b64 100644 --- a/src/logind-seat.c +++ b/src/logind-seat.c @@ -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; diff --git a/src/logind-session.c b/src/logind-session.c index 8e35e09069..d68423bdcf 100644 --- a/src/logind-session.c +++ b/src/logind-session.c @@ -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 diff --git a/src/logind-user.c b/src/logind-user.c index a4f78869a3..177e88200a 100644 --- a/src/logind-user.c +++ b/src/logind-user.c @@ -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; diff --git a/src/logind.h b/src/logind.h index 8c9bbf1080..88a7c1808c 100644 --- a/src/logind.h +++ b/src/logind.h @@ -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 diff --git a/src/org.freedesktop.login1.policy b/src/org.freedesktop.login1.policy index b81e4888ff..da66998e51 100644 --- a/src/org.freedesktop.login1.policy +++ b/src/org.freedesktop.login1.policy @@ -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> |