From f33af81907204eaf34807ef032f293223417dd99 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Wed, 16 Mar 2005 02:22:46 +0000 Subject: [PATCH] AIX getpeerid support --- build/openldap.m4 | 13 +++++++++ configure.in | 3 ++ libraries/libldap/os-local.c | 31 +++++++++++++++++++- libraries/liblutil/getpeereid.c | 50 +++++++++++++++++++++++++++++---- 4 files changed, 90 insertions(+), 7 deletions(-) diff --git a/build/openldap.m4 b/build/openldap.m4 index 5e1c8cbb42..6ca7b6a552 100644 --- a/build/openldap.m4 +++ b/build/openldap.m4 @@ -1334,6 +1334,19 @@ AC_DEFUN(OL_MSGHDR_MSG_ACCRIGHTS, [define if struct msghdr has msg_accrights]) fi ])dnl +dnl ==================================================================== +dnl check for cmsghdr +AC_DEFUN(OL_MSGHDR_MSG_CONTROL, + [AC_CACHE_CHECK(for msg_control in msghdr, ol_cv_msghdr_msg_control, + [AC_TRY_COMPILE([#include ], + [struct msghdr m; m.msg_control=(struct cmsghdr *)0], + ol_cv_msghdr_msg_control=yes, ol_cv_msghdr_msg_control=no) + ]) + if test $ol_cv_msghdr_msg_control = "yes" ; then + AC_DEFINE(HAVE_MSGHDR_MSG_CONTROL,1, + [define if struct msghdr has msg_control]) + fi +])dnl AC_DEFUN([OL_SSL_COMPAT], [AC_CACHE_CHECK([OpenSSL library version (CRL checking capability)], [ol_cv_ssl_crl_compat],[ AC_EGREP_CPP(__ssl_compat,[ diff --git a/configure.in b/configure.in index 003c528333..e5dddc7394 100644 --- a/configure.in +++ b/configure.in @@ -2519,6 +2519,9 @@ if test "$ac_cv_func_getopt" != yes; then fi if test "$ac_cv_func_getpeereid" != yes; then OL_MSGHDR_MSG_ACCRIGHTS + if test "$ac_cv_func_getpeereid" != yes; then + OL_MSGHDR_MSG_CONTROL + fi LIBSRCS="$LIBSRCS getpeereid.c" fi if test "$ac_cv_func_snprintf" != yes -o "$ac_cv_func_vsnprintf" != yes; then diff --git a/libraries/libldap/os-local.c b/libraries/libldap/os-local.c index 275c08e778..a3d4a019d9 100644 --- a/libraries/libldap/os-local.c +++ b/libraries/libldap/os-local.c @@ -156,7 +156,8 @@ ldap_pvt_is_socket_ready(LDAP *ld, int s) #if !defined(HAVE_GETPEEREID) && \ !defined(SO_PEERCRED) && !defined(LOCAL_PEERCRED) && \ - defined(HAVE_SENDMSG) && defined(HAVE_MSGHDR_MSG_ACCRIGHTS) + defined(HAVE_SENDMSG) && (defined(HAVE_MSGHDR_MSG_ACCRIGHTS) || \ + defined(HAVE_MSGHDR_MSG_CONTROL)) #define DO_SENDMSG static const char abandonPDU[] = {LDAP_TAG_MESSAGE, 6, LDAP_TAG_MSGID, 1, 0, LDAP_REQ_ABANDON, 1, 0}; @@ -194,12 +195,40 @@ sendcred: /* Abandon, noop, has no reply */ struct iovec iov; struct msghdr msg = {0}; +# ifdef HAVE_MSGHDR_MSG_CONTROL +# ifndef CMSG_SPACE +# define CMSG_SPACE(len) (_CMSG_ALIGN( sizeof(struct cmsghdr)) + _CMSG_ALIGN(len) ) +# endif +# 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; +# endif /* HAVE_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; +# ifdef HAVE_MSGHDR_MSG_CONTROL + 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; + + *((int *)CMSG_DATA(cmsg)) = fds[0]; +# else msg.msg_accrights = (char *)fds; msg.msg_accrightslen = sizeof(int); +# endif /* HAVE_MSGHDR_MSG_CONTROL */ sendmsg( s, &msg, 0 ); close(fds[0]); close(fds[1]); diff --git a/libraries/liblutil/getpeereid.c b/libraries/liblutil/getpeereid.c index 258e7c5de9..3d7ce7a6e1 100644 --- a/libraries/liblutil/getpeereid.c +++ b/libraries/liblutil/getpeereid.c @@ -32,7 +32,8 @@ #endif #if !defined(SO_PEERCRED) && !defined(LOCAL_PEERCRED) && \ - defined(HAVE_SENDMSG) && defined(HAVE_MSGHDR_MSG_ACCRIGHTS) + defined(HAVE_SENDMSG) && (defined(HAVE_MSGHDR_MSG_ACCRIGHTS) || \ + defined(HAVE_MSGHDR_MSG_CONTROL)) #define DO_SENDMSG #ifdef HAVE_SYS_UIO_H #include @@ -72,25 +73,62 @@ int getpeereid( int s, uid_t *euid, gid_t *egid ) return 0; } #elif defined( DO_SENDMSG ) - int dummy, fd[2]; + char dummy[8]; + int err, fd[2]; struct iovec iov; struct msghdr msg = {0}; +# ifdef HAVE_MSGHDR_MSG_CONTROL +# ifndef CMSG_SPACE +# define CMSG_SPACE(len) (_CMSG_ALIGN(sizeof(struct cmsghdr)) + _CMSG_ALIGN(len)) +# endif +# 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; +# endif /* HAVE_MSGHDR_MSG_CONTROL */ struct stat st; - iov.iov_base = (char*) &dummy; - iov.iov_len = 1; + msg.msg_name = NULL; + msg.msg_namelen = 0; + + iov.iov_base = dummy; + iov.iov_len = sizeof dummy; msg.msg_iov = &iov; msg.msg_iovlen = 1; +# ifdef HAVE_MSGHDR_MSG_CONTROL + msg.msg_control = control_un.control; + msg.msg_controllen = sizeof( control_un.control ); + + cmsg = CMSG_FIRSTHDR( &msg ); + + /* + * AIX returns a bogus file descriptor if recvmsg() is + * called with MSG_PEEK (is this a bug?). Hence we need + * to receive the Abandon PDU. + */ + if( recvmsg( s, &msg, MSG_WAITALL ) >= 0 && + cmsg->cmsg_len == CMSG_LEN( sizeof(int) ) && + cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_RIGHTS ) +# else msg.msg_accrights = (char *)fd; msg.msg_accrightslen = sizeof(fd); if( recvmsg( s, &msg, MSG_PEEK) >= 0 && msg.msg_accrightslen == sizeof(int) ) +# endif /* HAVE_MSGHDR_MSG_CONTROL*/ { /* 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 ); +# ifdef HAVE_MSGHDR_MSG_CONTROL + fd[0] = (*(int *)CMSG_DATA( cmsg )); +# endif + err = fstat( fd[0], &st ); close(fd[0]); - if( dummy == 0 && S_ISFIFO(st.st_mode) && + if( err == 0 && S_ISFIFO(st.st_mode) && ((st.st_mode & (S_IRWXG|S_IRWXO)) == 0)) { *euid = st.st_uid; -- 2.39.5