mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-03-07 14:18:15 +08:00
Interoperability fix for sendmsg/recvmsg with access rights
This commit is contained in:
parent
4f35d76253
commit
50280bcfed
@ -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,28 @@ 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], rc;
|
||||
/* Abandon, noop, has no reply */
|
||||
char txt[] = {LDAP_TAG_MESSAGE, 6, LDAP_TAG_MSGID, 1, 0, LDAP_REQ_ABANDON, 1, 0};
|
||||
struct iovec iov = {txt, sizeof(txt)};
|
||||
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);
|
||||
rc = sendmsg( s, &msg, 0 );
|
||||
if (rc < 0) rc = errno;
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return ( 0 );
|
||||
}
|
||||
|
||||
|
@ -13,11 +13,17 @@
|
||||
#include <ac/unistd.h>
|
||||
|
||||
#include <ac/socket.h>
|
||||
#include <ac/errno.h>
|
||||
|
||||
#if HAVE_SYS_UCRED_H
|
||||
#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,9 +52,34 @@ 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, 1};
|
||||
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, MSG_PEEK) >= 0 && msg.msg_accrightslen == sizeof(int) )
|
||||
{
|
||||
/* We must receive a valid descriptor, it must be a pipe,
|
||||
* and it must only be accessible by its owner.
|
||||
*/
|
||||
dummy = fstat( fd[0], &st );
|
||||
close(fd[0]);
|
||||
if( dummy == 0 && S_ISFIFO(st.st_mode) &&
|
||||
((st.st_mode & (S_IRWXG|S_IRWXO)) == 0))
|
||||
{
|
||||
*euid = st.st_uid;
|
||||
*egid = st.st_gid;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* HAVE_GETPEEREID */
|
||||
|
Loading…
Reference in New Issue
Block a user