X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fsd-login.c;fp=src%2Fsd-login.c;h=3ae850d80116ba4201e7ec9d4b83a5d6ae40bf69;hb=74b91131ed09850ed487a2f7849147ff6f80194d;hp=0000000000000000000000000000000000000000;hpb=0a55b298d930543c8065bb9e708dd112562b1736;p=elogind.git diff --git a/src/sd-login.c b/src/sd-login.c new file mode 100644 index 000000000..3ae850d80 --- /dev/null +++ b/src/sd-login.c @@ -0,0 +1,323 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "util.h" +#include "cgroup-util.h" +#include "macro.h" +#include "sd-login.h" + +_public_ int sd_pid_get_session(pid_t pid, char **session) { + int r; + char *cg_process, *cg_init, *p; + + if (pid == 0) + pid = getpid(); + + if (pid <= 0) + return -EINVAL; + + if (!session) + return -EINVAL; + + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &cg_process); + if (r < 0) + return r; + + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &cg_init); + if (r < 0) { + free(cg_process); + return r; + } + + if (endswith(cg_init, "/system")) + cg_init[strlen(cg_init)-7] = 0; + else if (streq(cg_init, "/")) + cg_init[0] = 0; + + if (startswith(cg_process, cg_init)) + p = cg_process + strlen(cg_init); + else + p = cg_process; + + free(cg_init); + + if (!startswith(p, "/user/")) { + free(cg_process); + return -ENOENT; + } + + p += 6; + if (startswith(p, "shared/") || streq(p, "shared")) { + free(cg_process); + return -ENOENT; + } + + p = strchr(p, '/'); + if (!p) { + free(cg_process); + return -ENOENT; + } + + p++; + p = strndup(p, strcspn(p, "/")); + free(cg_process); + + if (!p) + return -ENOMEM; + + *session = p; + return 0; +} + +_public_ int sd_uid_get_state(uid_t uid, char**state) { + char *p, *s = NULL; + int r; + + if (!state) + return -EINVAL; + + if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) uid) < 0) + return -ENOMEM; + + r = parse_env_file(p, NEWLINE, "STATE", &s, NULL); + free(p); + + if (r == -ENOENT) { + free(s); + s = strdup("offline"); + if (!s) + return -ENOMEM; + + *state = s; + return 0; + } else if (r < 0) { + free(s); + return r; + } else if (!s) + return -EIO; + + *state = s; + return 0; +} + +static int uid_is_on_seat_internal(uid_t uid, const char *seat, const char *variable) { + char *p, *w, *t, *state, *s = NULL; + size_t l; + int r; + + if (!seat) + return -EINVAL; + + p = strappend("/run/systemd/seats/", seat); + if (!p) + return -ENOMEM; + + r = parse_env_file(p, NEWLINE, "UIDS", &s, NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } + + if (!s) + return -EIO; + + if (asprintf(&t, "%lu", (unsigned long) uid) < 0) { + free(s); + return -ENOMEM; + } + + FOREACH_WORD(w, l, s, state) { + if (strncmp(t, w, l) == 0) { + free(s); + free(t); + + return 1; + } + } + + free(s); + free(t); + + return 0; +} + +_public_ int sd_uid_is_on_seat(uid_t uid, const char *seat) { + return uid_is_on_seat_internal(uid, seat, "UIDS"); +} + +_public_ int sd_uid_is_active_on_seat(uid_t uid, const char *seat) { + return uid_is_on_seat_internal(uid, seat, "ACTIVE_UID"); +} + +_public_ int sd_session_is_active(const char *session) { + int r; + char *p, *s = NULL; + + if (!session) + return -EINVAL; + + p = strappend("/run/systemd/sessions/", session); + if (!p) + return -ENOMEM; + + r = parse_env_file(p, NEWLINE, "ACTIVE", &s, NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } + + if (!s) + return -EIO; + + r = parse_boolean(s); + free(s); + + return r; +} + +_public_ int sd_session_get_uid(const char *session, uid_t *uid) { + int r; + char *p, *s = NULL; + unsigned long ul; + + if (!session) + return -EINVAL; + if (!uid) + return -EINVAL; + + p = strappend("/run/systemd/sessions/", session); + if (!p) + return -ENOMEM; + + r = parse_env_file(p, NEWLINE, "UID", &s, NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } + + if (!s) + return -EIO; + + r = safe_atolu(s, &ul); + free(s); + + if (r < 0) + return r; + + *uid = (uid_t) ul; + return 0; +} + +_public_ int sd_session_get_seat(const char *session, char **seat) { + char *p, *s = NULL; + int r; + + if (!session) + return -EINVAL; + if (!seat) + return -EINVAL; + + p = strappend("/run/systemd/sessions/", session); + if (!p) + return -ENOMEM; + + r = parse_env_file(p, NEWLINE, "SEAT", &s, NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } + + if (isempty(s)) + return -ENOENT; + + *seat = s; + return 0; +} + +_public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) { + char *p, *s = NULL, *t = NULL; + int r; + + if (!seat) + return -EINVAL; + if (!session && !uid) + return -EINVAL; + + p = strappend("/run/systemd/seats/", seat); + if (!p) + return -ENOMEM; + + r = parse_env_file(p, NEWLINE, + "ACTIVE", &s, + "ACTIVE_UID", &t, + NULL); + free(p); + + if (r < 0) { + free(s); + free(t); + return r; + } + + if (session && !s) { + free(t); + return -EIO; + } + + if (uid && !t) { + free(s); + return -EIO; + } + + if (uid && t) { + unsigned long ul; + + r = safe_atolu(t, &ul); + if (r < 0) { + free(t); + free(s); + return r; + } + + *uid = (uid_t) ul; + } + + free(t); + + if (session && s) + *session = s; + else + free(s); + + return 0; +}