Support LOCAL_PEERCRED found on FreeBSD and MacOS in _dbus_read_credentials_socket()

This commit is contained in:
Alex S 2025-03-13 11:27:21 +03:00 committed by Gleb Popov
parent cddd0a7c94
commit 667d78ff0b
4 changed files with 34 additions and 3 deletions

View file

@ -31,6 +31,7 @@ check_include_file(sys/random.h HAVE_SYS_RANDOM_H)
check_include_file(sys/resource.h HAVE_SYS_RESOURCE_H) check_include_file(sys/resource.h HAVE_SYS_RESOURCE_H)
check_include_file(sys/syscall.h HAVE_SYS_SYSCALL_H) check_include_file(sys/syscall.h HAVE_SYS_SYSCALL_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H)# dbus-sysdeps-win.c check_include_file(sys/time.h HAVE_SYS_TIME_H)# dbus-sysdeps-win.c
check_include_file(sys/ucred.h HAVE_SYS_UCRED_H)# dbus-sysdeps-unix.c
check_include_file(sys/vfs.h HAVE_SYS_VFS_H) check_include_file(sys/vfs.h HAVE_SYS_VFS_H)
check_include_file(syslog.h HAVE_SYSLOG_H) check_include_file(syslog.h HAVE_SYSLOG_H)
check_include_file(unistd.h HAVE_UNISTD_H) # dbus-sysdeps-util-win.c check_include_file(unistd.h HAVE_UNISTD_H) # dbus-sysdeps-util-win.c

View file

@ -131,6 +131,9 @@
/* Define to 1 if you have sys/time.h */ /* Define to 1 if you have sys/time.h */
#cmakedefine HAVE_SYS_TIME_H 1 #cmakedefine HAVE_SYS_TIME_H 1
/* Define to 1 if you have sys/ucred.h */
#cmakedefine HAVE_SYS_UCRED_H 1
/* Define to 1 if you have unistd.h */ /* Define to 1 if you have unistd.h */
#cmakedefine HAVE_UNISTD_H 1 #cmakedefine HAVE_UNISTD_H 1

View file

@ -80,6 +80,9 @@
#ifdef HAVE_GETPEERUCRED #ifdef HAVE_GETPEERUCRED
#include <ucred.h> #include <ucred.h>
#endif #endif
#ifdef HAVE_SYS_UCRED_H
#include <sys/ucred.h>
#endif
#ifdef HAVE_ALLOCA_H #ifdef HAVE_ALLOCA_H
#include <alloca.h> #include <alloca.h>
#endif #endif
@ -2373,6 +2376,29 @@ _dbus_read_credentials_socket (DBusSocket client_fd,
pid_read = cr.unp_pid; pid_read = cr.unp_pid;
uid_read = cr.unp_euid; uid_read = cr.unp_euid;
} }
#elif defined(LOCAL_PEERCRED)
/* A variant of SO_PEERCRED found on FreeBSD 13+ and MacOS
* The structure returned by getsockopt in this case is called struct xucred
* and is documented in unix(4) page of the FreeBSD manual.
*/
struct xucred cr;
socklen_t cr_len = sizeof (cr);
if (getsockopt (client_fd.fd, 0, LOCAL_PEERCRED, &cr, &cr_len) != 0)
{
_dbus_verbose ("Failed to getsockopt(LOCAL_PEERCRED): %s\n",
_dbus_strerror (errno));
}
else if (cr_len != sizeof (cr))
{
_dbus_verbose ("Failed to getsockopt(LOCAL_PEERCRED), returned %d bytes, expected %d\n",
cr_len, (int) sizeof (cr));
}
else
{
pid_read = cr.cr_pid;
uid_read = cr.cr_uid;
}
#elif defined(HAVE_CMSGCRED) #elif defined(HAVE_CMSGCRED)
/* We only check for HAVE_CMSGCRED, but we're really assuming that the /* We only check for HAVE_CMSGCRED, but we're really assuming that the
* presence of that struct implies SCM_CREDS. Supported by at least * presence of that struct implies SCM_CREDS. Supported by at least
@ -2462,8 +2488,8 @@ _dbus_read_credentials_socket (DBusSocket client_fd,
* - AIX? * - AIX?
* - Blackberry? * - Blackberry?
* - Cygwin * - Cygwin
* - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid) * - FreeBSD 4.6+ (but we prefer LOCAL_PEERCRED and fall back to SCM_CREDS: both methods carry the pid)
* - Mac OS X * - Mac OS X (but we prefer LOCAL_PEERCRED if available: it carries the pid)
* - Minix 3.1.8+ * - Minix 3.1.8+
* - MirBSD? * - MirBSD?
* - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid) * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)

View file

@ -744,6 +744,7 @@ check_headers = [
'sys/resource.h', 'sys/resource.h',
'sys/syscall.h', 'sys/syscall.h',
'sys/time.h', 'sys/time.h',
'sys/ucred.h',
'sys/vfs.h', 'sys/vfs.h',
'unistd.h', 'unistd.h',
'ws2tcpip.h', 'ws2tcpip.h',