]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/sasl.c
Move serverID into a Global configuration section.
[openldap] / libraries / libldap / sasl.c
index 8945d957331159d1a61b272e67128582f27ca23b..d58d2c5d9e42e7f939c9e648e25c7b17c44fe6e3 100644 (file)
@@ -1,7 +1,16 @@
 /* $OpenLDAP$ */
-/*
- * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2008 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
  */
 
 /*
  *             name            DistinguishedName,       -- who
  *             authentication  CHOICE {
  *                     simple          [0] OCTET STRING -- passwd
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
- *                     krbv42ldap      [1] OCTET STRING
- *                     krbv42dsa       [2] OCTET STRING
-#endif
+ *                     krbv42ldap      [1] OCTET STRING -- OBSOLETE
+ *                     krbv42dsa       [2] OCTET STRING -- OBSOLETE
  *                     sasl            [3] SaslCredentials     -- LDAPv3
  *             }
  *     }
 
 #include "portable.h"
 
-#include <stdlib.h>
 #include <stdio.h>
 
 #include <ac/socket.h>
+#include <ac/stdlib.h>
 #include <ac/string.h>
 #include <ac/time.h>
 #include <ac/errno.h>
@@ -60,6 +67,7 @@ ldap_sasl_bind(
 {
        BerElement      *ber;
        int rc;
+       ber_int_t id;
 
        Debug( LDAP_DEBUG_TRACE, "ldap_sasl_bind\n", 0, 0, 0 );
 
@@ -71,13 +79,8 @@ ldap_sasl_bind(
        rc = ldap_int_client_controls( ld, cctrls );
        if( rc != LDAP_SUCCESS ) return rc;
 
-       if( msgidp == NULL ) {
-               ld->ld_errno = LDAP_PARAM_ERROR;
-               return ld->ld_errno;
-       }
-
        if( mechanism == LDAP_SASL_SIMPLE ) {
-               if( dn == NULL && cred != NULL ) {
+               if( dn == NULL && cred != NULL && cred->bv_len ) {
                        /* use default binddn */
                        dn = ld->ld_defbinddn;
                }
@@ -97,26 +100,27 @@ ldap_sasl_bind(
                return ld->ld_errno;
        }
 
-       assert( BER_VALID( ber ) );
+       assert( LBER_VALID( ber ) );
 
+       LDAP_NEXT_MSGID( ld, id );
        if( mechanism == LDAP_SASL_SIMPLE ) {
                /* simple bind */
                rc = ber_printf( ber, "{it{istON}" /*}*/,
-                       ++ld->ld_msgid, LDAP_REQ_BIND,
+                       id, LDAP_REQ_BIND,
                        ld->ld_version, dn, LDAP_AUTH_SIMPLE,
                        cred );
                
-       } else if ( cred == NULL || !cred->bv_len ) {
-               /* SASL bind w/o creditials */
+       } else if ( cred == NULL || cred->bv_val == NULL ) {
+               /* SASL bind w/o credentials */
                rc = ber_printf( ber, "{it{ist{sN}N}" /*}*/,
-                       ++ld->ld_msgid, LDAP_REQ_BIND,
+                       id, LDAP_REQ_BIND,
                        ld->ld_version, dn, LDAP_AUTH_SASL,
                        mechanism );
 
        } else {
-               /* SASL bind w/ creditials */
+               /* SASL bind w/ credentials */
                rc = ber_printf( ber, "{it{ist{sON}N}" /*}*/,
-                       ++ld->ld_msgid, LDAP_REQ_BIND,
+                       id, LDAP_REQ_BIND,
                        ld->ld_version, dn, LDAP_AUTH_SASL,
                        mechanism, cred );
        }
@@ -139,14 +143,9 @@ ldap_sasl_bind(
                return ld->ld_errno;
        }
 
-#ifndef LDAP_NOCACHE
-       if ( ld->ld_cache != NULL ) {
-               ldap_flush_cache( ld );
-       }
-#endif /* !LDAP_NOCACHE */
 
        /* send the message */
-       *msgidp = ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber );
+       *msgidp = ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber, id );
 
        if(*msgidp < 0)
                return ld->ld_errno;
@@ -186,7 +185,13 @@ ldap_sasl_bind_s(
                return( rc );
        }
 
-       if ( ldap_result( ld, msgid, 1, NULL, &result ) == -1 ) {
+#ifdef LDAP_CONNECTIONLESS
+       if (LDAP_IS_UDP(ld)) {
+               return( rc );
+       }
+#endif
+
+       if ( ldap_result( ld, msgid, LDAP_MSG_ALL, NULL, &result ) == -1 || !result ) {
                return( ld->ld_errno ); /* ldap_result sets ld_errno */
        }
 
@@ -196,7 +201,7 @@ ldap_sasl_bind_s(
                rc = ldap_parse_sasl_bind_result( ld, result, &scredp, 0 );
        }
 
-       if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
+       if ( rc != LDAP_SUCCESS ) {
                ldap_msgfree( result );
                return( rc );
        }
@@ -251,10 +256,6 @@ ldap_parse_sasl_bind_result(
        assert( LDAP_VALID( ld ) );
        assert( res != NULL );
 
-       if ( ld == NULL || res == NULL ) {
-               return LDAP_PARAM_ERROR;
-       }
-
        if( servercredp != NULL ) {
                if( ld->ld_version < LDAP_VERSION2 ) {
                        return LDAP_NOT_SUPPORTED;
@@ -288,7 +289,7 @@ ldap_parse_sasl_bind_result(
        }
 
        if ( ld->ld_version < LDAP_VERSION2 ) {
-               tag = ber_scanf( ber, "{ia}",
+               tag = ber_scanf( ber, "{iA}",
                        &errcode, &ld->ld_error );
 
                if( tag == LBER_ERROR ) {
@@ -300,7 +301,7 @@ ldap_parse_sasl_bind_result(
        } else {
                ber_len_t len;
 
-               tag = ber_scanf( ber, "{iaa" /*}*/,
+               tag = ber_scanf( ber, "{eAA" /*}*/,
                        &errcode, &ld->ld_matched, &ld->ld_error );
 
                if( tag == LBER_ERROR ) {
@@ -346,7 +347,7 @@ ldap_parse_sasl_bind_result(
                ldap_msgfree( res );
        }
 
-       return( ld->ld_errno );
+       return( LDAP_SUCCESS );
 }
 
 int
@@ -419,29 +420,44 @@ ldap_sasl_interactive_bind_s(
        void *defaults )
 {
        int rc;
+       char *smechs = NULL;
 
 #if defined( LDAP_R_COMPILE ) && defined( HAVE_CYRUS_SASL )
        ldap_pvt_thread_mutex_lock( &ldap_int_sasl_mutex );
 #endif
+#ifdef LDAP_CONNECTIONLESS
+       if( LDAP_IS_UDP(ld) ) {
+               /* Just force it to simple bind, silly to make the user
+                * ask all the time. No, we don't ever actually bind, but I'll
+                * let the final bind handler take care of saving the cdn.
+                */
+               rc = ldap_simple_bind( ld, dn, NULL );
+               rc = rc < 0 ? rc : 0;
+               goto done;
+       } else
+#endif
 
+#ifdef HAVE_CYRUS_SASL
+       if( mechs == NULL || *mechs == '\0' ) {
+               mechs = ld->ld_options.ldo_def_sasl_mech;
+       }
+#endif
+               
        if( mechs == NULL || *mechs == '\0' ) {
-               char *smechs;
-
                rc = ldap_pvt_sasl_getmechs( ld, &smechs );
-
                if( rc != LDAP_SUCCESS ) {
                        goto done;
                }
 
                Debug( LDAP_DEBUG_TRACE,
-                       "ldap_interactive_sasl_bind_s: server supports: %s\n",
+                       "ldap_sasl_interactive_bind_s: server supports: %s\n",
                        smechs, 0, 0 );
 
                mechs = smechs;
 
        } else {
                Debug( LDAP_DEBUG_TRACE,
-                       "ldap_interactive_sasl_bind_s: user selected: %s\n",
+                       "ldap_sasl_interactive_bind_s: user selected: %s\n",
                        mechs, 0, 0 );
        }
 
@@ -453,6 +469,7 @@ done:
 #if defined( LDAP_R_COMPILE ) && defined( HAVE_CYRUS_SASL )
        ldap_pvt_thread_mutex_unlock( &ldap_int_sasl_mutex );
 #endif
+       if ( smechs ) LDAP_FREE( smechs );
 
        return rc;
 }