/src/postgres/src/port/getpeereid.c
Line | Count | Source (jump to first uncovered line) |
1 | | /*------------------------------------------------------------------------- |
2 | | * |
3 | | * getpeereid.c |
4 | | * get peer userid for UNIX-domain socket connection |
5 | | * |
6 | | * Portions Copyright (c) 1996-2025, 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 |
33 | | getpeereid(int sock, uid_t *uid, gid_t *gid) |
34 | 0 | { |
35 | 0 | #if defined(SO_PEERCRED) |
36 | | /* Linux: use getsockopt(SO_PEERCRED) */ |
37 | 0 | struct ucred peercred; |
38 | 0 | socklen_t so_len = sizeof(peercred); |
39 | |
|
40 | 0 | if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 || |
41 | 0 | so_len != sizeof(peercred)) |
42 | 0 | return -1; |
43 | 0 | *uid = peercred.uid; |
44 | 0 | *gid = peercred.gid; |
45 | 0 | 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 | 0 | } |