+ rc = slap_parseURI( ®out, &dn, &scope, &filter );
+ if( regout.bv_val ) ch_free( regout.bv_val );
+ if( rc != LDAP_SUCCESS ) {
+ goto FINISHED;
+ }
+
+ /* Must do an internal search */
+ be = select_backend( &dn, 0, 1 );
+
+ /* Massive shortcut: search scope == base */
+ if( scope == LDAP_SCOPE_BASE ) {
+ *sasldn = dn;
+ dn.bv_len = 0;
+ dn.bv_val = NULL;
+ goto FINISHED;
+ }
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( TRANSPORT, DETAIL1,
+ "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
+ dn.bv_val, scope, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
+ dn.bv_val, scope, 0 );
+#endif
+
+ if(( be == NULL ) || ( be->be_search == NULL)) {
+ goto FINISHED;
+ }
+ suffix_alias( be, &dn );
+
+ op.o_tag = LDAP_REQ_SEARCH;
+ op.o_protocol = LDAP_VERSION3;
+ op.o_ndn = conn->c_ndn;
+ 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,
+ scope, LDAP_DEREF_NEVER, 1, 0,
+ filter, NULL, NULL, 1 );
+
+FINISHED:
+ if( sasldn->bv_len ) {
+ conn->c_authz_backend = be;
+ }
+ if( dn.bv_len ) ch_free( dn.bv_val );
+ if( filter ) filter_free( filter );
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( TRANSPORT, ENTRY,
+ "slap_sasl2dn: Converted SASL name to %s\n",
+ sasldn->bv_len ? sasldn->bv_val : "<nothing>", 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "<==slap_sasl2dn: Converted SASL name to %s\n",
+ sasldn->bv_len ? sasldn->bv_val : "<nothing>", 0, 0 );
+#endif
+
+ return;
+}
+
+
+/* Check if a bind can SASL authorize to another identity.
+ * The DNs should not have the dn: prefix
+ */
+
+int slap_sasl_authorized( Connection *conn,
+ struct berval *authcDN, struct berval *authzDN )