chiark / gitweb /
socket-util: add new getpeergroups() call
authorLennart Poettering <lennart@poettering.net>
Sat, 30 Dec 2017 13:02:36 +0000 (14:02 +0100)
committerSven Eden <yamakuzure@gmx.net>
Wed, 30 May 2018 05:49:52 +0000 (07:49 +0200)
It's a wrapper around the new SO_PEERGROUPS sockopt, similar in style as
getpeersec() and getpeercred().

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

index 5aafa390f468b7f1cdc636730cc44ee81c891011..536fd1114e9fe800dac7407476f578d899fe0a43 100644 (file)
@@ -626,6 +626,10 @@ struct btrfs_ioctl_quota_ctl_args {
 #  define SO_REUSEPORT 15
 #endif
 
+#ifndef SO_PEERGROUPS
+#  define SO_PEERGROUPS 59
+#endif
+
 #ifndef EVIOCREVOKE
 #  define EVIOCREVOKE _IOW('E', 0x91, int)
 #endif
index 5969aa76129494754a12faef139105a2a0c52cbb..ea46477767cd1e9ce3a3de81dd6ecc3086d45fbe 100644 (file)
@@ -1027,6 +1027,39 @@ int getpeersec(int fd, char **ret) {
         return 0;
 }
 
+int getpeergroups(int fd, gid_t **ret) {
+        socklen_t n = sizeof(gid_t) * 64;
+        _cleanup_free_ gid_t *d = NULL;
+
+        assert(fd);
+        assert(ret);
+
+        for (;;) {
+                d = malloc(n);
+                if (!d)
+                        return -ENOMEM;
+
+                if (getsockopt(fd, SOL_SOCKET, SO_PEERGROUPS, d, &n) >= 0)
+                        break;
+
+                if (errno != ERANGE)
+                        return -errno;
+
+                d = mfree(d);
+        }
+
+        assert_se(n % sizeof(gid_t) == 0);
+        n /= sizeof(gid_t);
+
+        if ((socklen_t) (int) n != n)
+                return -E2BIG;
+
+        *ret = d;
+        d = NULL;
+
+        return (int) n;
+}
+
 int send_one_fd_sa(
                 int transport_fd,
                 int fd,
index 368e6a6dd0128298934c9100d450652bc0708523..c9c3e1f6e1e17e54406140c6f1fc66f028597c7a 100644 (file)
@@ -144,6 +144,7 @@ bool address_label_valid(const char *p);
 
 int getpeercred(int fd, struct ucred *ucred);
 int getpeersec(int fd, char **ret);
+int getpeergroups(int fd, gid_t **ret);
 
 int send_one_fd_sa(int transport_fd,
                    int fd,