+/*
+ * Given a SASL name (e.g. "UID=name,cn=REALM,cn=MECH,cn=AUTH")
+ * return the LDAP DN to which it matches. The SASL regexp rules in the config
+ * file turn the SASL name into an LDAP URI. If the URI is just a DN (or a
+ * search with scope=base), just return the URI (or its searchbase). Otherwise
+ * an internal search must be done, and if that search returns exactly one
+ * entry, return the DN of that one entry.
+ */
+void slap_sasl2dn( Operation *opx,
+ struct berval *saslname, struct berval *sasldn )
+{
+ int rc;
+ slap_callback cb = { sasl_sc_sasl2dn };
+ Operation op = {0};
+ SlapReply rs = {REP_RESULT};
+ struct berval regout = { 0, NULL };
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( TRANSPORT, ENTRY,
+ "slap_sasl2dn: converting SASL name %s to DN.\n",
+ saslname->bv_val, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "==>slap_sasl2dn: "
+ "converting SASL name %s to a DN\n",
+ saslname->bv_val, 0,0 );
+#endif
+
+ sasldn->bv_val = NULL;
+ sasldn->bv_len = 0;
+ cb.sc_private = sasldn;
+
+ /* Convert the SASL name into a minimal URI */
+ if( !slap_sasl_regexp( saslname, ®out, opx->o_tmpmemctx ) ) {
+ goto FINISHED;
+ }
+
+ rc = slap_parseURI( opx, ®out, &op.o_req_ndn, &op.oq_search.rs_scope, &op.oq_search.rs_filter );
+ if( regout.bv_val ) sl_free( regout.bv_val, opx->o_tmpmemctx );
+ if( rc != LDAP_SUCCESS ) {
+ goto FINISHED;
+ }
+
+ /* Must do an internal search */
+ op.o_bd = select_backend( &op.o_req_ndn, 0, 1 );
+
+ /* Massive shortcut: search scope == base */
+ if( op.oq_search.rs_scope == LDAP_SCOPE_BASE ) {
+ *sasldn = op.o_req_ndn;
+ op.o_req_ndn.bv_len = 0;
+ op.o_req_ndn.bv_val = NULL;
+ goto FINISHED;
+ }