From c49812bf6fb8d279936c2cc4df44ca155a65e32a Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 26 Mar 2007 12:44:11 +0000 Subject: [PATCH] ITS#4893 back to pipes... --- libraries/libldap/os-local.c | 71 +++++++++++++++++++-------------- libraries/liblutil/getpeereid.c | 23 +++++------ 2 files changed, 51 insertions(+), 43 deletions(-) diff --git a/libraries/libldap/os-local.c b/libraries/libldap/os-local.c index 20727a614e..52f6745c5e 100644 --- a/libraries/libldap/os-local.c +++ b/libraries/libldap/os-local.c @@ -182,15 +182,18 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_un *sa, int async) #ifdef LDAP_PF_LOCAL_SENDMSG /* Send a dummy message with access rights. Remote side will - * obtain our uid/gid by fstat'ing this descriptor. + * obtain our uid/gid by fstat'ing this descriptor. The + * descriptor permissions must match exactly, and we also + * send the socket name, which must also match. */ sendcred: { - fchmod( s, S_ISUID|S_IRWXU ); - - /* Abandon, noop, has no reply */ - struct iovec iov; - struct msghdr msg = {0}; + int fds[2]; + socklen_t salen = sizeof(*sa); + if (pipe(fds) == 0) { + /* Abandon, noop, has no reply */ + struct iovec iov; + struct msghdr msg = {0}; # ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL # ifndef CMSG_SPACE # define CMSG_SPACE(len) (_CMSG_ALIGN( sizeof(struct cmsghdr)) + _CMSG_ALIGN(len) ) @@ -198,38 +201,44 @@ sendcred: # ifndef CMSG_LEN # define CMSG_LEN(len) (_CMSG_ALIGN( sizeof(struct cmsghdr)) + (len) ) # endif - union { - struct cmsghdr cm; - unsigned char control[CMSG_SPACE(sizeof(int))]; - } control_un; - struct cmsghdr *cmsg; + union { + struct cmsghdr cm; + unsigned char control[CMSG_SPACE(sizeof(int))]; + } control_un; + struct cmsghdr *cmsg; # endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */ - msg.msg_name = NULL; - msg.msg_namelen = 0; - iov.iov_base = (char *) abandonPDU; - iov.iov_len = sizeof abandonPDU; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; + msg.msg_name = NULL; + msg.msg_namelen = 0; + iov.iov_base = (char *) abandonPDU; + iov.iov_len = sizeof abandonPDU; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; # ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof( control_un.control ); - msg.msg_flags = 0; + msg.msg_control = control_un.control; + msg.msg_controllen = sizeof( control_un.control ); + msg.msg_flags = 0; - cmsg = CMSG_FIRSTHDR( &msg ); - cmsg->cmsg_len = CMSG_LEN( sizeof(int) ); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; + cmsg = CMSG_FIRSTHDR( &msg ); + cmsg->cmsg_len = CMSG_LEN( sizeof(int) ); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; - *((int *)CMSG_DATA(cmsg)) = s; + *((int *)CMSG_DATA(cmsg)) = fds[0]; # else - msg.msg_accrights = (char *)&s; - msg.msg_accrightslen = sizeof(int); + msg.msg_accrights = (char *)fds; + msg.msg_accrightslen = sizeof(int); # endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */ - sendmsg( s, &msg, 0 ); - } + getpeername( s, sa, &salen ); + fchmod( fds[0], S_ISUID|S_IRWXU ); + write( fds[1], sa, salen ); + sendmsg( s, &msg, 0 ); + close(fds[0]); + close(fds[1]); + } + } #endif - return 0; -} + return 0; + } if ( errno != EINPROGRESS && errno != EWOULDBLOCK ) return -1; diff --git a/libraries/liblutil/getpeereid.c b/libraries/liblutil/getpeereid.c index 25bbd05342..4619c280be 100644 --- a/libraries/liblutil/getpeereid.c +++ b/libraries/liblutil/getpeereid.c @@ -108,15 +108,15 @@ int lutil_getpeereid( int s, uid_t *euid, gid_t *egid rlen = sizeof(rname); llen = sizeof(lname); + memset( &lname, 0, sizeof( lname )); getsockname(s, (struct sockaddr *)&lname, &llen); - msg.msg_name = NULL; - msg.msg_namelen = 0; - iov.iov_base = peerbv->bv_val; iov.iov_len = peerbv->bv_len; msg.msg_iov = &iov; msg.msg_iovlen = 1; + peerbv->bv_len = 0; + # ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL msg.msg_control = &control_st; msg.msg_controllen = sizeof( struct cmsghdr ) + sizeof( int ); /* no padding! */ @@ -132,8 +132,8 @@ int lutil_getpeereid( int s, uid_t *euid, gid_t *egid * called with MSG_PEEK (is this a bug?). Hence we need * to receive the Abandon PDU. */ - peerbv->bv_len = recvmsg( s, &msg, MSG_WAITALL ); - if( peerbv->bv_len >= 0 && + err = recvmsg( s, &msg, MSG_WAITALL ); + if( err >= 0 && # ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL cmsg->cmsg_len == CMSG_LEN( sizeof(int) ) && cmsg->cmsg_level == SOL_SOCKET && @@ -142,18 +142,19 @@ int lutil_getpeereid( int s, uid_t *euid, gid_t *egid msg.msg_accrightslen == sizeof(int) # endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL*/ ) { - int mode = S_IFSOCK|S_ISUID|S_IRWXU; + int mode = S_IFIFO|S_ISUID|S_IRWXU; - /* We must receive a valid descriptor, it must be a socket, - * it must only be accessible by its owner, and it must be - * connected to our socket. + /* We must receive a valid descriptor, it must be a pipe, + * it must only be accessible by its owner, and it must + * have the name of our socket written on it. */ + peerbv->bv_len = err; # ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL fd = (*(int *)CMSG_DATA( cmsg )); # endif err = fstat( fd, &st ); if ( err == 0 ) - err = getpeername(fd, (struct sockaddr *)&rname, &rlen); + rlen = read(fd, &rname, rlen); close(fd); if( err == 0 && st.st_mode == mode && llen == rlen && !memcmp(&lname, &rname, llen)) @@ -162,8 +163,6 @@ int lutil_getpeereid( int s, uid_t *euid, gid_t *egid *egid = st.st_gid; return 0; } - } else if ( peerbv->bv_len < 0 ) { - peerbv->bv_len = 0; } #elif defined(SOCKCREDSIZE) struct msghdr msg; -- 2.39.5