[Fedora-directory-commits] ldapserver/ldap/servers/slapd slap.h, 1.31, 1.32 getsocketpeer.c, 1.3, 1.4 daemon.c, 1.18, 1.19 bind.c, 1.11, 1.12

Noriko Hosoi (nhosoi) fedora-directory-commits at redhat.com
Fri May 16 16:46:52 UTC 2008


Author: nhosoi

Update of /cvs/dirsec/ldapserver/ldap/servers/slapd
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv20423

Modified Files:
	slap.h getsocketpeer.c daemon.c bind.c 
Log Message:
Resolves: #436390
Summary: LDAPI: support auto-bind
Description: 
1) Debugged the basic code of slapd_get_socket_peer, which is used for Solaris9
and HP-UX.  The recvmsg call returns an error immediately if no data is waiting
to be received since the socket is set PR_SockOpt_Nonblocking (O_NONBLOCK).  To
make slapd_get_socket_peer more robust, we have to retry recvmsg if it returns
EAGAIN.  But set a retry count not to hang there.
2) Introduced c_local_valid in the Connection handle to tell the autobind
code that the uid/gid pair is valid or not. 
3) Stops the automagic/unconditional auto-bind (the code used to be in 
daemon.c). 
4) Auto-bind is effective only when the client passes the SASL/EXTERNAL request.



Index: slap.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slap.h,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- slap.h	3 Apr 2008 16:52:46 -0000	1.31
+++ slap.h	16 May 2008 16:46:49 -0000	1.32
@@ -1247,9 +1247,10 @@
     int				c_enable_sasl_io; /* Flag to tell us to enable SASL I/O on the next read */
     int				c_sasl_io; /* Flag to tell us to enable SASL I/O on the next read */
     int				c_sasl_ssf; /* flag to tell us the SASL SSF */
-    int                         c_unix_local; /* flag true for LDAPI */
-    uid_t                         c_local_uid;  /* uid of connecting process */
-    gid_t                         c_local_gid;  /* gid of connecting process */
+    int				c_unix_local; /* flag true for LDAPI */
+    int				c_local_valid; /* flag true if the uid/gid are valid */
+    uid_t			c_local_uid;  /* uid of connecting process */
+    gid_t			c_local_gid;  /* gid of connecting process */
 } Connection;
 #define CONN_FLAG_SSL	1	/* Is this connection an SSL connection or not ? 
 							 * Used to direct I/O code when SSL is handled differently 


Index: getsocketpeer.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/getsocketpeer.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- getsocketpeer.c	27 Feb 2007 20:16:08 -0000	1.3
+++ getsocketpeer.c	16 May 2008 16:46:49 -0000	1.4
@@ -70,7 +70,7 @@
 		}
 	}
 
-#elif 0 /*defined(HAVE_GETPEERUCRED)*/ /* solaris */
+#elif defined(HAVE_GETPEERUCRED) /* solaris10 */
 
 	ucred_t *creds = 0;
 
@@ -78,15 +78,15 @@
 	{
 		if(uid)
 		{
-			uid = ucred_getruid(creds);
+			*uid = ucred_getruid(creds);
 			if(-1 != uid)
 				ret = 0;
 		}
 
 		if(gid)
 		{
-			gid = ucred_getrgid(creds);
-			if(-1 == gid)
+			*gid = ucred_getrgid(creds);
+			if(-1 == *gid)
 				ret = -1;
 			else
 				ret = 0;
@@ -95,44 +95,61 @@
 		ucred_free(creds);
 	}
 
-#elif 0 /* defined(HAVE_GETPEEREID) */ /* osx / some BSDs */
+#elif defined(HAVE_GETPEEREID) /* osx / some BSDs */
 
 	if(0 == getpeereid(fd, &uid, &gid))
 		ret = 0;
 
-#elif 0 /* hpux / some BSDs - file descriptor cooperative auth */
-
-        struct msghdr msg;
+#else /* hpux / Solaris9 / some BSDs - file descriptor cooperative auth */
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+	struct msghdr msg;
 	struct iovec iov;
 	char dummy[8];
-	int fd[2];
+	int pass_sd[2];
+	int rc = 0;
+	unsigned int retrycnt = 0xffffffff;	/* safety net */
+	int myerrno = 0;
 
-	memset(msg, 0, sizeof(msg));
+	memset((void *)&msg, 0, sizeof(msg));
 	
 	iov.iov_base = dummy;
 	iov.iov_len = sizeof(dummy);
 	msg.msg_iov = &iov;
 	msg.msg_iovlen = 1;
-	msg.msg_accrights = (char*)fd;
-	msg.msg_accrightslen = sizeof(fd);
+	msg.msg_accrights = (caddr_t)&pass_sd;
+	msg.msg_accrightslen = sizeof(pass_sd); /* Initialize it with 8 bytes. 
+											   If recvmsg is successful,
+											   4 is supposed to be returned. */
+	/* 
+	   Since PR_SockOpt_Nonblocking is set to the socket,
+	   recvmsg returns immediately if no data is waiting to be received.
+	   If recvmsg returns an error and EGAIN (== EWOULDBLOCK) is set to errno, 
+	   we should retry some time.
+	 */
+	while ((rc = recvmsg(fd, &msg, MSG_PEEK)) < 0 && (EAGAIN == (myerrno = errno)) && retrycnt-- >= 0)
+		;
 
-        if(recvmsg(fd, &msg, MSG_PEEK) >= 0 && msg.msg_accrightslen == sizeof(int))
-        {
+	if (rc >= 0 && msg.msg_accrightslen == sizeof(int))
+	{
 		struct stat st;
 
-		ret = fstat(fd[0], &st);
-		close(fd[0]);
+		ret = fstat(pass_sd[0], &st);
 
 		if(0 == ret && S_ISFIFO(st.st_mode) &&
-			0 == st.st_mode & (S_IRWXG|S_IRWXO))
+		   0 == (st.st_mode & (S_IRWXG|S_IRWXO)))
 		{
 			if(uid)
-				uid = st.st_uid;
+				*uid = st.st_uid;
 
 			if(gid)
-				gid = st.st_gid;
+				*gid = st.st_gid;
+		} else {
+			ret = -1;
 		}
-        }
+	}
 
 #endif
 


Index: daemon.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/daemon.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- daemon.c	14 Nov 2007 20:18:53 -0000	1.18
+++ daemon.c	16 May 2008 16:46:49 -0000	1.19
@@ -1963,11 +1963,13 @@
 	int ret = -1;
 	uid_t uid = 0;
 	gid_t gid = 0;
+	conn->c_local_valid = 0;
 
 	if(0 == slapd_get_socket_peer(conn->c_prfd, &uid, &gid))
 	{
 		conn->c_local_uid = uid;
 		conn->c_local_gid = gid;
+		conn->c_local_valid = 1;
 
 		ret = 0;
 	}
@@ -1983,6 +1985,11 @@
 	uid_t uid = conn->c_local_uid;
 	gid_t gid = conn->c_local_gid;
 
+	if (!conn->c_local_valid)
+	{
+		goto bail;
+	}
+
 	/* observe configuration for auto binding */
 	/* bind at all? */
 	if(config_get_ldapi_bind_switch())
@@ -2338,16 +2345,12 @@
 
 #if defined(ENABLE_LDAPI)
 #if !defined( XP_WIN32 )
-        /* ldapi */
-        if( local )
-        {
-                conn->c_unix_local = 1;
+	/* ldapi */
+	if( local )
+	{
+		conn->c_unix_local = 1;
 		slapd_identify_local_user(conn);
-
-#if defined(ENABLE_AUTOBIND)
-                slapd_bind_local_user(conn);
-#endif /* ENABLE_AUTOBIND */
-        }
+	}
 #endif
 #endif /* ENABLE_LDAPI */
 


Index: bind.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/bind.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- bind.c	18 Oct 2007 00:08:34 -0000	1.11
+++ bind.c	16 May 2008 16:46:49 -0000	1.12
@@ -259,20 +259,24 @@
     bind_credentials_clear( pb->pb_conn, PR_FALSE, /* do not lock conn */
                             PR_FALSE /* do not clear external creds. */ );
 
+#if defined(ENABLE_AUTOBIND)
     /* LDAPI might have auto bind on, binding as anon should
        mean bind as self in this case
      */
-#if defined(ENABLE_AUTOBIND)
-    if((0 == dn || 0 == dn[0]) && pb->pb_conn->c_unix_local)
+    /* You are "bound" when the SSL connection is made, 
+       but the client still passes a BIND SASL/EXTERNAL request.
+     */
+    if((LDAP_AUTH_SASL == method) &&
+       (0 == strcasecmp (saslmech, LDAP_SASL_EXTERNAL)) &&
+       (0 == dn || 0 == dn[0]) && pb->pb_conn->c_unix_local)
     {
         slapd_bind_local_user(pb->pb_conn);
-	
-	if(pb->pb_conn->c_dn)
-	{
+        if(pb->pb_conn->c_dn)
+        {
             auto_bind = 1; /* flag the bind method */
-	    dn = slapi_ch_strdup(pb->pb_conn->c_dn);
-	    slapi_sdn_init_dn_passin(&sdn,dn);
-	}
+            dn = slapi_ch_strdup(pb->pb_conn->c_dn);
+            slapi_sdn_init_dn_passin(&sdn,dn);
+        }
     }
 #endif /* ENABLE_AUTOBIND */
 
@@ -365,11 +369,17 @@
             ids_sasl_check_bind(pb);
             goto free_and_return;
         }
-	else {
-	    charray_free(supported); /* Avoid leaking */
-	}
+        else {
+            charray_free(supported); /* Avoid leaking */
+        }
 
         if (!strcasecmp (saslmech, LDAP_SASL_EXTERNAL)) {
+#if defined(ENABLE_AUTOBIND)
+            if (1 == auto_bind) {
+                /* Already AUTO-BOUND */
+                break;
+            }
+#endif
             /*
              * if this is not an SSL connection, fail and return an
              * inappropriateAuth error.




More information about the Fedora-directory-commits mailing list