Age Owner Branch data 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-2024, 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.
31 : : */
32 : : int
4700 tgl@sss.pgh.pa.us 33 :CBC 28 : getpeereid(int sock, uid_t *uid, gid_t *gid)
34 : : {
35 : : #if defined(SO_PEERCRED)
36 : : /* Linux: use getsockopt(SO_PEERCRED) */
37 : : struct ucred peercred;
887 peter@eisentraut.org 38 : 28 : socklen_t so_len = sizeof(peercred);
39 : :
4700 tgl@sss.pgh.pa.us 40 [ + - ]: 28 : if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 ||
41 [ - + ]: 28 : so_len != sizeof(peercred))
4700 tgl@sss.pgh.pa.us 42 :UBC 0 : return -1;
4700 tgl@sss.pgh.pa.us 43 :CBC 28 : *uid = peercred.uid;
44 : 28 : *gid = peercred.gid;
45 : 28 : 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 : : }
|