]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
socket-util: introduce getpeerpidref()
authorLennart Poettering <lennart@poettering.net>
Tue, 19 Nov 2024 15:35:48 +0000 (16:35 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 6 Jan 2025 08:45:57 +0000 (09:45 +0100)
This combines getpeercred() and getpeerpidfd() and returns a PidRef

src/basic/socket-util.c
src/basic/socket-util.h
src/test/test-socket-util.c

index 94089323b45fc81c7e8bf72795aa37847b8a9e0b..9190072f4e2e6bfc3f9d66b1b2dc3139b04fae6b 100644 (file)
@@ -975,6 +975,28 @@ int getpeerpidfd(int fd) {
         return pidfd;
 }
 
+int getpeerpidref(int fd, PidRef *ret) {
+        int r;
+
+        assert(fd >= 0);
+        assert(ret);
+
+        int pidfd = getpeerpidfd(fd);
+        if (pidfd < 0) {
+                if (!ERRNO_IS_NEG_NOT_SUPPORTED(pidfd))
+                        return pidfd;
+
+                struct ucred ucred;
+                r = getpeercred(fd, &ucred);
+                if (r < 0)
+                        return r;
+
+                return pidref_set_pid(ret, ucred.pid);
+        }
+
+        return pidref_set_pidfd_consume(ret, pidfd);
+}
+
 ssize_t send_many_fds_iov_sa(
                 int transport_fd,
                 int *fds_array, size_t n_fds_array,
index 874e559a4b3e3ff6b520b99aae4d630ce2f1a9aa..e21a4427f0dc1678e6a9039ae596e8c5b73f6f8f 100644 (file)
@@ -20,6 +20,7 @@
 #include "macro.h"
 #include "missing_network.h"
 #include "missing_socket.h"
+#include "pidref.h"
 #include "sparse-endian.h"
 
 union sockaddr_union {
@@ -154,6 +155,7 @@ int getpeercred(int fd, struct ucred *ucred);
 int getpeersec(int fd, char **ret);
 int getpeergroups(int fd, gid_t **ret);
 int getpeerpidfd(int fd);
+int getpeerpidref(int fd, PidRef *ret);
 
 ssize_t send_many_fds_iov_sa(
                 int transport_fd,
index f7b31aeb46f628d169717e1a04fefcf7dee25df9..63bbb1d1d274ae4d661fe31f74282a0ea44564cd 100644 (file)
@@ -584,4 +584,25 @@ TEST(sockaddr_un_set_path) {
         assert_se(connect(fd2, &sa.sa, SOCKADDR_LEN(sa)) >= 0);
 }
 
+TEST(getpeerpidref) {
+        _cleanup_close_pair_ int fd[2] = EBADF_PAIR;
+
+        ASSERT_OK(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fd));
+
+        _cleanup_(pidref_done) PidRef pidref0 = PIDREF_NULL, pidref1 = PIDREF_NULL, pidref_self = PIDREF_NULL, pidref_pid1 = PIDREF_NULL;
+        ASSERT_OK(getpeerpidref(fd[0], &pidref0));
+        ASSERT_OK(getpeerpidref(fd[1], &pidref1));
+
+        ASSERT_OK(pidref_set_self(&pidref_self));
+        ASSERT_OK(pidref_set_pid(&pidref_pid1, 1));
+
+        ASSERT_TRUE(pidref_equal(&pidref0, &pidref1));
+        ASSERT_TRUE(pidref_equal(&pidref0, &pidref_self));
+        ASSERT_TRUE(pidref_equal(&pidref1, &pidref_self));
+
+        ASSERT_TRUE(!pidref_equal(&pidref_self, &pidref_pid1));
+        ASSERT_TRUE(!pidref_equal(&pidref1, &pidref_pid1));
+        ASSERT_TRUE(!pidref_equal(&pidref0, &pidref_pid1));
+}
+
 DEFINE_TEST_MAIN(LOG_DEBUG);