diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-03-17 18:14:26 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-03-17 18:15:57 +0100 |
commit | bf34ab149f3038686bc75e1592179abac1700322 (patch) | |
tree | 42a953b9e17ef1614a890f699f245c84bd6a831b | |
parent | 7366b080b324caf66e2ca1671f8ce7f57ace7553 (diff) |
sd-login: add calls that retrieve credentials of peers connected to AF_UNIX peers
This is supposed to be an extension of SO_PEERCRED and SO_PEERSEC,
except for cgroup information.
-rw-r--r-- | Makefile-man.am | 30 | ||||
-rw-r--r-- | man/sd_pid_get_session.xml | 68 | ||||
-rw-r--r-- | src/libsystemd/libsystemd.sym.m4 | 6 | ||||
-rw-r--r-- | src/login/sd-login.c | 91 | ||||
-rw-r--r-- | src/login/test-login.c | 7 | ||||
-rw-r--r-- | src/systemd/sd-login.h | 28 |
6 files changed, 218 insertions, 12 deletions
diff --git a/Makefile-man.am b/Makefile-man.am index 8a4ee9d179..079ba63e7e 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -1179,6 +1179,12 @@ 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_machine_name.3 \ + man/sd_peer_get_owner_uid.3 \ + man/sd_peer_get_session.3 \ + man/sd_peer_get_slice.3 \ + man/sd_peer_get_unit.3 \ + man/sd_peer_get_user_unit.3 \ man/sd_pid_get_machine_name.3 \ man/sd_pid_get_owner_uid.3 \ man/sd_pid_get_slice.3 \ @@ -1213,6 +1219,12 @@ 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_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 +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_unit.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 @@ -1265,6 +1277,24 @@ 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_machine_name.html: man/sd_pid_get_session.html + $(html-alias) + +man/sd_peer_get_owner_uid.html: man/sd_pid_get_session.html + $(html-alias) + +man/sd_peer_get_session.html: man/sd_pid_get_session.html + $(html-alias) + +man/sd_peer_get_slice.html: man/sd_pid_get_session.html + $(html-alias) + +man/sd_peer_get_unit.html: man/sd_pid_get_session.html + $(html-alias) + +man/sd_peer_get_user_unit.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 1e762f450b..a8266e0206 100644 --- a/man/sd_pid_get_session.xml +++ b/man/sd_pid_get_session.xml @@ -49,9 +49,15 @@ <refname>sd_pid_get_owner_uid</refname> <refname>sd_pid_get_machine_name</refname> <refname>sd_pid_get_slice</refname> + <refname>sd_peer_get_session</refname> + <refname>sd_peer_get_unit</refname> + <refname>sd_peer_get_user_unit</refname> + <refname>sd_peer_get_owner_uid</refname> + <refname>sd_peer_get_machine_name</refname> + <refname>sd_peer_get_slice</refname> <refpurpose>Determine session, service, owner of a session, container/VM or slice of a specific - PID</refpurpose> + PID or socket peer</refpurpose> </refnamediv> <refsynopsisdiv> @@ -93,6 +99,42 @@ <paramdef>pid_t <parameter>pid</parameter></paramdef> <paramdef>char** <parameter>slice</parameter></paramdef> </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_peer_get_session</function></funcdef> + <paramdef>int <parameter>fd</parameter></paramdef> + <paramdef>char** <parameter>session</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_peer_get_unit</function></funcdef> + <paramdef>int <parameter>fd</parameter></paramdef> + <paramdef>char** <parameter>unit</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_peer_get_user_unit</function></funcdef> + <paramdef>int <parameter>fd</parameter></paramdef> + <paramdef>char** <parameter>unit</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_peer_get_owner_uid</function></funcdef> + <paramdef>int <parameter>fd</parameter></paramdef> + <paramdef>uid_t* <parameter>uid</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_peer_get_machine_name</function></funcdef> + <paramdef>int <parameter>fd</parameter></paramdef> + <paramdef>char** <parameter>name</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_peer_get_slice</function></funcdef> + <paramdef>int <parameter>fd</parameter></paramdef> + <paramdef>char** <parameter>slice</parameter></paramdef> + </funcprototype> </funcsynopsis> </refsynopsisdiv> @@ -167,6 +209,16 @@ <para>If the <varname>pid</varname> parameter of any of these functions is passed as 0, the operation is executed for the calling process.</para> + + <para>The <function>sd_peer_get_session()</function>, + <function>sd_peer_get_unit()</function>, + <function>sd_peer_get_user_unit()</function>, + <function>sd_peer_get_owner_uid()</function>, + <function>sd_peer_get_machine_name()</function> and + <function>sd_peer_get_slice()</function> calls operate + similar to their PID counterparts, but operate on a + connected AF_UNIX socket and retrieve information + about the connected peer process.</para> </refsect1> <refsect1> @@ -184,10 +236,16 @@ <function>sd_pid_get_unit()</function>, <function>sd_pid_get_user_unit()</function>, <function>sd_pid_get_owner_uid()</function>, - <function>sd_pid_get_machine_name()</function> and - <function>sd_pid_get_slice()</function> interfaces are - available as a shared library, which can be compiled and - linked to with the + <function>sd_pid_get_machine_name()</function>, + <function>sd_pid_get_slice()</function>, + <function>sd_peer_get_session()</function>, + <function>sd_peer_get_unit()</function>, + <function>sd_peer_get_user_unit()</function>, + <function>sd_peer_get_owner_uid()</function>, + <function>sd_peer_get_machine_name()</function> and + <function>sd_peer_get_slice()</function> interfaces are + available as a shared library, which can be compiled + and linked to with the <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry> file.</para> diff --git a/src/libsystemd/libsystemd.sym.m4 b/src/libsystemd/libsystemd.sym.m4 index 290eabe1a0..e9c42d0044 100644 --- a/src/libsystemd/libsystemd.sym.m4 +++ b/src/libsystemd/libsystemd.sym.m4 @@ -129,6 +129,12 @@ local: LIBSYSTEMD_211 { global: sd_machine_get_class; + sd_peer_get_session; + sd_peer_get_owner_uid; + sd_peer_get_unit; + sd_peer_get_user_unit; + sd_peer_get_machine_name; + sd_peer_get_slice; m4_ifdef(`ENABLE_KDBUS', /* sd-bus */ diff --git a/src/login/sd-login.c b/src/login/sd-login.c index 4ad250eb37..d24b2ed1fd 100644 --- a/src/login/sd-login.c +++ b/src/login/sd-login.c @@ -81,8 +81,93 @@ _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) { return cg_pid_get_owner_uid(pid, uid); } +_public_ int sd_peer_get_session(int fd, char **session) { + struct ucred ucred; + int r; + + assert_return(fd >= 0, -EINVAL); + assert_return(session, -EINVAL); + + r = getpeercred(fd, &ucred); + if (r < 0) + return r; + + return cg_pid_get_session(ucred.pid, session); +} + +_public_ int sd_peer_get_owner_uid(int fd, uid_t *uid) { + struct ucred ucred; + int r; + + assert_return(fd >= 0, -EINVAL); + assert_return(uid, -EINVAL); + + r = getpeercred(fd, &ucred); + if (r < 0) + return r; + + return cg_pid_get_owner_uid(ucred.pid, uid); +} + +_public_ int sd_peer_get_unit(int fd, char **unit) { + struct ucred ucred; + int r; + + assert_return(fd >= 0, -EINVAL); + assert_return(unit, -EINVAL); + + r = getpeercred(fd, &ucred); + if (r < 0) + return r; + + return cg_pid_get_unit(ucred.pid, unit); +} + +_public_ int sd_peer_get_user_unit(int fd, char **unit) { + struct ucred ucred; + int r; + + assert_return(fd >= 0, -EINVAL); + assert_return(unit, -EINVAL); + + r = getpeercred(fd, &ucred); + if (r < 0) + return r; + + return cg_pid_get_user_unit(ucred.pid, unit); +} + +_public_ int sd_peer_get_machine_name(int fd, char **machine) { + struct ucred ucred; + int r; + + assert_return(fd >= 0, -EINVAL); + assert_return(machine, -EINVAL); + + r = getpeercred(fd, &ucred); + if (r < 0) + return r; + + return cg_pid_get_machine_name(ucred.pid, machine); +} + +_public_ int sd_peer_get_slice(int fd, char **slice) { + struct ucred ucred; + int r; + + assert_return(fd >= 0, -EINVAL); + assert_return(slice, -EINVAL); + + r = getpeercred(fd, &ucred); + if (r < 0) + return r; + + return cg_pid_get_slice(ucred.pid, slice); +} + _public_ int sd_uid_get_state(uid_t uid, char**state) { - char *p, *s = NULL; + _cleanup_free_ char *p = NULL; + char *s = NULL; int r; assert_return(state, -EINVAL); @@ -91,16 +176,12 @@ _public_ int sd_uid_get_state(uid_t uid, char**state) { 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; diff --git a/src/login/test-login.c b/src/login/test-login.c index d78cea46af..2ab083bb71 100644 --- a/src/login/test-login.c +++ b/src/login/test-login.c @@ -28,6 +28,8 @@ #include "strv.h" static void test_login(void) { + _cleanup_close_pipe_ int pair[2] = { -1, -1 }; + _cleanup_free_ char *pp = NULL, *qq = NULL; int r, k; uid_t u, u2; char *seat, *type, *class, *display, *remote_user, *remote_host; @@ -47,6 +49,11 @@ static void test_login(void) { assert_se(sd_pid_get_owner_uid(0, &u2) == 0); printf("user = %lu\n", (unsigned long) u2); + assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0); + sd_peer_get_session(pair[0], &pp); + sd_peer_get_session(pair[1], &qq); + assert_se(streq_ptr(pp, qq)); + r = sd_uid_get_sessions(u2, false, &sessions); assert_se(r >= 0); assert_se(r == (int) strv_length(sessions)); diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h index d6cfbc3133..87ebafb264 100644 --- a/src/systemd/sd-login.h +++ b/src/systemd/sd-login.h @@ -73,10 +73,34 @@ int sd_pid_get_user_unit(pid_t pid, char **unit); /* Get machine name from PID, for processes assigned to VM or * container. This will return an error for non-machine processes. */ -int sd_pid_get_machine_name(pid_t pid, char **name); +int sd_pid_get_machine_name(pid_t pid, char **machine); /* Get slice name from PID. */ -int sd_pid_get_slice(pid_t pid, char **name); +int sd_pid_get_slice(pid_t pid, char **slice); + +/* 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); + +/* Similar to sd_pid_get_owner_uid(), but retrieves data about peer of + * connected AF_UNIX socket */ +int sd_peer_get_owner_uid(int fd, uid_t *uid); + +/* Similar to sd_pid_get_unit(), but retrieves data about peer of + * connected AF_UNIX socket */ +int sd_peer_get_unit(int fd, char **unit); + +/* Similar to sd_pid_get_user_unit(), but retrieves data about peer of + * connected AF_UNIX socket */ +int sd_peer_get_user_unit(int fd, char **unit); + +/* Similar to sd_pid_get_machine_name(), but retrieves data about peer + * of connected AF_UNIX socket */ +int sd_peer_get_machine_name(int fd, char **machine); + +/* Similar to sd_pid_get_slice(), but retrieves data about peer of + * connected AF_UNIX socket */ +int sd_peer_get_slice(int fd, char **slice); /* Get state from uid. Possible states: offline, lingering, online, active, closing */ int sd_uid_get_state(uid_t uid, char**state); |