]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/sasl.c
listener:
[openldap] / servers / slapd / sasl.c
index 2d9df14d59e59cc27905af9b8bbeeeafc01b1a13..fe748bc3b518c5ab3d0c967ae3c5a8bd35a7d22c 100644 (file)
@@ -32,7 +32,8 @@
 #define        SASL_CONST
 #endif
 
-#include <ldap_pvt.h>
+#include "ldap_pvt.h"
+#include "lber_pvt.h"
 
 /* Flags for telling slap_sasl_getdn() what type of identity is being passed */
 #define FLAG_GETDN_AUTHCID 2
@@ -298,7 +299,7 @@ slap_sasl_log(
 #define        SET_DN  1
 #define        SET_U   2
 
-static struct berval ext_bv = { sizeof("EXTERNAL")-1, "EXTERNAL" };
+static struct berval ext_bv = BER_BVC( "EXTERNAL" );
 
 int slap_sasl_getdn( Connection *conn, char *id, int len,
        char *user_realm, struct berval *dn, int flags )
@@ -341,8 +342,10 @@ int slap_sasl_getdn( Connection *conn, char *id, int len,
         */
        if( flags & FLAG_GETDN_AUTHCID ) {
 #ifdef HAVE_TLS
-               if( conn->c_is_tls && conn->c_sasl_bind_mech.bv_len == ext_bv.bv_len
-                       && ( strcasecmp( ext_bv.bv_val, conn->c_sasl_bind_mech.bv_val ) == 0 ) ) {
+               if( conn->c_is_tls &&
+                       conn->c_sasl_bind_mech.bv_len == ext_bv.bv_len &&
+                       strcasecmp( ext_bv.bv_val, conn->c_sasl_bind_mech.bv_val ) == 0 )
+               {
                        /* X.509 DN is already normalized */
                        do_norm = 0;
                        is_dn = SET_DN;
@@ -815,17 +818,24 @@ slap_sasl_canonicalize(
        if ( auxvals[which].values )
                goto done;
 
-       if ( flags == SASL_CU_AUTHZID ) {
-       /* If we got unqualified authzid's, they probably came from SASL
-        * itself just passing the authcid to us. Look inside the oparams
-        * structure to see if that's true. (HACK: the out_len pointer is
-        * the address of a member of a sasl_out_params_t structure...)
+       /* Normally we require an authzID to have a u: or dn: prefix.
+        * However, SASL frequently gives us an authzID that is just
+        * an exact copy of the authcID, without a prefix. We need to
+        * detect and allow this condition. If SASL calls canonicalize
+        * with SASL_CU_AUTHID|SASL_CU_AUTHZID this is a no-brainer.
+        * But if it's broken into two calls, we need to remember the
+        * authcID so that we can compare the authzID later. We store
+        * the authcID temporarily in conn->c_sasl_dn. We necessarily
+        * finish Canonicalizing before Authorizing, so there is no
+        * conflict with slap_sasl_authorize's use of this temp var.
         */
-               sasl_out_params_t dummy;
-               int offset = (void *)&dummy.ulen - (void *)&dummy.authid;
-               char **authid = (void *)out_len - offset;
-               if ( *authid && !strcmp( in, *authid ) )
-                       goto done;
+       if ( flags == SASL_CU_AUTHID ) {
+               conn->c_sasl_dn.bv_val = (char *) in;
+       } else if ( flags == SASL_CU_AUTHZID && conn->c_sasl_dn.bv_val ) {
+               rc = strcmp( in, conn->c_sasl_dn.bv_val );
+               conn->c_sasl_dn.bv_val = NULL;
+               /* They were equal, no work needed */
+               if ( !rc ) goto done;
        }
 
        rc = slap_sasl_getdn( conn, (char *)in, inlen, (char *)user_realm, &dn,
@@ -1091,11 +1101,35 @@ int slap_sasl_init( void )
                { SASL_CB_LIST_END, NULL, NULL }
        };
 
+#ifdef HAVE_SASL_VERSION
+#define SASL_BUILD_VERSION ((SASL_VERSION_MAJOR << 24) |\
+       (SASL_VERSION_MINOR << 16) | SASL_VERSION_STEP)
+
+       sasl_version( NULL, &rc );
+       if ( ((rc >> 16) != ((SASL_VERSION_MAJOR << 8)|SASL_VERSION_MINOR)) ||
+               (rc & 0xffff) < SASL_VERSION_STEP) {
+
+#ifdef NEW_LOGGING
+               LDAP_LOG( TRANSPORT, INFO,
+               "slap_sasl_init: SASL version mismatch, got %x, wanted %x.\n",
+                       rc, SASL_BUILD_VERSION, 0 );
+#else
+               Debug( LDAP_DEBUG_ANY,
+               "slap_sasl_init: SASL version mismatch, got %x, wanted %x.\n",
+                       rc, SASL_BUILD_VERSION, 0 );
+#endif
+               return -1;
+       }
+#endif
+
+       /* SASL 2 does its own memory management internally */
+#if SASL_VERSION_MAJOR < 2
        sasl_set_alloc(
                ber_memalloc,
                ber_memcalloc,
                ber_memrealloc,
                ber_memfree ); 
+#endif
 
        sasl_set_mutex(
                ldap_pvt_sasl_mutex_new,
@@ -1117,6 +1151,10 @@ int slap_sasl_init( void )
                Debug( LDAP_DEBUG_ANY, "sasl_server_init failed\n",
                        0, 0, 0 );
 #endif
+#if SASL_VERSION_MAJOR < 2
+               /* A no-op used to make sure we linked with Cyrus 1.5 */
+               sasl_client_auth( NULL, NULL, NULL, 0, NULL, NULL );
+#endif
 
                return -1;
        }