chiark / gitweb /
sd-login: add calls that retrieve credentials of peers connected to AF_UNIX peers
authorLennart Poettering <lennart@poettering.net>
Mon, 17 Mar 2014 17:14:26 +0000 (18:14 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 17 Mar 2014 17:15:57 +0000 (18:15 +0100)
This is supposed to be an extension of SO_PEERCRED and SO_PEERSEC,
except for cgroup information.

Makefile-man.am
man/sd_pid_get_session.xml
src/libsystemd/libsystemd.sym.m4
src/login/sd-login.c
src/login/test-login.c
src/systemd/sd-login.h

index 8a4ee9d17917377775fda886c24e1641aa121937..079ba63e7eaa30dd9b92405240682be1257ed921 100644 (file)
@@ -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)
 
index 1e762f450b334fba6e40a782633a508fda581dfd..a8266e02062f222bff09a9f9e7d0637f678fa876 100644 (file)
                 <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>
                                 <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>
 
                 <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>
                 <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>
 
index 290eabe1a0733e5be64389691dbe7d42e6e50a05..e9c42d0044f6f073cb74f9011e49ede8cf0b9211 100644 (file)
@@ -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 */
index 4ad250eb37e0338aaea0f2cf08cc19dfadbe5f1a..d24b2ed1fdd698f1b62bc04d5cdbe54b89c20df4 100644 (file)
@@ -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;
index d78cea46af9a8a5efd0090025070b71a8957086b..2ab083bb71960b447acda01b082fdd3a67fb72ae 100644 (file)
@@ -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));
index d6cfbc31333ea6741405f1756bb2c5e52044db9d..87ebafb26445e91905420d82198992d9d148a8c4 100644 (file)
@@ -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);