logind-user.c revision c9caad802128a5dc599342c1400a61f31e8b17b5
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/***
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2011 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering***/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek#include <string.h>
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek#include <unistd.h>
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include <errno.h>
4ad7f2761da661853dcc29d542efb4727abb1101Nick Owens
7263f72499e962b3fd54cdb7c79d49ca72121edeZbigniew Jędrzejewski-Szmek#include "logind-user.h"
e4e73a632524c382139034d4271f53b6089ab4cbLennart Poettering#include "util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "mkdir.h"
e4e73a632524c382139034d4271f53b6089ab4cbLennart Poettering#include "cgroup-util.h"
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering#include "hashmap.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "strv.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
d7671a3efdaef690b4316a03011038f731f2eea9Zbigniew Jędrzejewski-SzmekUser* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering User *u;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering assert(m);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering assert(name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering u = new0(User, 1);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (!u)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return NULL;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering u->name = strdup(name);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (!u->name) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering free(u);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return NULL;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering }
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (asprintf(&u->state_file, "/run/systemd/users/%lu", (unsigned long) uid) < 0) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering free(u->name);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering free(u);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return NULL;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering }
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
36d9205d669bcdcb04fa730d1f3549a9fc9a9001Tom Gundersen if (hashmap_put(m->users, ULONG_TO_PTR((unsigned long) uid), u) < 0) {
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering free(u->state_file);
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering free(u->name);
36d9205d669bcdcb04fa730d1f3549a9fc9a9001Tom Gundersen free(u);
36d9205d669bcdcb04fa730d1f3549a9fc9a9001Tom Gundersen return NULL;
36d9205d669bcdcb04fa730d1f3549a9fc9a9001Tom Gundersen }
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering u->manager = m;
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering u->uid = uid;
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering u->gid = gid;
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering return u;
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering}
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poetteringvoid user_free(User *u) {
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering assert(u);
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering if (u->in_gc_queue)
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering LIST_REMOVE(User, gc_queue, u->manager->user_gc_queue, u);
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering while (u->sessions)
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering session_free(u->sessions);
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering if (u->cgroup_path)
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering hashmap_remove(u->manager->user_cgroups, u->cgroup_path);
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering free(u->cgroup_path);
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering free(u->service);
36d9205d669bcdcb04fa730d1f3549a9fc9a9001Tom Gundersen free(u->runtime_path);
36d9205d669bcdcb04fa730d1f3549a9fc9a9001Tom Gundersen
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering hashmap_remove(u->manager->users, ULONG_TO_PTR((unsigned long) u->uid));
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering free(u->name);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering free(u->state_file);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering free(u);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering}
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringint user_save(User *u) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering FILE *f;
dc477e7385e8ab29efb8fadb72ec994077a105c6Lennart Poettering int r;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering char *temp_path;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering assert(u);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering assert(u->state_file);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering if (!u->started)
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering return 0;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = mkdir_safe_label("/run/systemd/users", 0755, 0, 0);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering if (r < 0)
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering goto finish;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = fopen_temporary(u->state_file, &f, &temp_path);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering if (r < 0)
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering goto finish;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering fchmod(fileno(f), 0644);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fprintf(f,
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering "# This is private data. Do not parse.\n"
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering "NAME=%s\n"
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering "STATE=%s\n",
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering u->name,
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering user_state_to_string(user_get_state(u)));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (u->cgroup_path)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fprintf(f,
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering "CGROUP=%s\n",
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering u->cgroup_path);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (u->runtime_path)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fprintf(f,
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering "RUNTIME=%s\n",
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering u->runtime_path);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (u->service)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fprintf(f,
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering "SERVICE=%s\n",
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering u->service);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering if (u->display)
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering fprintf(f,
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering "DISPLAY=%s\n",
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering u->display->id);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (u->sessions) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering Session *i;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering bool first;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fputs("SESSIONS=", f);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering first = true;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (first)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering first = false;
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering else
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fputc(' ', f);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fputs(i->id, f);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering }
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fputs("\nSEATS=", f);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering first = true;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (!i->seat)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering continue;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
28b9b7640603f88cb49f95609331fa5072715f15Lennart Poettering if (first)
28b9b7640603f88cb49f95609331fa5072715f15Lennart Poettering first = false;
28b9b7640603f88cb49f95609331fa5072715f15Lennart Poettering else
28b9b7640603f88cb49f95609331fa5072715f15Lennart Poettering fputc(' ', f);
28b9b7640603f88cb49f95609331fa5072715f15Lennart Poettering
28b9b7640603f88cb49f95609331fa5072715f15Lennart Poettering fputs(i->seat->id, f);
28b9b7640603f88cb49f95609331fa5072715f15Lennart Poettering }
28b9b7640603f88cb49f95609331fa5072715f15Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fputs("\nACTIVE_SESSIONS=", f);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering first = true;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
4d247a6cd3f69acbc5a09e8ac7e4fbb50eaa3228Lennart Poettering if (!session_is_active(i))
4d247a6cd3f69acbc5a09e8ac7e4fbb50eaa3228Lennart Poettering continue;
4d247a6cd3f69acbc5a09e8ac7e4fbb50eaa3228Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (first)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering first = false;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering else
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fputc(' ', f);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fputs(i->id, f);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering }
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fputs("\nACTIVE_SEATS=", f);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering first = true;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (!session_is_active(i) || !i->seat)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering continue;
105e151299dc1208855380be2b22d0db2d66ebc6Lennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering if (first)
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering first = false;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering else
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fputs(i->seat->id, f);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering }
4d247a6cd3f69acbc5a09e8ac7e4fbb50eaa3228Lennart Poettering fputc('\n', f);
4d247a6cd3f69acbc5a09e8ac7e4fbb50eaa3228Lennart Poettering }
4d247a6cd3f69acbc5a09e8ac7e4fbb50eaa3228Lennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering fflush(f);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering if (ferror(f) || rename(temp_path, u->state_file) < 0) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = -errno;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering unlink(u->state_file);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering unlink(temp_path);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering }
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering fclose(f);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering free(temp_path);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringfinish:
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering if (r < 0)
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering log_error("Failed to save user data for %s: %s", u->name, strerror(-r));
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering return r;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering}
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringint user_load(User *u) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering int r;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering char *display = NULL;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering Session *s = NULL;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering assert(u);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering r = parse_env_file(u->state_file, NEWLINE,
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering "CGROUP", &u->cgroup_path,
5d27351f8546530cf779847b0b04b0172c09f9d0Tom Gundersen "RUNTIME", &u->runtime_path,
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering "SERVICE", &u->service,
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering "DISPLAY", &display,
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering NULL);
5d27351f8546530cf779847b0b04b0172c09f9d0Tom Gundersen if (r < 0) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering free(display);
5d27351f8546530cf779847b0b04b0172c09f9d0Tom Gundersen
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (r == -ENOENT)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return 0;
5d27351f8546530cf779847b0b04b0172c09f9d0Tom Gundersen
5d27351f8546530cf779847b0b04b0172c09f9d0Tom Gundersen log_error("Failed to read %s: %s", u->state_file, strerror(-r));
5d27351f8546530cf779847b0b04b0172c09f9d0Tom Gundersen return r;
5d27351f8546530cf779847b0b04b0172c09f9d0Tom Gundersen }
58db254ade4fb2ef77de68f28c4f13814819f6a1Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (display) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering s = hashmap_get(u->manager->sessions, display);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering free(display);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering }
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering if (s && s->display && display_is_local(s->display))
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering u->display = s;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering return r;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering}
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringstatic int user_mkdir_runtime_path(User *u) {
5d27351f8546530cf779847b0b04b0172c09f9d0Tom Gundersen char *p;
5d27351f8546530cf779847b0b04b0172c09f9d0Tom Gundersen int r;
5d27351f8546530cf779847b0b04b0172c09f9d0Tom Gundersen
5d27351f8546530cf779847b0b04b0172c09f9d0Tom Gundersen assert(u);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = mkdir_safe_label("/run/user", 0755, 0, 0);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering if (r < 0) {
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering log_error("Failed to create /run/user: %s", strerror(-r));
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering return r;
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering }
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering if (!u->runtime_path) {
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering if (asprintf(&p, "/run/user/%lu", (unsigned long) u->uid) < 0)
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering return log_oom();
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering } else
65b200e70d01cb7c513114b602c9b5cf41348f77Lennart Poettering p = u->runtime_path;
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = mkdir_safe_label(p, 0700, u->uid, u->gid);
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering if (r < 0) {
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering log_error("Failed to create runtime directory %s: %s", p, strerror(-r));
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering free(p);
0936416a1cba187dc76903dae73246f4cbddf312Lennart Poettering u->runtime_path = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersen
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering u->runtime_path = p;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering return 0;
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersen}
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersenstatic int user_create_cgroup(User *u) {
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersen char **k;
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersen char *p;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering int r;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt assert(u);
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering if (!u->cgroup_path) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering if (asprintf(&p, "%s/%s", u->manager->cgroup_path, u->name) < 0)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return log_oom();
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering } else
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering p = u->cgroup_path;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering r = cg_create(SYSTEMD_CGROUP_CONTROLLER, p);
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering if (r < 0) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering log_error("Failed to create cgroup "SYSTEMD_CGROUP_CONTROLLER":%s: %s", p, strerror(-r));
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering free(p);
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering u->cgroup_path = NULL;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering return r;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering }
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering u->cgroup_path = p;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering STRV_FOREACH(k, u->manager->controllers) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering if (strv_contains(u->manager->reset_controllers, *k))
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt continue;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt r = cg_create(*k, p);
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt if (r < 0)
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt log_warning("Failed to create cgroup %s:%s: %s", *k, p, strerror(-r));
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering }
d23a27a964748967e1ad20e86de869a753af555bTom Gundersen
f2af5ea3cbf54998ed41d2d21a3448abb92ca7ffLennart Poettering hashmap_put(u->manager->user_cgroups, u->cgroup_path, u);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering return 0;
6af47493de0ef2b66d4c3fbcdd4a2e12fec4bfbaLennart Poettering}
6af47493de0ef2b66d4c3fbcdd4a2e12fec4bfbaLennart Poettering
6af47493de0ef2b66d4c3fbcdd4a2e12fec4bfbaLennart Poetteringstatic int user_start_service(User *u) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering assert(u);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
d23a27a964748967e1ad20e86de869a753af555bTom Gundersen /* FIXME: Fill me in later ... */
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering return 0;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering}
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poetteringint user_start(User *u) {
d23a27a964748967e1ad20e86de869a753af555bTom Gundersen int r;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering assert(u);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
f2af5ea3cbf54998ed41d2d21a3448abb92ca7ffLennart Poettering if (u->started)
f2af5ea3cbf54998ed41d2d21a3448abb92ca7ffLennart Poettering return 0;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering log_debug("New user %s logged in.", u->name);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering /* Make XDG_RUNTIME_DIR */
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = user_mkdir_runtime_path(u);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0)
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering return r;
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering /* Create cgroup */
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering r = user_create_cgroup(u);
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering if (r < 0)
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering return r;
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering /* Spawn user systemd */
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering r = user_start_service(u);
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering if (r < 0)
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering return r;
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering dual_timestamp_get(&u->timestamp);
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering u->started = true;
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering /* Save new user data */
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering user_save(u);
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering user_send_signal(u, true);
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering return 0;
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering}
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poetteringstatic int user_stop_service(User *u) {
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering assert(u);
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering if (!u->service)
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering return 0;
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering return 0;
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering}
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poetteringstatic int user_shall_kill(User *u) {
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering assert(u);
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering if (!u->manager->kill_user_processes)
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering return false;
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering
f57e3cd5fa709ec0f52531eccba909ac0851927cLennart Poettering if (strv_contains(u->manager->kill_exclude_users, u->name))
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (strv_isempty(u->manager->kill_only_users))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return strv_contains(u->manager->kill_only_users, u->name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringstatic int user_terminate_cgroup(User *u) {
ee3d6aff9bd73c1b23e29d1fa1fa6f7a1ef0533bLennart Poettering int r;
97c67192eadaffe67b803ec5b991a92bb1137d0bLennart Poettering char **k;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!u->cgroup_path)
8bf52d3d17d364438191077d0750b8b80b5dc53aLennart Poettering return 0;
8bf52d3d17d364438191077d0750b8b80b5dc53aLennart Poettering
8bf52d3d17d364438191077d0750b8b80b5dc53aLennart Poettering cg_trim(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, false);
8bf52d3d17d364438191077d0750b8b80b5dc53aLennart Poettering
8bf52d3d17d364438191077d0750b8b80b5dc53aLennart Poettering if (user_shall_kill(u)) {
8bf52d3d17d364438191077d0750b8b80b5dc53aLennart Poettering
8bf52d3d17d364438191077d0750b8b80b5dc53aLennart Poettering r = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true);
8bf52d3d17d364438191077d0750b8b80b5dc53aLennart Poettering if (r < 0)
8bf52d3d17d364438191077d0750b8b80b5dc53aLennart Poettering log_error("Failed to kill user cgroup: %s", strerror(-r));
8bf52d3d17d364438191077d0750b8b80b5dc53aLennart Poettering } else {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to check user cgroup: %s", strerror(-r));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else if (r > 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = cg_delete(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to delete user cgroup: %s", strerror(-r));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = -EBUSY;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering STRV_FOREACH(k, u->manager->controllers)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering cg_trim(*k, u->cgroup_path, true);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering hashmap_remove(u->manager->user_cgroups, u->cgroup_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(u->cgroup_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->cgroup_path = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering}
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poetteringstatic int user_remove_runtime_path(User *u) {
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering int r;
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering assert(u);
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek if (!u->runtime_path)
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek return 0;
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek
8ac4e9e1e54397f6d1745c2a7a806132418c7da2Lennart Poettering r = rm_rf(u->runtime_path, false, true, false);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (r < 0)
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek log_error("Failed to remove runtime directory %s: %s", u->runtime_path, strerror(-r));
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek free(u->runtime_path);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering u->runtime_path = NULL;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek return r;
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering}
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poetteringint user_stop(User *u) {
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering Session *s;
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek int r = 0, k;
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering assert(u);
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering if (u->started)
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering log_debug("User %s logged out.", u->name);
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering LIST_FOREACH(sessions_by_user, s, u->sessions) {
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek k = session_stop(s);
946c70944ebdf428ffeb9991a7449edbd4011461Zbigniew Jędrzejewski-Szmek if (k < 0)
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek r = k;
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering }
abf126a355e2f2b62b6c51ab3bb37895d1e3eee7Tom Gundersen
abf126a355e2f2b62b6c51ab3bb37895d1e3eee7Tom Gundersen /* Kill systemd */
abf126a355e2f2b62b6c51ab3bb37895d1e3eee7Tom Gundersen k = user_stop_service(u);
abf126a355e2f2b62b6c51ab3bb37895d1e3eee7Tom Gundersen if (k < 0)
42cc2eebb01056beb7acd3ecfe8e533558237f84Lennart Poettering r = k;
549c1a2564b56f2bb38f1203d59c747ea15817f3Tom Gundersen
42cc2eebb01056beb7acd3ecfe8e533558237f84Lennart Poettering /* Kill cgroup */
42cc2eebb01056beb7acd3ecfe8e533558237f84Lennart Poettering k = user_terminate_cgroup(u);
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek if (k < 0)
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek r = k;
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek /* Kill XDG_RUNTIME_DIR */
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek k = user_remove_runtime_path(u);
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek if (k < 0)
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek r = k;
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek unlink(u->state_file);
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen user_add_to_gc_queue(u);
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen if (u->started)
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen user_send_signal(u, false);
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen u->started = false;
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen return r;
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen}
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersenint user_get_idle_hint(User *u, dual_timestamp *t) {
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek Session *s;
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek bool idle_hint = true;
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek dual_timestamp ts = { 0, 0 };
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering assert(u);
48d45d2b49d2adb870cd5f1bc7cb389b33655f1cZbigniew Jędrzejewski-Szmek
48d45d2b49d2adb870cd5f1bc7cb389b33655f1cZbigniew Jędrzejewski-Szmek LIST_FOREACH(sessions_by_user, s, u->sessions) {
48d45d2b49d2adb870cd5f1bc7cb389b33655f1cZbigniew Jędrzejewski-Szmek dual_timestamp k;
48d45d2b49d2adb870cd5f1bc7cb389b33655f1cZbigniew Jędrzejewski-Szmek int ih;
d93a16b81f8baa0e6a16310b210f225129347322Zbigniew Jędrzejewski-Szmek
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek ih = session_get_idle_hint(s, &k);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (ih < 0)
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek return ih;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering if (!ih) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (!idle_hint) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (k.monotonic < ts.monotonic)
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering ts = k;
7b50eb2efa122200e39646c19a29abab302f7d24Lennart Poettering } else {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering idle_hint = false;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering ts = k;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering }
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering } else if (idle_hint) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (k.monotonic > ts.monotonic)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering ts = k;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (t)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering *t = ts;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return idle_hint;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering}
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poetteringstatic int user_check_linger_file(User *u) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering char *p;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering int r;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (asprintf(&p, "/var/lib/systemd/linger/%s", u->name) < 0)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return -ENOMEM;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering r = access(p, F_OK) >= 0;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering free(p);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return r;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering}
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poetteringint user_check_gc(User *u, bool drop_not_started) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering int r;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering assert(u);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (drop_not_started && !u->started)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return 0;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (u->sessions)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return 1;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (user_check_linger_file(u) > 0)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return 1;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (u->cgroup_path) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, false);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r < 0)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return r;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r <= 0)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return 1;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return 0;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering}
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poetteringvoid user_add_to_gc_queue(User *u) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering assert(u);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (u->in_gc_queue)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering LIST_PREPEND(User, gc_queue, u->manager->user_gc_queue, u);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering u->in_gc_queue = true;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering}
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart PoetteringUserState user_get_state(User *u) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering Session *i;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering bool all_closing = true;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering assert(u);
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering LIST_FOREACH(sessions_by_user, i, u->sessions) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering if (session_is_active(i))
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering return USER_ACTIVE;
4d247a6cd3f69acbc5a09e8ac7e4fbb50eaa3228Lennart Poettering if (session_get_state(i) != SESSION_CLOSING)
4d247a6cd3f69acbc5a09e8ac7e4fbb50eaa3228Lennart Poettering all_closing = false;
4d247a6cd3f69acbc5a09e8ac7e4fbb50eaa3228Lennart Poettering }
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering if (u->sessions)
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering return all_closing ? USER_CLOSING : USER_ONLINE;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
fd0b4602f6332c3f1660eb208c8f5c719709a009Lennart Poettering if (user_check_linger_file(u) > 0)
fd0b4602f6332c3f1660eb208c8f5c719709a009Lennart Poettering return USER_LINGERING;
fd0b4602f6332c3f1660eb208c8f5c719709a009Lennart Poettering
fd0b4602f6332c3f1660eb208c8f5c719709a009Lennart Poettering return USER_CLOSING;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering}
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poetteringint user_kill(User *u, int signo) {
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering int r = 0, q;
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering Set *pid_set = NULL;
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering assert(u);
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering if (!u->cgroup_path)
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering return -ESRCH;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering pid_set = set_new(trivial_hash_func, trivial_compare_func);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (!pid_set)
8ac4e9e1e54397f6d1745c2a7a806132418c7da2Lennart Poettering return -ENOMEM;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (q < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (q != -EAGAIN && q != -ESRCH && q != -ENOENT)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = q;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek if (pid_set)
0f84a72e3c0f58d71cff2121e6df1611eaf9c9eaDavid Herrmann set_free(pid_set);
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering
2e276efc7b0398a3086629a52970bdd4ab7252f9Zbigniew Jędrzejewski-Szmek return r;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering}
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poetteringstatic const char* const user_state_table[_USER_STATE_MAX] = {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering [USER_OFFLINE] = "offline",
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering [USER_LINGERING] = "lingering",
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering [USER_ONLINE] = "online",
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering [USER_ACTIVE] = "active",
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering [USER_CLOSING] = "closing"
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering};
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart PoetteringDEFINE_STRING_TABLE_LOOKUP(user_state, UserState);
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering