X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibelogind%2Fsd-login%2Fsd-login.c;h=ac22fa3454ce57a5fc757c5726c3309752d67acd;hb=da2587d5154e11d4e643e326793f3ce2cc48dee6;hp=6300162ebe3703ace2304722f5658011f7636cb6;hpb=f2cfa6051c00fe07268bf72f625ba4b2cf21e168;p=elogind.git diff --git a/src/libelogind/sd-login/sd-login.c b/src/libelogind/sd-login/sd-login.c index 6300162eb..ac22fa345 100644 --- a/src/libelogind/sd-login/sd-login.c +++ b/src/libelogind/sd-login/sd-login.c @@ -19,21 +19,43 @@ along with systemd; If not, see . ***/ -#include -#include #include -#include #include +#include +#include +#include -#include "util.h" +#include "sd-login.h" + +#include "alloc-util.h" #include "cgroup-util.h" -#include "macro.h" -#include "strv.h" +#include "dirent-util.h" +#include "escape.h" +#include "fd-util.h" #include "fileio.h" -#include "login-util.h" #include "formats-util.h" +#include "fs-util.h" #include "hostname-util.h" -#include "sd-login.h" +#include "io-util.h" +#include "login-util.h" +#include "macro.h" +#include "parse-util.h" +#include "path-util.h" +#include "socket-util.h" +#include "string-util.h" +#include "strv.h" +#include "user-util.h" +#include "util.h" + +/* Error codes: + * + * invalid input parameters → -EINVAL + * invalid fd → -EBADF + * process does not exist → -ESRCH + * cgroup does not exist → -ENOENT + * machine, session does not exist → -ENXIO + * requested metadata on object is missing → -ENODATA + */ _public_ int sd_pid_get_session(pid_t pid, char **session) { @@ -48,7 +70,11 @@ _public_ int sd_pid_get_unit(pid_t pid, char **unit) { assert_return(pid >= 0, -EINVAL); assert_return(unit, -EINVAL); +#if 0 /// elogind does not support systemd units return cg_pid_get_unit(pid, unit); +#else + return -ESRCH; +#endif // 0 } _public_ int sd_pid_get_user_unit(pid_t pid, char **unit) { @@ -56,7 +82,11 @@ _public_ int sd_pid_get_user_unit(pid_t pid, char **unit) { assert_return(pid >= 0, -EINVAL); assert_return(unit, -EINVAL); +#if 0 /// elogind does not support systemd units return cg_pid_get_user_unit(pid, unit); +#else + return -ESRCH; +#endif // 0 } _public_ int sd_pid_get_machine_name(pid_t pid, char **name) { @@ -64,7 +94,11 @@ _public_ int sd_pid_get_machine_name(pid_t pid, char **name) { assert_return(pid >= 0, -EINVAL); assert_return(name, -EINVAL); +#if 0 /// elogind does not support systemd units return cg_pid_get_machine_name(pid, name); +#else + return -ESRCH; +#endif // 0 } _public_ int sd_pid_get_slice(pid_t pid, char **slice) { @@ -72,7 +106,11 @@ _public_ int sd_pid_get_slice(pid_t pid, char **slice) { assert_return(pid >= 0, -EINVAL); assert_return(slice, -EINVAL); +#if 0 /// elogind does not support systemd slices return cg_pid_get_slice(pid, slice); +#else + return -ESRCH; +#endif // 0 } _public_ int sd_pid_get_user_slice(pid_t pid, char **slice) { @@ -80,7 +118,11 @@ _public_ int sd_pid_get_user_slice(pid_t pid, char **slice) { assert_return(pid >= 0, -EINVAL); assert_return(slice, -EINVAL); +#if 0 /// elogind does not support systemd slices return cg_pid_get_user_slice(pid, slice); +#else + return -ESRCH; +#endif // 0 } _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) { @@ -88,7 +130,37 @@ _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) { assert_return(pid >= 0, -EINVAL); assert_return(uid, -EINVAL); +#if 0 /// elogind does not support systemd slices return cg_pid_get_owner_uid(pid, uid); +#else + return -ESRCH; +#endif // 0 +} + +_public_ int sd_pid_get_cgroup(pid_t pid, char **cgroup) { + char *c; + int r; + + assert_return(pid >= 0, -EINVAL); + assert_return(cgroup, -EINVAL); + + r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &c); + if (r < 0) + return r; + + /* The internal APIs return the empty string for the root + * cgroup, let's return the "/" in the public APIs instead, as + * that's easier and less ambigious for people to grok. */ + if (isempty(c)) { + free(c); + c = strdup("/"); + if (!c) + return -ENOMEM; + + } + + *cgroup = c; + return 0; } _public_ int sd_peer_get_session(int fd, char **session) { @@ -102,7 +174,11 @@ _public_ int sd_peer_get_session(int fd, char **session) { if (r < 0) return r; +#if 0 /// elogind does not support systemd scopes return cg_pid_get_session(ucred.pid, session); +#else + return -ESRCH; +#endif // 0 } _public_ int sd_peer_get_owner_uid(int fd, uid_t *uid) { @@ -116,7 +192,11 @@ _public_ int sd_peer_get_owner_uid(int fd, uid_t *uid) { if (r < 0) return r; +#if 0 /// elogind does not support systemd units return cg_pid_get_owner_uid(ucred.pid, uid); +#else + return -ESRCH; +#endif // 0 } _public_ int sd_peer_get_unit(int fd, char **unit) { @@ -130,7 +210,11 @@ _public_ int sd_peer_get_unit(int fd, char **unit) { if (r < 0) return r; +#if 0 /// elogind does not support systemd units return cg_pid_get_unit(ucred.pid, unit); +#else + return -ESRCH; +#endif // 0 } _public_ int sd_peer_get_user_unit(int fd, char **unit) { @@ -144,7 +228,11 @@ _public_ int sd_peer_get_user_unit(int fd, char **unit) { if (r < 0) return r; +#if 0 /// elogind does not support systemd units return cg_pid_get_user_unit(ucred.pid, unit); +#else + return -ESRCH; +#endif // 0 } _public_ int sd_peer_get_machine_name(int fd, char **machine) { @@ -158,7 +246,11 @@ _public_ int sd_peer_get_machine_name(int fd, char **machine) { if (r < 0) return r; +#if 0 /// elogind does not support systemd units return cg_pid_get_machine_name(ucred.pid, machine); +#else + return -ESRCH; +#endif // 0 } _public_ int sd_peer_get_slice(int fd, char **slice) { @@ -172,7 +264,11 @@ _public_ int sd_peer_get_slice(int fd, char **slice) { if (r < 0) return r; +#if 0 /// elogind does not support systemd slices return cg_pid_get_slice(ucred.pid, slice); +#else + return -ESRCH; +#endif // 0 } _public_ int sd_peer_get_user_slice(int fd, char **slice) { @@ -186,10 +282,30 @@ _public_ int sd_peer_get_user_slice(int fd, char **slice) { if (r < 0) return r; +#if 0 /// elogind does not support systemd slices return cg_pid_get_user_slice(ucred.pid, slice); +#else + return -ESRCH; +#endif // 0 +} + +_public_ int sd_peer_get_cgroup(int fd, char **cgroup) { + struct ucred ucred; + int r; + + assert_return(fd >= 0, -EBADF); + assert_return(cgroup, -EINVAL); + + r = getpeercred(fd, &ucred); + if (r < 0) + return r; + + return sd_pid_get_cgroup(ucred.pid, cgroup); } static int file_of_uid(uid_t uid, char **p) { + + assert_return(uid_is_valid(uid), -EINVAL); assert(p); if (asprintf(p, "/run/systemd/users/" UID_FMT, uid) < 0) @@ -203,7 +319,6 @@ _public_ int sd_uid_get_state(uid_t uid, char**state) { char *s = NULL; int r; - assert_return(uid_is_valid(uid), -EINVAL); assert_return(state, -EINVAL); r = file_of_uid(uid, &p); @@ -217,11 +332,15 @@ _public_ int sd_uid_get_state(uid_t uid, char**state) { if (!s) return -ENOMEM; - } else if (r < 0) { + } + if (r < 0) { free(s); return r; - } else if (!s) + } + if (isempty(s)) { + free(s); return -EIO; + } *state = s; return 0; @@ -231,7 +350,6 @@ _public_ int sd_uid_get_display(uid_t uid, char **session) { _cleanup_free_ char *p = NULL, *s = NULL; int r; - assert_return(uid_is_valid(uid), -EINVAL); assert_return(session, -EINVAL); r = file_of_uid(uid, &p); @@ -240,12 +358,11 @@ _public_ int sd_uid_get_display(uid_t uid, char **session) { r = parse_env_file(p, NEWLINE, "DISPLAY", &s, NULL); if (r == -ENOENT) - return -ENXIO; + return -ENODATA; if (r < 0) return r; - if (isempty(s)) - return -ENXIO; + return -ENODATA; *session = s; s = NULL; @@ -253,6 +370,35 @@ _public_ int sd_uid_get_display(uid_t uid, char **session) { return 0; } +static int file_of_seat(const char *seat, char **_p) { + char *p; + int r; + + assert(_p); + + if (seat) { + if (!filename_is_valid(seat)) + return -EINVAL; + + p = strappend("/run/systemd/seats/", seat); + } else { + _cleanup_free_ char *buf = NULL; + + r = sd_session_get_seat(NULL, &buf); + if (r < 0) + return r; + + p = strappend("/run/systemd/seats/", buf); + } + + if (!p) + return -ENOMEM; + + *_p = p; + p = NULL; + return 0; +} + _public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) { _cleanup_free_ char *t = NULL, *s = NULL, *p = NULL; size_t l; @@ -260,29 +406,27 @@ _public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) const char *word, *variable, *state; assert_return(uid_is_valid(uid), -EINVAL); - assert_return(seat, -EINVAL); - variable = require_active ? "ACTIVE_UID" : "UIDS"; + r = file_of_seat(seat, &p); + if (r < 0) + return r; - p = strappend("/run/systemd/seats/", seat); - if (!p) - return -ENOMEM; + variable = require_active ? "ACTIVE_UID" : "UIDS"; r = parse_env_file(p, NEWLINE, variable, &s, NULL); - + if (r == -ENOENT) + return 0; if (r < 0) return r; - - if (!s) - return -EIO; + if (isempty(s)) + return 0; if (asprintf(&t, UID_FMT, uid) < 0) return -ENOMEM; - FOREACH_WORD(word, l, s, state) { + FOREACH_WORD(word, l, s, state) if (strneq(t, word, l)) return 1; - } return 0; } @@ -292,33 +436,22 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { char **a; int r; - assert_return(uid_is_valid(uid), -EINVAL); + assert(variable); r = file_of_uid(uid, &p); if (r < 0) return r; - r = parse_env_file(p, NEWLINE, - variable, &s, - NULL); - if (r < 0) { - if (r == -ENOENT) { + r = parse_env_file(p, NEWLINE, variable, &s, NULL); + if (r == -ENOENT || (r >= 0 && isempty(s))) { if (array) *array = NULL; return 0; } - + if (r < 0) return r; - } - - if (!s) { - if (array) - *array = NULL; - return 0; - } a = strv_split(s, " "); - if (!a) return -ENOMEM; @@ -380,37 +513,39 @@ static int file_of_session(const char *session, char **_p) { } _public_ int sd_session_is_active(const char *session) { - int r; _cleanup_free_ char *p = NULL, *s = NULL; + int r; r = file_of_session(session, &p); if (r < 0) return r; r = parse_env_file(p, NEWLINE, "ACTIVE", &s, NULL); + if (r == -ENOENT) + return -ENXIO; if (r < 0) return r; - - if (!s) + if (isempty(s)) return -EIO; return parse_boolean(s); } _public_ int sd_session_is_remote(const char *session) { - int r; _cleanup_free_ char *p = NULL, *s = NULL; + int r; r = file_of_session(session, &p); if (r < 0) return r; r = parse_env_file(p, NEWLINE, "REMOTE", &s, NULL); + if (r == -ENOENT) + return -ENXIO; if (r < 0) return r; - - if (!s) - return -EIO; + if (isempty(s)) + return -ENODATA; return parse_boolean(s); } @@ -426,9 +561,11 @@ _public_ int sd_session_get_state(const char *session, char **state) { return r; r = parse_env_file(p, NEWLINE, "STATE", &s, NULL); + if (r == -ENOENT) + return -ENXIO; if (r < 0) return r; - else if (!s) + if (isempty(s)) return -EIO; *state = s; @@ -448,10 +585,11 @@ _public_ int sd_session_get_uid(const char *session, uid_t *uid) { return r; r = parse_env_file(p, NEWLINE, "UID", &s, NULL); + if (r == -ENOENT) + return -ENXIO; if (r < 0) return r; - - if (!s) + if (isempty(s)) return -EIO; return parse_uid(s, uid); @@ -462,17 +600,19 @@ static int session_get_string(const char *session, const char *field, char **val int r; assert_return(value, -EINVAL); + assert(field); r = file_of_session(session, &p); if (r < 0) return r; r = parse_env_file(p, NEWLINE, field, &s, NULL); + if (r == -ENOENT) + return -ENXIO; if (r < 0) return r; - if (isempty(s)) - return -ENXIO; + return -ENODATA; *value = s; s = NULL; @@ -492,6 +632,8 @@ _public_ int sd_session_get_vt(const char *session, unsigned *vtnr) { unsigned u; int r; + assert_return(vtnr, -EINVAL); + r = session_get_string(session, "VTNR", &vtnr_string); if (r < 0) return r; @@ -547,32 +689,6 @@ _public_ int sd_session_get_remote_host(const char *session, char **remote_host) return session_get_string(session, "REMOTE_HOST", remote_host); } -static int file_of_seat(const char *seat, char **_p) { - char *p; - int r; - - assert(_p); - - if (seat) - p = strappend("/run/systemd/seats/", seat); - else { - _cleanup_free_ char *buf = NULL; - - r = sd_session_get_seat(NULL, &buf); - if (r < 0) - return r; - - p = strappend("/run/systemd/seats/", buf); - } - - if (!p) - return -ENOMEM; - - *_p = p; - p = NULL; - return 0; -} - _public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) { _cleanup_free_ char *p = NULL, *s = NULL, *t = NULL; int r; @@ -587,14 +703,16 @@ _public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) { "ACTIVE", &s, "ACTIVE_UID", &t, NULL); + if (r == -ENOENT) + return -ENXIO; if (r < 0) return r; if (session && !s) - return -ENOENT; + return -ENODATA; if (uid && !t) - return -ENOENT; + return -ENODATA; if (uid && t) { r = parse_uid(t, uid); @@ -625,7 +743,8 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui "SESSIONS", &s, "ACTIVE_SESSIONS", &t, NULL); - + if (r == -ENOENT) + return -ENXIO; if (r < 0) return r; @@ -657,7 +776,6 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui return -ENOMEM; r = parse_uid(k, b + i); - if (r < 0) continue; @@ -688,7 +806,7 @@ static int seat_get_can(const char *seat, const char *variable) { _cleanup_free_ char *p = NULL, *s = NULL; int r; - assert_return(variable, -EINVAL); + assert(variable); r = file_of_seat(seat, &p); if (r < 0) @@ -697,10 +815,12 @@ static int seat_get_can(const char *seat, const char *variable) { r = parse_env_file(p, NEWLINE, variable, &s, NULL); + if (r == -ENOENT) + return -ENXIO; if (r < 0) return r; - if (!s) - return 0; + if (isempty(s)) + return -ENODATA; return parse_boolean(s); } @@ -824,6 +944,8 @@ _public_ int sd_machine_get_class(const char *machine, char **class) { p = strjoina("/run/systemd/machines/", machine); r = parse_env_file(p, NEWLINE, "CLASS", &c, NULL); + if (r == -ENOENT) + return -ENXIO; if (r < 0) return r; if (!c) @@ -847,6 +969,8 @@ _public_ int sd_machine_get_ifindices(const char *machine, int **ifindices) { p = strjoina("/run/systemd/machines/", machine); r = parse_env_file(p, NEWLINE, "NETIF", &netif, NULL); + if (r == -ENOENT) + return -ENXIO; if (r < 0) return r; if (!netif) { @@ -860,9 +984,7 @@ _public_ int sd_machine_get_ifindices(const char *machine, int **ifindices) { *(char*) (mempcpy(buf, word, l)) = 0; - if (safe_atoi(buf, &ifi) < 0) - continue; - if (ifi <= 0) + if (parse_ifindex(buf, &ifi) < 0) continue; if (!GREEDY_REALLOC(ni, allocated, nr+1)) {