X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flogin%2Fsd-login.c;h=66c4487ff88ff6a3f37f6fe117816cb540530579;hb=38158b920e772ea3a7cc9dfcf705666ce3aa5ce3;hp=c97d75c000f5883b425b0c321a06da2aa7996c7f;hpb=7027ff61a34a12487712b382a061c654acc3a679;p=elogind.git diff --git a/src/login/sd-login.c b/src/login/sd-login.c index c97d75c00..66c4487ff 100644 --- a/src/login/sd-login.c +++ b/src/login/sd-login.c @@ -73,9 +73,6 @@ _public_ int sd_pid_get_machine_name(pid_t pid, char **name) { } _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) { - int r; - char *root, *cgroup, *p, *cc; - struct stat st; if (pid < 0) return -EINVAL; @@ -83,44 +80,7 @@ _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) { if (!uid) return -EINVAL; - r = cg_pid_get_path_shifted(pid, &root, &cgroup); - if (r < 0) - return r; - - if (!startswith(cgroup, "/user/")) { - free(cgroup); - free(root); - return -ENOENT; - } - - p = strchr(cgroup + 6, '/'); - if (!p) { - free(cgroup); - return -ENOENT; - } - - p++; - p += strcspn(p, "/"); - *p = 0; - - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, root, cgroup, &cc); - free(root); - free(cgroup); - - if (r < 0) - return -ENOMEM; - - r = lstat(cc, &st); - free(cc); - - if (r < 0) - return -errno; - - if (!S_ISDIR(st.st_mode)) - return -ENOTDIR; - - *uid = st.st_uid; - return 0; + return cg_pid_get_owner_uid(pid, uid); } _public_ int sd_uid_get_state(uid_t uid, char**state) { @@ -155,7 +115,8 @@ _public_ int sd_uid_get_state(uid_t uid, char**state) { } _public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) { - char *p, *w, *t, *state, *s = NULL; + char *w, *state; + _cleanup_free_ char *t = NULL, *s = NULL, *p = NULL; size_t l; int r; const char *variable; @@ -170,38 +131,26 @@ _public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) return -ENOMEM; r = parse_env_file(p, NEWLINE, variable, &s, NULL); - free(p); - if (r < 0) { - free(s); + if (r < 0) return r; - } if (!s) return -EIO; - if (asprintf(&t, "%lu", (unsigned long) uid) < 0) { - free(s); + if (asprintf(&t, "%lu", (unsigned long) uid) < 0) return -ENOMEM; - } FOREACH_WORD(w, l, s, state) { - if (strneq(t, w, l)) { - free(s); - free(t); - + if (strneq(t, w, l)) return 1; - } } - free(s); - free(t); - return 0; } static int uid_get_array(uid_t uid, const char *variable, char ***array) { - char *p, *s = NULL; + _cleanup_free_ char *p = NULL, *s = NULL; char **a; int r; @@ -211,11 +160,7 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { r = parse_env_file(p, NEWLINE, variable, &s, NULL); - free(p); - if (r < 0) { - free(s); - if (r == -ENOENT) { if (array) *array = NULL; @@ -232,7 +177,6 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { } a = strv_split(s, " "); - free(s); if (!a) return -ENOMEM; @@ -294,31 +238,27 @@ static int file_of_session(const char *session, char **_p) { _public_ int sd_session_is_active(const char *session) { int r; - char *p, *s = NULL; + _cleanup_free_ char *p = NULL, *s = NULL; r = file_of_session(session, &p); if (r < 0) return r; r = parse_env_file(p, NEWLINE, "ACTIVE", &s, NULL); - free(p); - if (r < 0) { - free(s); + if (r < 0) return r; - } if (!s) return -EIO; r = parse_boolean(s); - free(s); return r; } _public_ int sd_session_get_state(const char *session, char **state) { - char *p, *s = NULL; + _cleanup_free_ char *p = NULL, *s = NULL; int r; if (!state) @@ -329,21 +269,21 @@ _public_ int sd_session_get_state(const char *session, char **state) { return r; r = parse_env_file(p, NEWLINE, "STATE", &s, NULL); - free(p); - if (r < 0) { - free(s); + if (r < 0) return r; - } else if (!s) + else if (!s) return -EIO; *state = s; + s = NULL; + return 0; } _public_ int sd_session_get_uid(const char *session, uid_t *uid) { int r; - char *p, *s = NULL; + _cleanup_free_ char *p = NULL, *s = NULL; if (!uid) return -EINVAL; @@ -353,24 +293,20 @@ _public_ int sd_session_get_uid(const char *session, uid_t *uid) { return r; r = parse_env_file(p, NEWLINE, "UID", &s, NULL); - free(p); - if (r < 0) { - free(s); + if (r < 0) return r; - } if (!s) return -EIO; r = parse_uid(s, uid); - free(s); return r; } static int session_get_string(const char *session, const char *field, char **value) { - char *p, *s = NULL; + _cleanup_free_ char *p = NULL, *s = NULL; int r; if (!value) @@ -381,17 +317,15 @@ static int session_get_string(const char *session, const char *field, char **val return r; r = parse_env_file(p, NEWLINE, field, &s, NULL); - free(p); - if (r < 0) { - free(s); + if (r < 0) return r; - } if (isempty(s)) return -ENOENT; *value = s; + s = NULL; return 0; } @@ -428,25 +362,25 @@ static int file_of_seat(const char *seat, char **_p) { if (seat) p = strappend("/run/systemd/seats/", seat); else { - char *buf; + _cleanup_free_ char *buf = NULL; r = sd_session_get_seat(NULL, &buf); if (r < 0) return r; p = strappend("/run/systemd/seats/", buf); - free(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) { - char *p, *s = NULL, *t = NULL; + _cleanup_free_ char *p = NULL, *s = NULL, *t = NULL; int r; if (!session && !uid) @@ -460,46 +394,33 @@ _public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) { "ACTIVE", &s, "ACTIVE_UID", &t, NULL); - free(p); - - if (r < 0) { - free(s); - free(t); + if (r < 0) return r; - } - if (session && !s) { - free(t); + if (session && !s) return -ENOENT; - } - if (uid && !t) { - free(s); + if (uid && !t) return -ENOENT; - } if (uid && t) { r = parse_uid(t, uid); - if (r < 0) { - free(t); - free(s); + if (r < 0) return r; - } } - free(t); - - if (session && s) + if (session && s) { *session = s; - else - free(s); + s = NULL; + } return 0; } _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uids, unsigned *n_uids) { - char *p, *s = NULL, *t = NULL, **a = NULL; - uid_t *b = NULL; + _cleanup_free_ char *p = NULL, *s = NULL, *t = NULL; + _cleanup_strv_free_ char **a = NULL; + _cleanup_free_ uid_t *b = NULL; unsigned n = 0; int r; @@ -511,25 +432,16 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui "SESSIONS", &s, "ACTIVE_SESSIONS", &t, NULL); - free(p); - if (r < 0) { - free(s); - free(t); + if (r < 0) return r; - } if (s) { a = strv_split(s, " "); - if (!a) { - free(s); - free(t); + if (!a) return -ENOMEM; - } } - free(s); - if (uids && t) { char *w, *state; size_t l; @@ -537,30 +449,22 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui FOREACH_WORD(w, l, t, state) n++; - if (n == 0) - b = NULL; - else { + if (n > 0) { unsigned i = 0; b = new(uid_t, n); - if (!b) { - strv_free(a); + if (!b) return -ENOMEM; - } FOREACH_WORD(w, l, t, state) { - char *k; + _cleanup_free_ char *k = NULL; k = strndup(w, l); - if (!k) { - free(t); - free(b); - strv_free(a); + if (!k) return -ENOMEM; - } r = parse_uid(k, b + i); - free(k); + if (r < 0) continue; @@ -569,17 +473,17 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui } } - free(t); - r = strv_length(a); - if (sessions) + if (sessions) { *sessions = a; - else - strv_free(a); + a = NULL; + } - if (uids) + if (uids) { *uids = b; + b = NULL; + } if (n_uids) *n_uids = n; @@ -588,7 +492,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui } static int seat_get_can(const char *seat, const char *variable) { - char *p, *s = NULL; + _cleanup_free_ char *p = NULL, *s = NULL; int r; r = file_of_seat(seat, &p); @@ -598,17 +502,12 @@ static int seat_get_can(const char *seat, const char *variable) { r = parse_env_file(p, NEWLINE, variable, &s, NULL); - free(p); - - if (r < 0) { - free(s); + if (r < 0) return r; - } - if (s) { + if (s) r = parse_boolean(s); - free(s); - } else + else r = 0; return r; @@ -635,10 +534,10 @@ _public_ int sd_get_sessions(char ***sessions) { } _public_ int sd_get_uids(uid_t **users) { - DIR *d; + _cleanup_closedir_ DIR *d; int r = 0; unsigned n = 0; - uid_t *l = NULL; + _cleanup_free_ uid_t *l = NULL; d = opendir("/run/systemd/users/"); if (!d) @@ -651,10 +550,8 @@ _public_ int sd_get_uids(uid_t **users) { uid_t uid; k = readdir_r(d, &buf.de, &de); - if (k != 0) { - r = -k; - goto finish; - } + if (k != 0) + return -k; if (!de) break; @@ -674,10 +571,8 @@ _public_ int sd_get_uids(uid_t **users) { n = MAX(16, 2*r); t = realloc(l, sizeof(uid_t) * n); - if (!t) { - r = -ENOMEM; - goto finish; - } + if (!t) + return -ENOMEM; l = t; } @@ -688,19 +583,51 @@ _public_ int sd_get_uids(uid_t **users) { r++; } -finish: - if (d) - closedir(d); - - if (r >= 0) { - if (users) - *users = l; - } else - free(l); + if (users) { + *users = l; + l = NULL; + } return r; } +int sd_get_machine_names(char ***machines) { + _cleanup_closedir_ DIR *d = NULL; + _cleanup_strv_free_ char **l = NULL; + _cleanup_free_ char *md = NULL; + char *n; + int c = 0, r; + + r = cg_get_machine_path(NULL, &md); + if (r < 0) + return r; + + r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, md, &d); + if (r < 0) + return r; + + while ((r = cg_read_subgroup(d, &n)) > 0) { + + r = strv_push(&l, n); + if (r < 0) { + free(n); + return -ENOMEM; + } + + c++; + } + + if (r < 0) + return r; + + if (machines) { + *machines = l; + l = NULL; + } + + return c; +} + static inline int MONITOR_TO_FD(sd_login_monitor *m) { return (int) (unsigned long) m - 1; } @@ -750,6 +677,27 @@ _public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) { good = true; } + if (!category || streq(category, "machine")) { + _cleanup_free_ char *md = NULL, *p = NULL; + int r; + + r = cg_get_machine_path(NULL, &md); + if (r < 0) + return r; + + r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, md, NULL, &p); + if (r < 0) + return r; + + k = inotify_add_watch(fd, p, IN_MOVED_TO|IN_CREATE|IN_DELETE); + if (k < 0) { + close_nointr_nofail(fd); + return -errno; + } + + good = true; + } + if (!good) { close_nointr(fd); return -EINVAL;