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.
This commit is contained in:
Lennart Poettering 2014-03-17 18:14:26 +01:00
parent 7366b080b3
commit bf34ab149f
6 changed files with 218 additions and 12 deletions

View 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)

View File

@ -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>

View 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 */

View 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;

View 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));

View 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);