]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/cyrus.c
Sync with HEAD
[openldap] / libraries / libldap / cyrus.c
index 548f365952b19d0f76fc1c6d7dd86871c65b7021..936f44d35b53e33b3faa9bb6e0250065a30375c1 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2005 The OpenLDAP Foundation.
+ * Copyright 1998-2006 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -602,23 +602,31 @@ ldap_int_sasl_bind(
                return ld->ld_errno;
        }
 
+       rc = 0;
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
        ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd );
 
        if ( sd == AC_SOCKET_INVALID ) {
                /* not connected yet */
-               int rc;
 
                rc = ldap_open_defconn( ld );
-               if( rc < 0 ) return ld->ld_errno;
 
-               ber_sockbuf_ctrl( ld->ld_defconn->lconn_sb,
-                       LBER_SB_OPT_GET_FD, &sd );
+               if ( rc == 0 ) {
+                       ber_sockbuf_ctrl( ld->ld_defconn->lconn_sb,
+                               LBER_SB_OPT_GET_FD, &sd );
 
-               if( sd == AC_SOCKET_INVALID ) {
-                       ld->ld_errno = LDAP_LOCAL_ERROR;
-                       return ld->ld_errno;
+                       if( sd == AC_SOCKET_INVALID ) {
+                               ld->ld_errno = LDAP_LOCAL_ERROR;
+                               rc = ld->ld_errno;
+                       }
                }
        }   
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif
+       if( rc != 0 ) return ld->ld_errno;
 
        oldctx = ld->ld_defconn->lconn_sasl_authctx;
 
@@ -753,13 +761,31 @@ ldap_int_sasl_bind(
                        /* we're done, no need to step */
                        if( scred ) {
                                /* but we got additional data? */
-                               Debug( LDAP_DEBUG_TRACE,
-                                       "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
-                                       rc, saslrc, scred ? scred->bv_len : -1 );
-
-                               ber_bvfree( scred );
-                               rc = ld->ld_errno = LDAP_LOCAL_ERROR;
-                               goto done;
+#define KLUDGE_FOR_MSAD
+#ifdef         KLUDGE_FOR_MSAD
+                               /*
+                                * MSAD provides empty additional data in violation of LDAP
+                                * technical specifications.  As no existing SASL mechanism
+                                * allows empty data with an outcome message, just ignore it
+                                * for now.  Hopefully MS will fix their bug before someone
+                                * defines a mechanism with possibly empty additional data.
+                                */
+                               if( scred->bv_len == 0 ) {
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "ldap_int_sasl_bind: ignoring "
+                                                       " bogus empty data provided with SASL outcome message.\n",
+                                               rc, saslrc, scred->bv_len );
+                                       ber_bvfree( scred );
+                               } else
+#endif
+                               {
+                                       Debug( LDAP_DEBUG_TRACE,
+                                               "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
+                                               rc, saslrc, scred->bv_len );
+                                       rc = ld->ld_errno = LDAP_LOCAL_ERROR;
+                                       ber_bvfree( scred );
+                                       goto done;
+                               }
                        }
                        break;
                }
@@ -843,9 +869,6 @@ ldap_int_sasl_bind(
                }
 
                if( ssf && *ssf ) {
-                       if( flags != LDAP_SASL_QUIET ) {
-                               fprintf( stderr, "SASL installing layers\n" );
-                       }
                        if ( ld->ld_defconn->lconn_sasl_sockctx ) {
                                oldctx = ld->ld_defconn->lconn_sasl_sockctx;
                                sasl_dispose( &oldctx );
@@ -853,6 +876,10 @@ ldap_int_sasl_bind(
                        }
                        ldap_pvt_sasl_install( ld->ld_defconn->lconn_sb, ctx );
                        ld->ld_defconn->lconn_sasl_sockctx = ctx;
+
+                       if( flags != LDAP_SASL_QUIET ) {
+                               fprintf( stderr, "SASL data security layer installed.\n" );
+                       }
                }
        }
        ld->ld_defconn->lconn_sasl_authctx = ctx;
@@ -1005,7 +1032,7 @@ int ldap_pvt_sasl_secprops(
        sasl_security_properties_t *secprops )
 {
        int i, j, l;
-       char **props = ldap_str2charray( in, "," );
+       char **props;
        unsigned sflags = 0;
        int got_sflags = 0;
        sasl_ssf_t max_ssf = 0;
@@ -1015,7 +1042,11 @@ int ldap_pvt_sasl_secprops(
        unsigned maxbufsize = 0;
        int got_maxbufsize = 0;
 
-       if( props == NULL || secprops == NULL ) {
+       if( secprops == NULL ) {
+               return LDAP_PARAM_ERROR;
+       }
+       props = ldap_str2charray( in, "," );
+       if( props == NULL ) {
                return LDAP_PARAM_ERROR;
        }
 
@@ -1026,11 +1057,12 @@ int ldap_pvt_sasl_secprops(
                        if ( strncasecmp( props[i], sprops[j].key.bv_val,
                                sprops[j].key.bv_len )) continue;
                        if ( sprops[j].ival ) {
-                               int v;
+                               unsigned v;
                                char *next = NULL;
-                               if ( !isdigit( props[i][sprops[j].key.bv_len] )) continue;
+                               if ( !isdigit( (unsigned char)props[i][sprops[j].key.bv_len] ))
+                                       continue;
                                v = strtoul( &props[i][sprops[j].key.bv_len], &next, 10 );
-                               if ( next == NULL || next[ 0 ] != '\0' ) continue;
+                               if ( next == &props[i][sprops[j].key.bv_len] || next[0] != '\0' ) continue;
                                switch( sprops[j].ival ) {
                                case GOT_MINSSF:
                                        min_ssf = v; got_min_ssf++; break;
@@ -1050,6 +1082,7 @@ int ldap_pvt_sasl_secprops(
                        break;
                }
                if ( BER_BVISNULL( &sprops[j].key )) {
+                       ldap_charray_free( props );
                        return LDAP_NOT_SUPPORTED;
                }
        }
@@ -1161,7 +1194,7 @@ ldap_int_sasl_get_option( LDAP *ld, int option, void *arg )
 int
 ldap_int_sasl_set_option( LDAP *ld, int option, void *arg )
 {
-       if ( ld == NULL )
+       if ( ld == NULL || arg == NULL )
                return -1;
 
        switch ( option ) {