Age Owner TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * getpeereid.c
4 : * get peer userid for UNIX-domain socket connection
5 : *
6 : * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
7 : *
8 : *
9 : * IDENTIFICATION
10 : * src/port/getpeereid.c
11 : *
12 : *-------------------------------------------------------------------------
13 : */
14 :
15 : #include "c.h"
16 :
17 : #include <sys/param.h>
18 : #include <sys/socket.h>
19 : #include <sys/un.h>
20 : #include <unistd.h>
21 : #ifdef HAVE_UCRED_H
22 : #include <ucred.h>
23 : #endif
24 : #ifdef HAVE_SYS_UCRED_H
25 : #include <sys/ucred.h>
26 : #endif
27 :
28 :
29 : /*
30 : * BSD-style getpeereid() for platforms that lack it.
4329 tgl 31 ECB : */
32 : int
4329 tgl 33 GIC 27 : getpeereid(int sock, uid_t *uid, gid_t *gid)
34 : {
35 : #if defined(SO_PEERCRED)
4329 tgl 36 ECB : /* Linux: use getsockopt(SO_PEERCRED) */
37 : struct ucred peercred;
516 peter 38 CBC 27 : socklen_t so_len = sizeof(peercred);
4329 tgl 39 ECB :
4329 tgl 40 GBC 27 : if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 ||
4329 tgl 41 CBC 27 : so_len != sizeof(peercred))
4329 tgl 42 LBC 0 : return -1;
4329 tgl 43 CBC 27 : *uid = peercred.uid;
4329 tgl 44 GIC 27 : *gid = peercred.gid;
45 27 : return 0;
46 : #elif defined(LOCAL_PEERCRED)
47 : /* Debian with FreeBSD kernel: use getsockopt(LOCAL_PEERCRED) */
48 : struct xucred peercred;
49 : socklen_t so_len = sizeof(peercred);
50 :
51 : if (getsockopt(sock, 0, LOCAL_PEERCRED, &peercred, &so_len) != 0 ||
52 : so_len != sizeof(peercred) ||
53 : peercred.cr_version != XUCRED_VERSION)
54 : return -1;
55 : *uid = peercred.cr_uid;
56 : *gid = peercred.cr_gid;
57 : return 0;
58 : #elif defined(HAVE_GETPEERUCRED)
59 : /* Solaris: use getpeerucred() */
60 : ucred_t *ucred;
61 :
62 : ucred = NULL; /* must be initialized to NULL */
63 : if (getpeerucred(sock, &ucred) == -1)
64 : return -1;
65 :
66 : *uid = ucred_geteuid(ucred);
67 : *gid = ucred_getegid(ucred);
68 : ucred_free(ucred);
69 :
70 : if (*uid == (uid_t) (-1) || *gid == (gid_t) (-1))
71 : return -1;
72 : return 0;
73 : #else
74 : /* No implementation available on this platform */
75 : errno = ENOSYS;
76 : return -1;
77 : #endif
78 : }
|