logind-user.c revision a9c67ea2a24d61640971fc1ca366a3e6c7d75266
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/***
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen This file is part of systemd.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Copyright 2011 Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is free software; you can redistribute it and/or modify it
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen under the terms of the GNU Lesser General Public License as published by
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen (at your option) any later version.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is distributed in the hope that it will be useful, but
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Lesser General Public License for more details.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen You should have received a copy of the GNU Lesser General Public License
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen***/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include <sys/mount.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <string.h>
0a6f50c0afdfc434b492493bd9efab20cbee8623Thomas Hindoe Paaboel Andersen#include <unistd.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <errno.h>
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen#include "util.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "mkdir.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "hashmap.h"
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering#include "strv.h"
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering#include "fileio.h"
a5a807e63a50314e190e9166d8a453cd8dd258e3Zbigniew Jędrzejewski-Szmek#include "path-util.h"
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering#include "special.h"
3df3e884ae1237ef0d4d23b0e80f4ffda95ac135Ronny Chevalier#include "unit-name.h"
958b66ea16deddd794b3a52643bd44633e165eadLennart Poettering#include "bus-util.h"
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering#include "bus-error.h"
4ad7f2761da661853dcc29d542efb4727abb1101Nick Owens#include "conf-parser.h"
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering#include "clean-ipc.h"
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering#include "logind-user.h"
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering#include "smack-util.h"
5f402ae84bbc08fe8de5682e371b3f66c387da52Daniel Mack
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringUser* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering User *u;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u = new0(User, 1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!u)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->name = strdup(name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!u->name)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (asprintf(&u->state_file, "/run/systemd/users/"UID_FMT, uid) < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (hashmap_put(m->users, UID_TO_PTR(uid), u) < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->manager = m;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->uid = uid;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->gid = gid;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return u;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poetteringfail:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u->state_file);
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering free(u->name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringvoid user_free(User *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->in_gc_queue)
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering LIST_REMOVE(gc_queue, u->manager->user_gc_queue, u);
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering while (u->sessions)
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering session_free(u->sessions);
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering if (u->slice) {
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering hashmap_remove(u->manager->user_units, u->slice);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u->slice);
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->service) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering hashmap_remove(u->manager->user_units, u->service);
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering free(u->service);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u->slice_job);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u->service_job);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u->runtime_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering hashmap_remove(u->manager->users, UID_TO_PTR(u->uid));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt free(u->name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u->state_file);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint user_save(User *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_free_ char *temp_path = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u->state_file);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!u->started)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = mkdir_safe_label("/run/systemd/users", 0755, 0, 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = fopen_temporary(u->state_file, &f, &temp_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fchmod(fileno(f), 0644);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "# This is private data. Do not parse.\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "NAME=%s\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "STATE=%s\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->name,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering user_state_to_string(user_get_state(u)));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->runtime_path)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f, "RUNTIME=%s\n", u->runtime_path);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->service)
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen fprintf(f, "SERVICE=%s\n", u->service);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->service_job)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f, "SERVICE_JOB=%s\n", u->service_job);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->slice)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f, "SLICE=%s\n", u->slice);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->slice_job)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f, "SLICE_JOB=%s\n", u->slice_job);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->display)
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen fprintf(f, "DISPLAY=%s\n", u->display->id);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (dual_timestamp_is_set(&u->timestamp))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "REALTIME="USEC_FMT"\n"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "MONOTONIC="USEC_FMT"\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->timestamp.realtime,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->timestamp.monotonic);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->sessions) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Session *i;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering bool first;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs("SESSIONS=", f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering first = true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (first)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering first = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputc(' ', f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs(i->id, f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs("\nSEATS=", f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering first = true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!i->seat)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
3e044c492e3ebe64f4e3175c94f9db8a62557b82Markus Elfring if (first)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering first = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputc(' ', f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs(i->seat->id, f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs("\nACTIVE_SESSIONS=", f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering first = true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!session_is_active(i))
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen continue;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (first)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering first = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputc(' ', f);
cc98b3025eeb89addb76a27390cb2baca4eab8b9Torstein Husebø
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen fputs(i->id, f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs("\nONLINE_SESSIONS=", f);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen first = true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (session_get_state(i) == SESSION_CLOSING)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (first)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering first = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen fputc(' ', f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs(i->id, f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs("\nACTIVE_SEATS=", f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering first = true;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen LIST_FOREACH(sessions_by_user, i, u->sessions) {
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (!session_is_active(i) || !i->seat)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (first)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering first = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputc(' ', f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs(i->seat->id, f);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs("\nONLINE_SEATS=", f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering first = true;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen LIST_FOREACH(sessions_by_user, i, u->sessions) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (session_get_state(i) == SESSION_CLOSING || !i->seat)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (first)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering first = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputc(' ', f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs(i->seat->id, f);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen }
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen fputc('\n', f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fflush(f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (ferror(f) || rename(temp_path, u->state_file) < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = -errno;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen unlink(u->state_file);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering unlink(temp_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersenfinish:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error_errno(r, "Failed to save user data %s: %m", u->state_file);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint user_load(User *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_free_ char *display = NULL, *realtime = NULL, *monotonic = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Session *s = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = parse_env_file(u->state_file, NEWLINE,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "RUNTIME", &u->runtime_path,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "SERVICE", &u->service,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "SERVICE_JOB", &u->service_job,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "SLICE", &u->slice,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "SLICE_JOB", &u->slice_job,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "DISPLAY", &display,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "REALTIME", &realtime,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "MONOTONIC", &monotonic,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r == -ENOENT)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error_errno(r, "Failed to read %s: %m", u->state_file);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (display)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering s = hashmap_get(u->manager->sessions, display);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (s && s->display && display_is_local(s->display))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->display = s;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (realtime) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering unsigned long long l;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (sscanf(realtime, "%llu", &l) > 0)
0014a4ad505d119c7ac4346d9d774c3f17f663a5Lennart Poettering u->timestamp.realtime = l;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (monotonic) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering unsigned long long l;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (sscanf(monotonic, "%llu", &l) > 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->timestamp.monotonic = l;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int user_mkdir_runtime_path(User *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char *p;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = mkdir_safe_label("/run/user", 0755, 0, 0);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return log_error_errno(r, "Failed to create /run/user: %m");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (!u->runtime_path) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (asprintf(&p, "/run/user/" UID_FMT, u->uid) < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return log_oom();
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering } else
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering p = u->runtime_path;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (path_is_mount_point(p, false) <= 0) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering _cleanup_free_ char *t = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering (void) mkdir(p, 0700);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (mac_smack_use())
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = asprintf(&t, "mode=0700,smackfsroot=*,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu", u->uid, u->gid, u->manager->runtime_dir_size);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering else
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = asprintf(&t, "mode=0700,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu", u->uid, u->gid, u->manager->runtime_dir_size);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r < 0) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = log_oom();
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering goto fail;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = mount("tmpfs", p, "tmpfs", MS_NODEV|MS_NOSUID, t);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r < 0) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (errno != EPERM) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = log_error_errno(errno, "Failed to mount per-user tmpfs directory %s: %m", p);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering goto fail;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering /* Lacking permissions, maybe
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering * CAP_SYS_ADMIN-less container? In this case,
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering * just use a normal directory. */
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = chmod_and_chown(p, 0700, u->uid, u->gid);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_error_errno(r, "Failed to change runtime directory ownership and mode: %m");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering goto fail;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering u->runtime_path = p;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poetteringfail:
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (p) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering /* Try to clean up, but ignore errors */
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering (void) rmdir(p);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering free(p);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering u->runtime_path = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poetteringstatic int user_start_slice(User *u) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering char *job;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering int r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(u);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (!u->slice) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering char lu[DECIMAL_STR_MAX(uid_t) + 1], *slice;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering sprintf(lu, UID_FMT, u->uid);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = build_subslice(SPECIAL_USER_SLICE, lu, &slice);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return r;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = manager_start_unit(u->manager, slice, &error, &job);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r < 0) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_error("Failed to start user slice: %s", bus_error_message(&error, r));
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering free(slice);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering } else {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering u->slice = slice;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering free(u->slice_job);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering u->slice_job = job;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (u->slice)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering hashmap_put(u->manager->user_units, u->slice, u);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringstatic int user_start_service(User *u) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt char *job;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering int r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(u);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!u->service) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering char lu[DECIMAL_STR_MAX(uid_t) + 1], *service;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering sprintf(lu, UID_FMT, u->uid);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
8d3d7072e609ef0e0fb37e1d19a29307d58146c3Michal Schmidt service = unit_name_build("user", lu, ".service");
8d3d7072e609ef0e0fb37e1d19a29307d58146c3Michal Schmidt if (!service)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return log_oom();
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = manager_start_unit(u->manager, service, &error, &job);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_error("Failed to start user service: %s", bus_error_message(&error, r));
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering free(service);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering } else {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering u->service = service;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering free(u->service_job);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering u->service_job = job;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (u->service)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering hashmap_put(u->manager->user_units, u->service, u);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering}
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poetteringint user_start(User *u) {
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering int r;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering assert(u);
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering if (u->started)
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering return 0;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering log_debug("New user %s logged in.", u->name);
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering /* Make XDG_RUNTIME_DIR */
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering r = user_mkdir_runtime_path(u);
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering if (r < 0)
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering return r;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering /* Create cgroup */
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering r = user_start_slice(u);
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering if (r < 0)
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering return r;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering /* Spawn user systemd */
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering r = user_start_service(u);
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering if (r < 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!dual_timestamp_is_set(&u->timestamp))
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen dual_timestamp_get(&u->timestamp);
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering u->started = true;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen /* Save new user data */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen user_save(u);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering user_send_signal(u, true);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering}
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poetteringstatic int user_stop_slice(User *u) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering char *job;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen int r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen assert(u);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!u->slice)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = manager_stop_unit(u->manager, u->slice, &error, &job);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (r < 0) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_error("Failed to stop user slice: %s", bus_error_message(&error, r));
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering free(u->slice_job);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering u->slice_job = job;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int user_stop_service(User *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char *job;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!u->service)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = manager_stop_unit(u->manager, u->service, &error, &job);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to stop user service: %s", bus_error_message(&error, r));
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering return r;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen free(u->service_job);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen u->service_job = job;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen}
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poetteringstatic int user_remove_runtime_path(User *u) {
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering int r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering assert(u);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (!u->runtime_path)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return 0;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = rm_rf(u->runtime_path, false, false, false);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (r < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering log_error_errno(r, "Failed to remove runtime directory %s: %m", u->runtime_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Ignore cases where the directory isn't mounted, as that's
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * quite possible, if we lacked the permissions to mount
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * something */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = umount2(u->runtime_path, MNT_DETACH);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0 && errno != EINVAL && errno != ENOENT)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error_errno(errno, "Failed to unmount user runtime directory %s: %m", u->runtime_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering r = rm_rf(u->runtime_path, false, true, false);
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering if (r < 0)
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering log_error_errno(r, "Failed to remove runtime directory %s: %m", u->runtime_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
3e684349c2cead2e6fd2f816c34eb17daba23a49Lennart Poettering free(u->runtime_path);
3e684349c2cead2e6fd2f816c34eb17daba23a49Lennart Poettering u->runtime_path = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
cab5b05903096e1c9cf5575ccc73f89d15c8db69Lennart Poettering return r;
cab5b05903096e1c9cf5575ccc73f89d15c8db69Lennart Poettering}
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poetteringint user_stop(User *u, bool force) {
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering Session *s;
096b6773886bd7a0c8c97aa684b0b67dfae58355Lennart Poettering int r = 0, k;
096b6773886bd7a0c8c97aa684b0b67dfae58355Lennart Poettering assert(u);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering /* Stop jobs have already been queued */
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (u->stopping) {
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering user_save(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering LIST_FOREACH(sessions_by_user, s, u->sessions) {
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering k = session_stop(s, force);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (k < 0)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering r = k;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering /* Kill systemd */
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering k = user_stop_service(u);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (k < 0)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = k;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering /* Kill cgroup */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen k = user_stop_slice(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (k < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = k;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen u->stopping = true;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering user_save(u);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return r;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering}
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poetteringint user_finalize(User *u) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering Session *s;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering int r = 0, k;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering assert(u);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (u->started)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering log_debug("User %s logged out.", u->name);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering LIST_FOREACH(sessions_by_user, s, u->sessions) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering k = session_finalize(s);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (k < 0)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = k;
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering /* Kill XDG_RUNTIME_DIR */
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering k = user_remove_runtime_path(u);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (k < 0)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = k;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering /* Clean SysV + POSIX IPC objects */
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (u->manager->remove_ipc) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering k = clean_ipc(u->uid);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (k < 0)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = k;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering unlink(u->state_file);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering user_add_to_gc_queue(u);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (u->started) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering user_send_signal(u, false);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering u->started = false;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return r;
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt}
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poetteringint user_get_idle_hint(User *u, dual_timestamp *t) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering Session *s;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering bool idle_hint = true;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering dual_timestamp ts = { 0, 0 };
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering assert(u);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering LIST_FOREACH(sessions_by_user, s, u->sessions) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering dual_timestamp k;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering int ih;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering ih = session_get_idle_hint(s, &k);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (ih < 0)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return ih;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (!ih) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (!idle_hint) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (k.monotonic < ts.monotonic)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering ts = k;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering } else {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering idle_hint = false;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering ts = k;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering } else if (idle_hint) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (k.monotonic > ts.monotonic)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering ts = k;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering }
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (t)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering *t = ts;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return idle_hint;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering}
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poetteringint user_check_linger_file(User *u) {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering _cleanup_free_ char *cc = NULL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering char *p = NULL;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering cc = cescape(u->name);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (!cc)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return -ENOMEM;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering p = strjoina("/var/lib/systemd/linger/", cc);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return access(p, F_OK) >= 0;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering}
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersenbool user_check_gc(User *u, bool drop_not_started) {
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen assert(u);
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (drop_not_started && !u->started)
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering return false;
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering if (u->sessions)
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering return true;
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering if (user_check_linger_file(u) > 0)
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering return true;
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering if (u->slice_job && manager_job_is_active(u->manager, u->slice_job))
36a03ca2a8952ca1acb29fbe796210c27ff71affLennart Poettering return true;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (u->service_job && manager_job_is_active(u->manager, u->service_job))
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return true;
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen return false;
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen}
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersenvoid user_add_to_gc_queue(User *u) {
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen assert(u);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (u->in_gc_queue)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen LIST_PREPEND(gc_queue, u->manager->user_gc_queue, u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->in_gc_queue = true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringUserState user_get_state(User *u) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Session *i;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering if (u->stopping)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt return USER_CLOSING;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (u->slice_job || u->service_job)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return USER_OPENING;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering if (u->sessions) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen bool all_closing = true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen LIST_FOREACH(sessions_by_user, i, u->sessions) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen SessionState state;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering state = session_get_state(i);
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering if (state == SESSION_ACTIVE)
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering return USER_ACTIVE;
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering if (state != SESSION_CLOSING)
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering all_closing = false;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen }
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen return all_closing ? USER_CLOSING : USER_ONLINE;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen }
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen if (user_check_linger_file(u) > 0)
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen return USER_LINGERING;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen return USER_CLOSING;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen}
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersenint user_kill(User *u, int signo) {
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen assert(u);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen if (!u->slice)
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen return -ESRCH;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen return manager_kill_unit(u->manager, u->slice, KILL_ALL, signo, NULL);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen}
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poetteringvoid user_elect_display(User *u) {
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek Session *graphical = NULL, *text = NULL, *other = NULL, *s;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek assert(u);
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek /* This elects a primary session for each user, which we call
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek * the "display". We try to keep the assignment stable, but we
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek * "upgrade" to better choices. */
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering LIST_FOREACH(sessions_by_user, s, u->sessions) {
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (s->class != SESSION_USER)
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek continue;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (s->stopping)
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering continue;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (SESSION_TYPE_IS_GRAPHICAL(s->type))
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek graphical = s;
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering else if (s->type == SESSION_TTY)
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek text = s;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek else
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek other = s;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek }
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek if (graphical &&
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek (!u->display ||
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek u->display->class != SESSION_USER ||
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek u->display->stopping ||
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek !SESSION_TYPE_IS_GRAPHICAL(u->display->type))) {
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek u->display = graphical;
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek return;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (text &&
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen (!u->display ||
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering u->display->class != SESSION_USER ||
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->display->stopping ||
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->display->type != SESSION_TTY)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->display = text;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (other &&
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering (!u->display ||
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering u->display->class != SESSION_USER ||
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering u->display->stopping))
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering u->display = other;
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering}
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poetteringstatic const char* const user_state_table[_USER_STATE_MAX] = {
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering [USER_OFFLINE] = "offline",
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering [USER_OPENING] = "opening",
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen [USER_LINGERING] = "lingering",
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen [USER_ONLINE] = "online",
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen [USER_ACTIVE] = "active",
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering [USER_CLOSING] = "closing"
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering};
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart PoetteringDEFINE_STRING_TABLE_LOOKUP(user_state, UserState);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poetteringint config_parse_tmpfs_size(
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering const char* unit,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering const char *filename,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering unsigned line,
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen const char *section,
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen unsigned section_line,
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen const char *lvalue,
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen int ltype,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering const char *rvalue,
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering void *data,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering void *userdata) {
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering size_t *sz = data;
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering const char *e;
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering int r;
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen assert(filename);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen assert(lvalue);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen assert(rvalue);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen assert(data);
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen e = endswith(rvalue, "%");
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen if (e) {
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen unsigned long ul;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen char *f;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen errno = 0;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen ul = strtoul(rvalue, &f, 10);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering if (errno != 0 || f != e) {
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering log_syntax(unit, LOG_ERR, filename, line, errno ? errno : EINVAL, "Failed to parse percentage value, ignoring: %s", rvalue);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering return 0;
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering }
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering if (ul <= 0 || ul >= 100) {
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering log_syntax(unit, LOG_ERR, filename, line, errno ? errno : EINVAL, "Percentage value out of range, ignoring: %s", rvalue);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering return 0;
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering }
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering *sz = PAGE_ALIGN((size_t) ((physical_memory() * (uint64_t) ul) / (uint64_t) 100));
a5a807e63a50314e190e9166d8a453cd8dd258e3Zbigniew Jędrzejewski-Szmek } else {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen off_t o;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = parse_size(rvalue, 1024, &o);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (r < 0 || (off_t) (size_t) o != o) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_syntax(unit, LOG_ERR, filename, line, r < 0 ? -r : ERANGE, "Failed to parse size value, ignoring: %s", rvalue);
4713135eae4f7b6b670a98476fe413edfa1d9f41Zbigniew Jędrzejewski-Szmek return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *sz = PAGE_ALIGN((size_t) o);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen