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 33 56 : 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 56 : socklen_t so_len = sizeof(peercred); 39 : 40 56 : if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 || 41 56 : so_len != sizeof(peercred)) 42 0 : return -1; 43 56 : *uid = peercred.uid; 44 56 : *gid = peercred.gid; 45 56 : 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 : }