logind-user.c revision d0af76e68a5bab2e4fd9674b1c64a9f38d7afe97
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering/***
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering This file is part of systemd.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering Copyright 2011 Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering systemd is free software; you can redistribute it and/or modify it
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering under the terms of the GNU Lesser General Public License as published by
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering (at your option) any later version.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering systemd is distributed in the hope that it will be useful, but
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering Lesser General Public License for more details.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering You should have received a copy of the GNU Lesser General Public License
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering***/
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include <string.h>
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include <unistd.h>
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include <errno.h>
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "util.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "mkdir.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "cgroup-util.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "hashmap.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "strv.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "fileio.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "special.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "unit-name.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "dbus-common.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering#include "logind-user.h"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart PoetteringUser* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering User *u;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(m);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u = new0(User, 1);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!u)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->name = strdup(name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!u->name)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering goto fail;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (asprintf(&u->state_file, "/run/systemd/users/%lu", (unsigned long) uid) < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering goto fail;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (hashmap_put(m->users, ULONG_TO_PTR((unsigned long) uid), u) < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering goto fail;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->manager = m;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->uid = uid;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->gid = gid;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return u;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringfail:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u->state_file);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u->name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringvoid user_free(User *u) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (u->in_gc_queue)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering LIST_REMOVE(User, gc_queue, u->manager->user_gc_queue, u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering while (u->sessions)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering session_free(u->sessions);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (u->slice) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering hashmap_remove(u->manager->user_units, u->slice);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u->slice);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (u->service) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering hashmap_remove(u->manager->user_units, u->service);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u->service);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u->slice_job);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u->service_job);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u->runtime_path);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering hashmap_remove(u->manager->users, ULONG_TO_PTR((unsigned long) u->uid));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u->name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u->state_file);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringint user_save(User *u) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_free_ char *temp_path = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(u->state_file);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!u->started)
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = mkdir_safe_label("/run/systemd/users", 0755, 0, 0);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering goto finish;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = fopen_temporary(u->state_file, &f, &temp_path);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering goto finish;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering fchmod(fileno(f), 0644);
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering fprintf(f,
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering "# This is private data. Do not parse.\n"
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering "NAME=%s\n"
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "STATE=%s\n",
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->name,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering user_state_to_string(user_get_state(u)));
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (u->runtime_path)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fprintf(f, "RUNTIME=%s\n", u->runtime_path);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (u->service)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fprintf(f, "SERVICE=%s\n", u->service);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (u->service_job)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fprintf(f, "SERVICE_JOB=%s\n", u->service_job);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (u->slice)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fprintf(f, "SLICE=%s\n", u->slice);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (u->slice_job)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fprintf(f, "SLICE_JOB=%s\n", u->slice_job);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (u->display)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fprintf(f, "DISPLAY=%s\n", u->display->id);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (dual_timestamp_is_set(&u->timestamp))
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fprintf(f,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "REALTIME=%llu\n"
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering "MONOTONIC=%llu\n",
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering (unsigned long long) u->timestamp.realtime,
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering (unsigned long long) u->timestamp.monotonic);
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering if (u->sessions) {
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering Session *i;
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering bool first;
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputs("SESSIONS=", f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering first = true;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (first)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering first = false;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering else
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputc(' ', f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputs(i->id, f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputs("\nSEATS=", f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering first = true;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!i->seat)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering continue;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (first)
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering first = false;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering else
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputc(' ', f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputs(i->seat->id, f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputs("\nACTIVE_SESSIONS=", f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering first = true;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering if (!session_is_active(i))
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering continue;
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering if (first)
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering first = false;
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering else
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering fputc(' ', f);
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering fputs(i->id, f);
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering }
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering
9833a66c7eba011c3740867c80133bc6fa976aa3Lennart Poettering fputs("\nONLINE_SESSIONS=", f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering first = true;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (session_get_state(i) == SESSION_CLOSING)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering continue;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (first)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering first = false;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering else
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputc(' ', f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputs(i->id, f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputs("\nACTIVE_SEATS=", f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering first = true;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!session_is_active(i) || !i->seat)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering continue;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (first)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering first = false;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering else
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputc(' ', f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputs(i->seat->id, f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputs("\nONLINE_SEATS=", f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering first = true;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (session_get_state(i) == SESSION_CLOSING || !i->seat)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering continue;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (first)
78fe420ff0bb4cd94de3c4d3f15a3021cc3e2878Lennart Poettering first = false;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering else
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputc(' ', f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputs(i->seat->id, f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fputc('\n', f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering fflush(f);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (ferror(f) || rename(temp_path, u->state_file) < 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = -errno;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering unlink(u->state_file);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering unlink(temp_path);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringfinish:
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to save user data for %s: %s", u->name, strerror(-r));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringint user_load(User *u) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering _cleanup_free_ char *display = NULL, *realtime = NULL, *monotonic = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering Session *s = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = parse_env_file(u->state_file, NEWLINE,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "RUNTIME", &u->runtime_path,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "SERVICE", &u->service,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "SERVICE_JOB", &u->service_job,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "SLICE", &u->slice,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "SLICE_JOB", &u->slice_job,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "DISPLAY", &display,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "REALTIME", &realtime,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering "MONOTONIC", &monotonic,
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering NULL);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r == -ENOENT)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to read %s: %s", u->state_file, strerror(-r));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (display)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering s = hashmap_get(u->manager->sessions, display);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (s && s->display && display_is_local(s->display))
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->display = s;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (realtime) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering unsigned long long l;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (sscanf(realtime, "%llu", &l) > 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->timestamp.realtime = l;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (monotonic) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering unsigned long long l;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (sscanf(monotonic, "%llu", &l) > 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->timestamp.monotonic = l;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int user_mkdir_runtime_path(User *u) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering char *p;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = mkdir_safe_label("/run/user", 0755, 0, 0);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to create /run/user: %s", strerror(-r));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!u->runtime_path) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (asprintf(&p, "/run/user/%lu", (unsigned long) u->uid) < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering } else
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering p = u->runtime_path;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = mkdir_safe_label(p, 0700, u->uid, u->gid);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to create runtime directory %s: %s", p, strerror(-r));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(p);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->runtime_path = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->runtime_path = p;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int user_start_slice(User *u) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering DBusError error;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering char *job;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
0b97208d8c39131f8a7cfcfccb5c40b86af44ee5Lennart Poettering dbus_error_init(&error);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!u->slice) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering char lu[DECIMAL_STR_MAX(unsigned long) + 1], *slice;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering sprintf(lu, "%lu", (unsigned long) u->uid);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = build_subslice(SPECIAL_USER_SLICE, lu, &slice);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
25b3245fb483e52766867dfe33ce271011caaca9Lennart Poettering r = manager_start_unit(u->manager, slice, &error, &job);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to start user slice: %s", bus_error(&error, r));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering dbus_error_free(&error);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(slice);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering } else {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->slice = slice;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u->slice_job);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->slice_job = job;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (u->slice)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering hashmap_put(u->manager->user_units, u->slice, u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int user_start_service(User *u) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering DBusError error;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering char *job;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poettering dbus_error_init(&error);
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poettering
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poettering if (!u->service) {
5034c7bcdfc4493ed3c30722e9d897c8da78fedeLennart Poettering char lu[DECIMAL_STR_MAX(unsigned long) + 1], *service;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering sprintf(lu, "%lu", (unsigned long) u->uid);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering service = unit_name_build("user", lu, ".service");
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!service)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return log_oom();
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = manager_start_unit(u->manager, service, &error, &job);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to start user service: %s", bus_error(&error, r));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering dbus_error_free(&error);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(service);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering } else {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->service = service;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u->service_job);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->service_job = job;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
124aff6251c095367ce1323a21fa23235cbb0490Lennart Poettering if (u->service)
124aff6251c095367ce1323a21fa23235cbb0490Lennart Poettering hashmap_put(u->manager->user_units, u->service, u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringint user_start(User *u) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (u->started)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
0b97208d8c39131f8a7cfcfccb5c40b86af44ee5Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_debug("New user %s logged in.", u->name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering /* Make XDG_RUNTIME_DIR */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = user_mkdir_runtime_path(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering /* Create cgroup */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = user_start_slice(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering /* Spawn user systemd */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = user_start_service(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!dual_timestamp_is_set(&u->timestamp))
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering dual_timestamp_get(&u->timestamp);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->started = true;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering /* Save new user data */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering user_save(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering user_send_signal(u, true);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int user_stop_slice(User *u) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering DBusError error;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering char *job;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering dbus_error_init(&error);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (!u->slice)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = manager_stop_unit(u->manager, u->slice, &error, &job);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to stop user slice: %s", bus_error(&error, r));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering dbus_error_free(&error);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u->slice_job);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->slice_job = job;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
0b97208d8c39131f8a7cfcfccb5c40b86af44ee5Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringstatic int user_stop_service(User *u) {
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering DBusError error;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering char *job;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering int r;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering assert(u);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering dbus_error_init(&error);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (!u->service)
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering return 0;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering r = manager_stop_unit(u->manager, u->service, &error, &job);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (r < 0) {
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering log_error("Failed to stop user service: %s", bus_error(&error, r));
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering dbus_error_free(&error);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering return r;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering }
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering free(u->service_job);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering u->service_job = job;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering return r;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering}
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering/* static int user_shall_kill(User *u) { */
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering/* assert(u); */
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering/* if (!u->manager->kill_user_processes) */
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering/* return false; */
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering/* if (strv_contains(u->manager->kill_exclude_users, u->name)) */
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering/* return false; */
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering/* if (strv_isempty(u->manager->kill_only_users)) */
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering/* return true; */
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering/* return strv_contains(u->manager->kill_only_users, u->name); */
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering/* } */
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poetteringstatic int user_remove_runtime_path(User *u) {
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering int r;
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering assert(u);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering if (!u->runtime_path)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return 0;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = rm_rf(u->runtime_path, false, true, false);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (r < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Failed to remove runtime directory %s: %s", u->runtime_path, strerror(-r));
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering free(u->runtime_path);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->runtime_path = NULL;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering return r;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering}
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poetteringint user_stop(User *u) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering Session *s;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering int r = 0, k;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (u->started)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_debug("User %s logged out.", u->name);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering LIST_FOREACH(sessions_by_user, s, u->sessions) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k = session_stop(s);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (k < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = k;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering }
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering /* Kill systemd */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k = user_stop_service(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (k < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = k;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering /* Kill cgroup */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering k = user_stop_slice(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (k < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = k;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering /* Kill XDG_RUNTIME_DIR */
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt k = user_remove_runtime_path(u);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering if (k < 0)
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering r = k;
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering unlink(u->state_file);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering user_add_to_gc_queue(u);
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt if (u->started)
4d9ced9956755901238fede6fc5a3d7e4e816aa6Lennart Poettering user_send_signal(u, false);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering u->started = false;
return r;
}
int user_get_idle_hint(User *u, dual_timestamp *t) {
Session *s;
bool idle_hint = true;
dual_timestamp ts = { 0, 0 };
assert(u);
LIST_FOREACH(sessions_by_user, s, u->sessions) {
dual_timestamp k;
int ih;
ih = session_get_idle_hint(s, &k);
if (ih < 0)
return ih;
if (!ih) {
if (!idle_hint) {
if (k.monotonic < ts.monotonic)
ts = k;
} else {
idle_hint = false;
ts = k;
}
} else if (idle_hint) {
if (k.monotonic > ts.monotonic)
ts = k;
}
}
if (t)
*t = ts;
return idle_hint;
}
static int user_check_linger_file(User *u) {
char *p;
int r;
if (asprintf(&p, "/var/lib/systemd/linger/%s", u->name) < 0)
return -ENOMEM;
r = access(p, F_OK) >= 0;
free(p);
return r;
}
int user_check_gc(User *u, bool drop_not_started) {
assert(u);
if (drop_not_started && !u->started)
return 0;
if (u->sessions)
return 1;
if (user_check_linger_file(u) > 0)
return 1;
return 0;
}
void user_add_to_gc_queue(User *u) {
assert(u);
if (u->in_gc_queue)
return;
LIST_PREPEND(User, gc_queue, u->manager->user_gc_queue, u);
u->in_gc_queue = true;
}
UserState user_get_state(User *u) {
Session *i;
bool all_closing = true;
assert(u);
if (u->slice_job || u->service_job)
return u->started ? USER_OPENING : USER_CLOSING;
LIST_FOREACH(sessions_by_user, i, u->sessions) {
if (session_is_active(i))
return USER_ACTIVE;
if (session_get_state(i) != SESSION_CLOSING)
all_closing = false;
}
if (u->sessions)
return all_closing ? USER_CLOSING : USER_ONLINE;
if (user_check_linger_file(u) > 0)
return USER_LINGERING;
return USER_CLOSING;
}
int user_kill(User *u, int signo) {
assert(u);
if (!u->slice)
return -ESRCH;
return manager_kill_unit(u->manager, u->slice, KILL_ALL, signo, NULL);
}
static const char* const user_state_table[_USER_STATE_MAX] = {
[USER_OFFLINE] = "offline",
[USER_OPENING] = "opening",
[USER_LINGERING] = "lingering",
[USER_ONLINE] = "online",
[USER_ACTIVE] = "active",
[USER_CLOSING] = "closing"
};
DEFINE_STRING_TABLE_LOOKUP(user_state, UserState);