diff --git a/Makefile-man.am b/Makefile-man.am index 65287371b9..ab68c81b1d 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -1937,6 +1937,7 @@ MANPAGES_ALIAS += \ man/sd_login_monitor_get_fd.3 \ man/sd_login_monitor_get_timeout.3 \ man/sd_login_monitor_unref.3 \ + man/sd_peer_get_cgroup.3 \ man/sd_peer_get_machine_name.3 \ man/sd_peer_get_owner_uid.3 \ man/sd_peer_get_session.3 \ @@ -1944,6 +1945,7 @@ MANPAGES_ALIAS += \ man/sd_peer_get_unit.3 \ man/sd_peer_get_user_slice.3 \ man/sd_peer_get_user_unit.3 \ + man/sd_pid_get_cgroup.3 \ man/sd_pid_get_machine_name.3 \ man/sd_pid_get_owner_uid.3 \ man/sd_pid_get_slice.3 \ @@ -1981,6 +1983,7 @@ man/sd_login_monitor_get_events.3: man/sd_login_monitor_new.3 man/sd_login_monitor_get_fd.3: man/sd_login_monitor_new.3 man/sd_login_monitor_get_timeout.3: man/sd_login_monitor_new.3 man/sd_login_monitor_unref.3: man/sd_login_monitor_new.3 +man/sd_peer_get_cgroup.3: man/sd_pid_get_session.3 man/sd_peer_get_machine_name.3: man/sd_pid_get_session.3 man/sd_peer_get_owner_uid.3: man/sd_pid_get_session.3 man/sd_peer_get_session.3: man/sd_pid_get_session.3 @@ -1988,6 +1991,7 @@ man/sd_peer_get_slice.3: man/sd_pid_get_session.3 man/sd_peer_get_unit.3: man/sd_pid_get_session.3 man/sd_peer_get_user_slice.3: man/sd_pid_get_session.3 man/sd_peer_get_user_unit.3: man/sd_pid_get_session.3 +man/sd_pid_get_cgroup.3: man/sd_pid_get_session.3 man/sd_pid_get_machine_name.3: man/sd_pid_get_session.3 man/sd_pid_get_owner_uid.3: man/sd_pid_get_session.3 man/sd_pid_get_slice.3: man/sd_pid_get_session.3 @@ -2043,6 +2047,9 @@ man/sd_login_monitor_get_timeout.html: man/sd_login_monitor_new.html man/sd_login_monitor_unref.html: man/sd_login_monitor_new.html $(html-alias) +man/sd_peer_get_cgroup.html: man/sd_pid_get_session.html + $(html-alias) + man/sd_peer_get_machine_name.html: man/sd_pid_get_session.html $(html-alias) @@ -2064,6 +2071,9 @@ man/sd_peer_get_user_slice.html: man/sd_pid_get_session.html man/sd_peer_get_user_unit.html: man/sd_pid_get_session.html $(html-alias) +man/sd_pid_get_cgroup.html: man/sd_pid_get_session.html + $(html-alias) + man/sd_pid_get_machine_name.html: man/sd_pid_get_session.html $(html-alias) diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml index 903c143f36..035effcaa9 100644 --- a/man/sd_pid_get_session.xml +++ b/man/sd_pid_get_session.xml @@ -50,6 +50,7 @@ sd_pid_get_machine_name sd_pid_get_slice sd_pid_get_user_slice + sd_pid_get_cgroup sd_peer_get_session sd_peer_get_unit sd_peer_get_user_unit @@ -57,6 +58,7 @@ sd_peer_get_machine_name sd_peer_get_slice sd_peer_get_user_slice + sd_peer_get_cgroup Determine session, unit, owner of a session, container/VM or slice of a specific PID or socket peer @@ -108,6 +110,12 @@ char **slice + + int sd_pid_get_cgroup + pid_t pid + char **cgroup + + int sd_peer_get_session int fd @@ -149,6 +157,12 @@ int fd char **slice + + + int sd_peer_get_cgroup + int fd + char **cgroup + @@ -217,6 +231,17 @@ returns the user slice (as managed by the user's systemd instance) of a process. + sd_pid_get_cgroup() returns the control + group path of the specified process, relative to the root of the + hierarchy. Returns the path without trailing slash, except for + processes located in the root control group, where "/" is + returned. To find the actual control group path in the file system + the returned path needs to be prefixed with + /sys/fs/cgroup/ (if the unified control group + setup is used), or + /sys/fs/cgroup/HIERARCHY/ + (if the legacy multi-hierarchy control group setup is used). + If the pid parameter of any of these functions is passed as 0, the operation is executed for the calling process. @@ -226,13 +251,14 @@ sd_peer_get_user_unit(), sd_peer_get_owner_uid(), sd_peer_get_machine_name(), - sd_peer_get_slice() and - sd_peer_get_user_slice() calls operate - similar to their PID counterparts, but operate on a connected - AF_UNIX socket and retrieve information about the connected peer - process. Note that these fields are retrieved via - /proc, and hence are not suitable for - authorization purposes, as they are subject to races. + sd_peer_get_slice(), + sd_peer_get_user_slice() and + sd_peer_get_cgroup() calls operate similar to + their PID counterparts, but operate on a connected AF_UNIX socket + and retrieve information about the connected peer process. Note + that these fields are retrieved via /proc, + and hence are not suitable for authorization purposes, as they are + subject to races. diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 7bf1d66dde..d5ad127bcb 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -467,3 +467,9 @@ global: sd_bus_emit_object_removed; sd_bus_flush_close_unref; } LIBSYSTEMD_221; + +LIBSYSTEMD_226 { +global: + sd_pid_get_cgroup; + sd_peer_get_cgroup; +} LIBSYSTEMD_222; diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index 180bdd09ad..55da26e9d9 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -101,6 +101,32 @@ _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) { return cg_pid_get_owner_uid(pid, uid); } +_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) { struct ucred ucred = {}; int r; @@ -199,6 +225,20 @@ _public_ int sd_peer_get_user_slice(int fd, char **slice) { return cg_pid_get_user_slice(ucred.pid, slice); } +_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); diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c index 70b0345848..f734ce9eee 100644 --- a/src/libsystemd/sd-login/test-login.c +++ b/src/libsystemd/sd-login/test-login.c @@ -33,7 +33,7 @@ static void test_login(void) { _cleanup_free_ char *pp = NULL, *qq = NULL; int r, k; uid_t u, u2; - char *seat, *type, *class, *display, *remote_user, *remote_host, *display_session; + char *seat, *type, *class, *display, *remote_user, *remote_host, *display_session, *cgroup; char *session; char *state; char *session2; @@ -50,6 +50,10 @@ static void test_login(void) { assert_se(sd_pid_get_owner_uid(0, &u2) == 0); printf("user = "UID_FMT"\n", u2); + assert_se(sd_pid_get_cgroup(0, &cgroup) == 0); + printf("cgroup = %s\n", cgroup); + free(cgroup); + display_session = NULL; r = sd_uid_get_display(u2, &display_session); assert_se(r >= 0 || r == -ENODATA); diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h index 9260396d5d..39b68c3895 100644 --- a/src/systemd/sd-login.h +++ b/src/systemd/sd-login.h @@ -81,6 +81,10 @@ int sd_pid_get_user_slice(pid_t pid, char **slice); * container. This will return an error for non-machine processes. */ int sd_pid_get_machine_name(pid_t pid, char **machine); +/* Get the control group from a PID, relative to the root of the + * hierarchy. */ +int sd_pid_get_cgroup(pid_t pid, char **cgroup); + /* Similar to sd_pid_get_session(), but retrieves data about peer of * connected AF_UNIX socket */ int sd_peer_get_session(int fd, char **session); @@ -109,6 +113,10 @@ int sd_peer_get_user_slice(int fd, char **slice); * of connected AF_UNIX socket */ int sd_peer_get_machine_name(int fd, char **machine); +/* Similar to sd_pid_get_cgroup(), but retrieves data about the peer + * of a connected AF_UNIX socket. */ +int sd_peer_get_cgroup(pid_t pid, char **cgroup); + /* Get state from UID. Possible states: offline, lingering, online, active, closing */ int sd_uid_get_state(uid_t uid, char **state);