LCOV - code coverage report
Current view: top level - src/port - getpeereid.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 7 8 87.5 %
Date: 2024-04-19 06:11:31 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          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             : }

Generated by: LCOV version 1.14