#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
#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 )
*/
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;
op.o_callback = &cb;
op.o_time = slap_get_time();
op.o_do_not_cache = 1;
+ op.o_threadctx = conn->c_sasl_bindop->o_threadctx;
(*be->be_search)( be, conn, &op, NULL, &dn,
LDAP_SCOPE_BASE, LDAP_DEREF_NEVER, 1, 0,
op.o_callback = &cb;
op.o_time = slap_get_time();
op.o_do_not_cache = 1;
+ op.o_threadctx = conn->c_sasl_bindop->o_threadctx;
(*be->be_search)( be, conn, &op, NULL, &dn,
LDAP_SCOPE_BASE, LDAP_DEREF_NEVER, 1, 0,
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,
{ 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,
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;
}
return NULL;
}
- mechs = str2charray( mechstr, "," );
+ mechs = ldap_str2charray( mechstr, "," );
#if SASL_VERSION_MAJOR < 2
ch_free( mechstr );