logind-user.c revision 129eebe020118fc1bf0274c9ea75ffb6178a280f
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 General Public License as published by
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen the Free Software Foundation; either version 2 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 General Public License for more details.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen You should have received a copy of the GNU General Public License
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen***/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include <string.h>
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include <unistd.h>
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering#include <errno.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "logind-user.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "util.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "cgroup-util.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "hashmap.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "strv.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom GundersenUser* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen User *u;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering assert(m);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(name);
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering u = new0(User, 1);
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering if (!u)
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering return NULL;
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->name = strdup(name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!u->name) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (asprintf(&u->state_file, "/run/systemd/users/%lu", (unsigned long) uid) < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u->name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (hashmap_put(m->users, ULONG_TO_PTR((unsigned long) uid), u) < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u->state_file);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u->name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->manager = m;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->uid = uid;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->gid = gid;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return u;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poetteringvoid user_free(User *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u);
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->in_gc_queue)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_REMOVE(User, gc_queue, u->manager->user_gc_queue, u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering while (u->sessions)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering session_free(u->sessions);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u->cgroup_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u->service);
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering free(u->runtime_path);
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering hashmap_remove(u->manager->users, ULONG_TO_PTR((unsigned long) u->uid));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering free(u->name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u->state_file);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint user_save(User *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering FILE *f;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char *temp_path;
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
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = safe_mkdir("/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)
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart 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->cgroup_path)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "CGROUP=%s\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->cgroup_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->runtime_path)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "RUNTIME=%s\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->runtime_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->service)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "SERVICE=%s\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->service);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->display)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "DISPLAY=%s\n",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->display->id);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->sessions) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Session *i;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs("SESSIONS=", f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "%s%c",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering i->id,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering i->sessions_by_user_next ? ' ' : '\n');
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs("SEATS=", f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (i->seat)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "%s%c",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering i->seat->id,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering i->sessions_by_user_next ? ' ' : '\n');
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs("ACTIVE_SESSIONS=", f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (session_is_active(i))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "%lu%c",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (unsigned long) i->user->uid,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering i->sessions_by_user_next ? ' ' : '\n');
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fputs("ACTIVE_SEATS=", f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (session_is_active(i) && i->seat)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fprintf(f,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "%s%c",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering i->seat->id,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering i->sessions_by_user_next ? ' ' : '\n');
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
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;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering unlink(u->state_file);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering unlink(temp_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fclose(f);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(temp_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringfinish:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to save user data for %s: %s", u->name, strerror(-r));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint user_load(User *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char *display = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Session *s = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = parse_env_file(u->state_file, NEWLINE,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "CGROUP", &u->cgroup_path,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "RUNTIME", &u->runtime_path,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "SERVICE", &u->service,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "DISPLAY", &display,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(display);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r == -ENOENT)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to read %s: %s", u->state_file, strerror(-r));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (display) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering s = hashmap_get(u->manager->sessions, display);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(display);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (s && s->display && display_is_local(s->display))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->display = s;
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 = safe_mkdir("/run/user", 0755, 0, 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to create /run/user: %s", strerror(-r));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!u->runtime_path) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p = strappend("/run/user/", u->name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!p) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Out of memory");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p = u->runtime_path;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = safe_mkdir(p, 0700, u->uid, u->gid);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to create runtime directory %s: %s", p, strerror(-r));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->runtime_path = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->runtime_path = p;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int user_create_cgroup(User *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char **k;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char *p;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!u->cgroup_path) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (asprintf(&p, "%s/%s", u->manager->cgroup_path, u->name) < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Out of memory");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p = u->cgroup_path;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = cg_create(SYSTEMD_CGROUP_CONTROLLER, p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to create cgroup "SYSTEMD_CGROUP_CONTROLLER":%s: %s", p, strerror(-r));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->cgroup_path = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->cgroup_path = p;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering STRV_FOREACH(k, u->manager->controllers) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (strv_contains(u->manager->reset_controllers, *k))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
0014a4ad505d119c7ac4346d9d774c3f17f663a5Lennart Poettering r = cg_create(*k, p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("Failed to create cgroup %s:%s: %s", *k, p, strerror(-r));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int user_start_service(User *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* FIXME: Fill me in later ... */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint user_start(User *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(u);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (u->started)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_debug("New user %s logged in.", u->name);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering /* Make XDG_RUNTIME_DIR */
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = user_mkdir_runtime_path(u);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering /* Create cgroup */
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = user_create_cgroup(u);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering /* Spawn user systemd */
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = user_start_service(u);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering dual_timestamp_get(&u->timestamp);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering u->started = true;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering /* Save new user data */
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering user_save(u);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering user_send_signal(u, true);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringstatic int user_stop_service(User *u) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(u);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!u->service)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringstatic int user_shall_kill(User *u) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(u);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!u->manager->kill_user_processes)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return false;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (strv_contains(u->manager->kill_exclude_users, u->name))
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return false;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (strv_isempty(u->manager->kill_only_users))
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return true;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return strv_contains(u->manager->kill_only_users, u->name);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringstatic int user_terminate_cgroup(User *u) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering int r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering char **k;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(u);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!u->cgroup_path)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering cg_trim(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, false);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (user_shall_kill(u)) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_error("Failed to kill user cgroup: %s", strerror(-r));
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering } else {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_error("Failed to check user cgroup: %s", strerror(-r));
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering else if (r > 0) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = cg_delete(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_error("Failed to delete user cgroup: %s", strerror(-r));
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering } else
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = -EBUSY;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering }
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering STRV_FOREACH(k, u->manager->controllers)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering cg_trim(*k, u->cgroup_path, true);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering free(u->cgroup_path);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering u->cgroup_path = NULL;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering}
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, true, false);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (r < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering log_error("Failed to remove runtime directory %s: %s", u->runtime_path, strerror(-r));
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering free(u->runtime_path);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering u->runtime_path = NULL;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering}
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poetteringint user_stop(User *u) {
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering Session *s;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering int r = 0, k;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering assert(u);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (u->started)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering log_debug("User %s logged out.", u->name);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering LIST_FOREACH(sessions_by_user, s, u->sessions) {
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering k = session_stop(s);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (k < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = k;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering }
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering /* Kill systemd */
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering k = user_stop_service(u);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (k < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = k;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering /* Kill cgroup */
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering k = user_terminate_cgroup(u);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (k < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = k;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering /* Kill XDG_RUNTIME_DIR */
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering k = user_remove_runtime_path(u);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (k < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = k;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering unlink(u->state_file);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen user_add_to_gc_queue(u);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering if (u->started)
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering user_send_signal(u, false);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen u->started = false;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poetteringint user_get_idle_hint(User *u, dual_timestamp *t) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering Session *s;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering bool idle_hint = true;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering dual_timestamp ts = { 0, 0 };
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen assert(u);
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen LIST_FOREACH(sessions_by_user, s, u->sessions) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen dual_timestamp k;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen int ih;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen ih = session_get_idle_hint(s, &k);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (ih < 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return ih;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!ih) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!idle_hint) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (k.monotonic < ts.monotonic)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen ts = k;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering } else {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering idle_hint = false;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering ts = k;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering } else if (idle_hint) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (k.monotonic > ts.monotonic)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering ts = k;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (t)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *t = ts;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return idle_hint;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint user_check_gc(User *u, bool drop_not_started) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char *p;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen assert(u);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (drop_not_started && !u->started)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (u->sessions)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return 1;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (asprintf(&p, "/var/lib/systemd/linger/%s", u->name) < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return -ENOMEM;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = access(p, F_OK) >= 0;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering free(p);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (r > 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return 1;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->cgroup_path) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, false);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (r < 0)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r <= 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering return 0;
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringvoid user_add_to_gc_queue(User *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->in_gc_queue)
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering return;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen LIST_PREPEND(User, gc_queue, u->manager->user_gc_queue, u);
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering u->in_gc_queue = true;
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering}
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering
096b6773886bd7a0c8c97aa684b0b67dfae58355Lennart PoetteringUserState user_get_state(User *u) {
096b6773886bd7a0c8c97aa684b0b67dfae58355Lennart Poettering Session *i;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!u->sessions)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return USER_LINGERING;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (session_is_active(i))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return USER_ACTIVE;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return USER_ONLINE;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poetteringint user_kill(User *u, int signo) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering int r = 0, q;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering Set *pid_set = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(u);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!u->cgroup_path)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return -ESRCH;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering pid_set = set_new(trivial_hash_func, trivial_compare_func);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (!pid_set)
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return -ENOMEM;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (q < 0)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (q != -EAGAIN && q != -ESRCH && q != -ENOENT)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering r = q;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering if (pid_set)
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering set_free(pid_set);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering return r;
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering}
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poetteringstatic const char* const user_state_table[_USER_STATE_MAX] = {
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering [USER_OFFLINE] = "offline",
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering [USER_LINGERING] = "lingering",
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering [USER_ONLINE] = "online",
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering [USER_ACTIVE] = "active"
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering};
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart PoetteringDEFINE_STRING_TABLE_LOOKUP(user_state, UserState);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering