diff --git a/include/meson.build b/include/meson.build index 64cf0aeee..87dbfc844 100644 --- a/include/meson.build +++ b/include/meson.build @@ -135,6 +135,7 @@ conf_data.set('HAVE_FNMATCH_H', cc.has_header('fnmatch.h') ? '1' : false) conf_data.set('HAVE_LINUX_AGPGART_H', cc.has_header('linux/agpgart.h') ? '1' : false) conf_data.set('HAVE_STRINGS_H', cc.has_header('strings.h') ? '1' : false) conf_data.set('HAVE_SYS_AGPGART_H', cc.has_header('sys/agpgart.h') ? '1' : false) +conf_data.set('HAVE_SYS_UCRED_H', cc.has_header('sys/ucred.h') ? '1' : false) conf_data.set('HAVE_SYS_UN_H', cc.has_header('sys/un.h') ? '1' : false) conf_data.set('HAVE_SYS_UTSNAME_H', cc.has_header('sys/utsname.h') ? '1' : false) conf_data.set('HAVE_SYS_SYSMACROS_H', cc.has_header('sys/sysmacros.h') ? '1' : false) @@ -176,6 +177,7 @@ conf_data.set('HAVE_TIMINGSAFE_MEMCMP', cc.has_function('timingsafe_memcmp') ? ' conf_data.set('HAVE_VASPRINTF', cc.has_function('vasprintf') ? '1' : false) conf_data.set('HAVE_VSNPRINTF', cc.has_function('vsnprintf') ? '1' : false) conf_data.set('HAVE_WALKCONTEXT', cc.has_function('walkcontext') ? '1' : false) +conf_data.set('HAVE_XUCRED_CR_PID', cc.has_member('struct xucred', 'cr_pid', prefix : '#include ') ? '1' : false) conf_data.set('BUSFAULT', conf_data.get('HAVE_SIGACTION')) diff --git a/os/access.c b/os/access.c index 900796cad..9fec1b731 100644 --- a/os/access.c +++ b/os/access.c @@ -116,6 +116,10 @@ SOFTWARE. #endif #endif +#ifdef HAVE_SYS_UCRED_H +#include +#endif + #ifdef HAVE_SYS_UN_H #include #endif @@ -1166,7 +1170,7 @@ ComputeLocalClient(ClientPtr client) int GetLocalClientCreds(ClientPtr client, LocalClientCredRec ** lccp) { -#if defined(HAVE_GETPEEREID) || defined(HAVE_GETPEERUCRED) || defined(SO_PEERCRED) +#if defined(HAVE_GETPEEREID) || defined(HAVE_GETPEERUCRED) || defined(SO_PEERCRED) || defined(LOCAL_PEERCRED) int fd; XtransConnInfo ci; LocalClientCredRec *lcc; @@ -1177,6 +1181,9 @@ GetLocalClientCreds(ClientPtr client, LocalClientCredRec ** lccp) #elif defined(SO_PEERCRED) struct ucred peercred; socklen_t so_len = sizeof(peercred); +#elif defined(LOCAL_PEERCRED) && defined(HAVE_XUCRED_CR_PID) + struct xucred peercred; + socklen_t so_len = sizeof(peercred); #elif defined(HAVE_GETPEEREID) uid_t uid; gid_t gid; @@ -1253,6 +1260,17 @@ GetLocalClientCreds(ClientPtr client, LocalClientCredRec ** lccp) lcc->pid = peercred.pid; lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET; return 0; +#elif defined(LOCAL_PEERCRED) && defined(HAVE_XUCRED_CR_PID) + if (getsockopt(fd, SOL_LOCAL, LOCAL_PEERCRED, &peercred, &so_len) != 0 || + peercred.cr_version != XUCRED_VERSION) { + FreeLocalClientCreds(lcc); + return -1; + } + lcc->euid = peercred.cr_uid; + lcc->egid = peercred.cr_gid; + lcc->pid = peercred.cr_pid; + lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET; + return 0; #elif defined(HAVE_GETPEEREID) if (getpeereid(fd, &uid, &gid) == -1) { FreeLocalClientCreds(lcc);