From 867fb2fd9fe29eef689f5ab0d6e1b7fe8d48a703 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sun, 25 Mar 2007 15:20:50 +0000 Subject: [PATCH] ITS#4893 just send the client socket, not a pipe descriptor. --- libraries/libldap/os-local.c | 63 ++++++++++++++++----------------- libraries/liblutil/getpeereid.c | 29 ++++++++++----- 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/libraries/libldap/os-local.c b/libraries/libldap/os-local.c index fa8562369a..20727a614e 100644 --- a/libraries/libldap/os-local.c +++ b/libraries/libldap/os-local.c @@ -186,11 +186,11 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_un *sa, int async) */ sendcred: { - int fds[2]; - if (pipe(fds) == 0) { - /* Abandon, noop, has no reply */ - struct iovec iov; - struct msghdr msg = {0}; + fchmod( s, S_ISUID|S_IRWXU ); + + /* 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,41 +198,38 @@ 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)) = fds[0]; + *((int *)CMSG_DATA(cmsg)) = s; # else - msg.msg_accrights = (char *)fds; - msg.msg_accrightslen = sizeof(int); + msg.msg_accrights = (char *)&s; + msg.msg_accrightslen = sizeof(int); # endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */ - sendmsg( s, &msg, 0 ); - close(fds[0]); - close(fds[1]); - } - } -#endif - return 0; + sendmsg( s, &msg, 0 ); } +#endif + return 0; +} if ( errno != EINPROGRESS && errno != EWOULDBLOCK ) return -1; diff --git a/libraries/liblutil/getpeereid.c b/libraries/liblutil/getpeereid.c index fee069a893..25bbd05342 100644 --- a/libraries/liblutil/getpeereid.c +++ b/libraries/liblutil/getpeereid.c @@ -96,13 +96,19 @@ int lutil_getpeereid( int s, uid_t *euid, gid_t *egid # ifndef CMSG_LEN # define CMSG_LEN(len) (_CMSG_ALIGN(sizeof(struct cmsghdr)) + (len)) # endif - union { + struct { struct cmsghdr cm; - unsigned char control[CMSG_SPACE(sizeof(int))]; - } control_un; + int fd; + } control_st; struct cmsghdr *cmsg; # endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */ struct stat st; + struct sockaddr_un lname, rname; + socklen_t llen, rlen; + + rlen = sizeof(rname); + llen = sizeof(lname); + getsockname(s, (struct sockaddr *)&lname, &llen); msg.msg_name = NULL; msg.msg_namelen = 0; @@ -112,8 +118,8 @@ int lutil_getpeereid( int s, uid_t *euid, gid_t *egid 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_control = &control_st; + msg.msg_controllen = sizeof( struct cmsghdr ) + sizeof( int ); /* no padding! */ cmsg = CMSG_FIRSTHDR( &msg ); # else @@ -136,16 +142,21 @@ int lutil_getpeereid( int s, uid_t *euid, gid_t *egid msg.msg_accrightslen == sizeof(int) # endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL*/ ) { - /* We must receive a valid descriptor, it must be a pipe, - * and it must only be accessible by its owner. + int mode = S_IFSOCK|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. */ # 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); close(fd); - if( err == 0 && S_ISFIFO(st.st_mode) && - ((st.st_mode & (S_IRWXG|S_IRWXO)) == 0)) + if( err == 0 && st.st_mode == mode && + llen == rlen && !memcmp(&lname, &rname, llen)) { *euid = st.st_uid; *egid = st.st_gid; -- 2.39.5