chiark / gitweb /
logind: save /run/systemd/users/UID before starting user@.service
[elogind.git] / src / login / logind-user.c
index c0b473930db0bf71e69861de2e60ec5b552c2a39..21d7268120a9b115ce621951d8447cc86370a3c1 100644 (file)
 #include "bus-error.h"
 #include "conf-parser.h"
 #include "clean-ipc.h"
-#include "logind-user.h"
 #include "smack-util.h"
 #include "formats-util.h"
+#include "label.h"
+#include "logind-user.h"
 
 User* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) {
         User *u;
@@ -105,7 +106,7 @@ void user_free(User *u) {
         free(u);
 }
 
-int user_save(User *u) {
+static int user_save_internal(User *u) {
         _cleanup_free_ char *temp_path = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         int r;
@@ -113,9 +114,6 @@ int user_save(User *u) {
         assert(u);
         assert(u->state_file);
 
-        if (!u->started)
-                return 0;
-
         r = mkdir_safe_label("/run/systemd/users", 0755, 0, 0);
         if (r < 0)
                 goto finish;
@@ -258,6 +256,15 @@ finish:
         return r;
 }
 
+int user_save(User *u) {
+        assert(u);
+
+        if (!u->started)
+                return 0;
+
+        return user_save_internal (u);
+}
+
 int user_load(User *u) {
         _cleanup_free_ char *display = NULL, *realtime = NULL, *monotonic = NULL;
         Session *s = NULL;
@@ -323,7 +330,7 @@ static int user_mkdir_runtime_path(User *u) {
         if (path_is_mount_point(p, 0) <= 0) {
                 _cleanup_free_ char *t = NULL;
 
-                (void) mkdir(p, 0700);
+                (void) mkdir_label(p, 0700);
 
                 if (mac_smack_use())
                         r = asprintf(&t, "mode=0700,smackfsroot=*,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu", u->uid, u->gid, u->manager->runtime_dir_size);
@@ -351,6 +358,10 @@ static int user_mkdir_runtime_path(User *u) {
                                 goto fail;
                         }
                 }
+
+                r = label_fix(p, false, false);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to fix label of '%s', ignoring: %m", p);
         }
 
         u->runtime_path = p;
@@ -453,6 +464,12 @@ int user_start(User *u) {
         if (r < 0)
                 return r;
 
+        /* Save the user data so far, because pam_systemd will read the
+         * XDG_RUNTIME_DIR out of it while starting up systemd --user.
+         * We need to do user_save_internal() because we have not
+         * "officially" started yet. */
+        user_save_internal(u);
+
         /* Spawn user systemd */
         r = user_start_service(u);
         if (r < 0)
@@ -619,7 +636,7 @@ int user_finalize(User *u) {
 int user_get_idle_hint(User *u, dual_timestamp *t) {
         Session *s;
         bool idle_hint = true;
-        dual_timestamp ts = { 0, 0 };
+        dual_timestamp ts = DUAL_TIMESTAMP_NULL;
 
         assert(u);
 
@@ -704,7 +721,7 @@ UserState user_get_state(User *u) {
         if (u->stopping)
                 return USER_CLOSING;
 
-        if (u->slice_job || u->service_job)
+        if (!u->started || u->slice_job || u->service_job)
                 return USER_OPENING;
 
         if (u->sessions) {
@@ -763,6 +780,9 @@ static int elect_display_compare(Session *s1, Session *s2) {
          * is preferred.
          *
          * s1 or s2 may be NULL. */
+        if (!s1 && !s2)
+                return 0;
+
         if ((s1 == NULL) != (s2 == NULL))
                 return (s1 == NULL) - (s2 == NULL);