]> git.sur5r.net Git - openldap/commitdiff
AIX getpeerid support
authorKurt Zeilenga <kurt@openldap.org>
Wed, 16 Mar 2005 02:22:46 +0000 (02:22 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Wed, 16 Mar 2005 02:22:46 +0000 (02:22 +0000)
build/openldap.m4
configure.in
libraries/libldap/os-local.c
libraries/liblutil/getpeereid.c

index 5e1c8cbb4239573984b6aeec1037795b9f4433ed..6ca7b6a552d8ca4c8d70b79bb6b91a5ade10ca8d 100644 (file)
@@ -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 <sys/socket.h>],
+               [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,[
index 003c52833300a8d5ed3334a4d81dcec7d11c6537..e5dddc7394aa8585507bd144c0e7c74b686549c0 100644 (file)
@@ -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
index 275c08e778ea084644196b54f3116b39eee868f5..a3d4a019d9070b5f26217b2129ba2b8806f4c216 100644 (file)
@@ -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]);
index 258e7c5de9e9dc6eadc86eac5623b98d5d16fda9..3d7ce7a6e12d2e5322ba8b94ab96560019f8e1d9 100644 (file)
@@ -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 <sys/uio.h>
@@ -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;