summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--src/logind-dbus.c58
-rw-r--r--src/logind-seat.c12
-rw-r--r--src/logind-session.c4
-rw-r--r--src/logind-user.c6
-rw-r--r--src/logind.h1
-rw-r--r--src/org.freedesktop.login1.policy2
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>