From d7c0a19aab847e61798c666eb61111508000b838 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 4 Dec 2002 16:03:02 +0000 Subject: [PATCH] Added check for sendmsg(). Added hack to use BSD sendmsg()/recvmsg() to propagate peer creds if no explicit PEERCRED facility exists. Works on Solaris 8. --- configure.in | 1 + libraries/libldap/os-local.c | 27 +++++++++++++++++++++++++++ libraries/liblutil/getpeereid.c | 25 +++++++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/configure.in b/configure.in index f4821fde25..e0594ebed2 100644 --- a/configure.in +++ b/configure.in @@ -2475,6 +2475,7 @@ AC_CHECK_FUNCS( \ wait4 \ write \ send \ + sendmsg \ sendto \ ) diff --git a/libraries/libldap/os-local.c b/libraries/libldap/os-local.c index b752a382fe..9bd69ca92c 100644 --- a/libraries/libldap/os-local.c +++ b/libraries/libldap/os-local.c @@ -131,6 +131,10 @@ ldap_pvt_is_socket_ready(LDAP *ld, int s) } #undef TRACE +#if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && !defined(LOCAL_PEERCRED) && defined(HAVE_SENDMSG) +#define DO_SENDMSG +#endif + static int ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_un *sa, int async) { @@ -155,6 +159,25 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_un *sa, int async) if ( ldap_pvt_ndelay_off(ld, s) == -1 ) { return ( -1 ); } +#ifdef DO_SENDMSG + /* Send a dummy message with access rights. Remote side will + * obtain our uid/gid by fstat'ing this descriptor. + */ +sendcred: { + int fds[2]; + struct iovec iov = {(char *)fds, sizeof(int)}; + struct msghdr msg = {0}; + if (pipe(fds) == 0) { + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_accrights = (char *)fds; + msg.msg_accrightslen = sizeof(int); + sendmsg( s, &msg, 0 ); + close(fds[0]); + close(fds[1]); + } + } +#endif return ( 0 ); } @@ -181,7 +204,11 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_un *sa, int async) return ( -1 ); if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return ( -1 ); +#ifdef DO_SENDMSG + goto sendcred; +#else return ( 0 ); +#endif } oslocal_debug(ld, "ldap_connect_timeout: timed out\n",0,0,0); ldap_pvt_set_errno( ETIMEDOUT ); diff --git a/libraries/liblutil/getpeereid.c b/libraries/liblutil/getpeereid.c index c64c98429b..80d90d1ffe 100644 --- a/libraries/liblutil/getpeereid.c +++ b/libraries/liblutil/getpeereid.c @@ -18,6 +18,11 @@ #include #endif +#if !defined(SO_PEERCRED) && !defined(LOCAL_PEERCRED) && defined(HAVE_SENDMSG) +#define DO_SENDMSG +#include +#endif + int getpeereid( int s, uid_t *euid, gid_t *egid ) { #ifdef LDAP_PF_LOCAL @@ -46,6 +51,26 @@ int getpeereid( int s, uid_t *euid, gid_t *egid ) *egid = peercred.cr_gid; return 0; } +#elif defined( DO_SENDMSG ) + int dummy, fd[2]; + struct iovec iov = {(char *)&dummy, sizeof(dummy)}; + struct msghdr msg = {0}; + struct stat st; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_accrights = (char *)fd; + msg.msg_accrightslen = sizeof(fd); + if( recvmsg( s, &msg, 0) >= 0 && msg.msg_accrightslen == sizeof(int) ) + { + dummy = fstat( fd, &st ); + close(fd[0]); + if( dummy == 0 ) + { + *euid = st.st_uid; + *egid = st.st_gid; + return 0; + } + } #endif #endif -- 2.39.5