Commit d7c0a19a authored by Howard Chu's avatar Howard Chu
Browse files

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.
parent eb41333e
......@@ -2475,6 +2475,7 @@ AC_CHECK_FUNCS( \
wait4 \
write \
send \
sendmsg \
sendto \
)
......
......@@ -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 );
......
......@@ -18,6 +18,11 @@
#include <sys/ucred.h>
#endif
#if !defined(SO_PEERCRED) && !defined(LOCAL_PEERCRED) && defined(HAVE_SENDMSG)
#define DO_SENDMSG
#include <sys/stat.h>
#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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment