PostgreSQL Source Code  git master
getpeereid.c
Go to the documentation of this file.
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
33 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;
38  socklen_t so_len = sizeof(peercred);
39 
40  if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 ||
41  so_len != sizeof(peercred))
42  return -1;
43  *uid = peercred.uid;
44  *gid = peercred.gid;
45  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 }
int getpeereid(int sock, uid_t *uid, gid_t *gid)
Definition: getpeereid.c:33
unsigned int socklen_t
Definition: port.h:40
int gid_t
Definition: win32_port.h:245
int uid_t
Definition: win32_port.h:244