+ rc = LDAP_PROTOCOL_ERROR;
+ if ( !strncasecmp( uri->bv_val, "dn", sizeof( "dn" ) - 1 ) ) {
+ bv.bv_val = uri->bv_val + sizeof( "dn" ) - 1;
+
+ if ( bv.bv_val[ 0 ] == '.' ) {
+ bv.bv_val++;
+
+ if ( !strncasecmp( bv.bv_val, "exact:", sizeof( "exact:" ) - 1 ) ) {
+ bv.bv_val += sizeof( "exact:" ) - 1;
+ *scope = LDAP_X_SCOPE_EXACT;
+
+ } else if ( !strncasecmp( bv.bv_val, "regex:", sizeof( "regex:" ) - 1 ) ) {
+ bv.bv_val += sizeof( "regex:" ) - 1;
+ *scope = LDAP_X_SCOPE_REGEX;
+
+ } else if ( !strncasecmp( bv.bv_val, "children:", sizeof( "chldren:" ) - 1 ) ) {
+ bv.bv_val += sizeof( "children:" ) - 1;
+ *scope = LDAP_X_SCOPE_CHILDREN;
+
+ } else if ( !strncasecmp( bv.bv_val, "subtree:", sizeof( "subtree:" ) - 1 ) ) {
+ bv.bv_val += sizeof( "subtree:" ) - 1;
+ *scope = LDAP_X_SCOPE_SUBTREE;
+
+ } else if ( !strncasecmp( bv.bv_val, "onelevel:", sizeof( "onelevel:" ) - 1 ) ) {
+ bv.bv_val += sizeof( "onelevel:" ) - 1;
+ *scope = LDAP_X_SCOPE_ONELEVEL;
+
+ } else {
+ return LDAP_PROTOCOL_ERROR;
+ }
+ } else {
+ if ( bv.bv_val[ 0 ] != ':' ) {
+ return LDAP_PROTOCOL_ERROR;
+ }
+ *scope = LDAP_X_SCOPE_EXACT;
+ bv.bv_val++;
+ }
+
+ bv.bv_val += strspn( bv.bv_val, " " );
+ /* jump here in case no type specification was present
+ * and uir was not an URI... HEADS-UP: assuming EXACT */
+is_dn: bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val);
+
+ switch ( *scope ) {
+ case LDAP_X_SCOPE_EXACT:
+ case LDAP_X_SCOPE_CHILDREN:
+ case LDAP_X_SCOPE_SUBTREE:
+ case LDAP_X_SCOPE_ONELEVEL:
+ rc = dnNormalize( 0, NULL, NULL, &bv, nbase, op->o_tmpmemctx );
+ if( rc != LDAP_SUCCESS ) {
+ *scope = -1;
+ }
+ break;
+
+ case LDAP_X_SCOPE_REGEX:
+ ber_dupbv_x( nbase, &bv, op->o_tmpmemctx );
+ rc = LDAP_SUCCESS;
+ break;
+
+ default:
+ *scope = -1;
+ break;
+ }
+
+ return rc;
+
+ } else if ( ( uri->bv_val[ 0 ] == 'u' || uri->bv_val[ 0 ] == 'U' )
+ && ( uri->bv_val[ 1 ] == ':'
+ || uri->bv_val[ 1 ] == '/'
+ || uri->bv_val[ 1 ] == '.' ) )
+ {
+ Connection c = *op->o_conn;
+ char buf[ SLAP_LDAPDN_MAXLEN ];
+ struct berval id,
+ user = BER_BVNULL,
+ realm = BER_BVNULL,
+ mech = BER_BVNULL;
+
+ if ( sizeof( buf ) <= uri->bv_len ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+
+ id.bv_len = uri->bv_len;
+ id.bv_val = buf;
+ strncpy( buf, uri->bv_val, sizeof( buf ) );
+
+ rc = slap_parse_user( &id, &user, &realm, &mech );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ if ( mech.bv_val ) {
+ c.c_sasl_bind_mech = mech;
+ } else {
+ c.c_sasl_bind_mech.bv_val = "AUTHZ";
+ c.c_sasl_bind_mech.bv_len = sizeof( "AUTHZ" ) - 1;
+ }
+
+ rc = slap_sasl_getdn( &c, op, user.bv_val, user.bv_len,
+ realm.bv_val, nbase, SLAP_GETDN_AUTHZID );
+
+ if ( rc == LDAP_SUCCESS ) {
+ *scope = LDAP_X_SCOPE_EXACT;
+ }
+
+ return rc;
+ }
+
+ rc = ldap_url_parse( uri->bv_val, &ludp );
+ if ( rc == LDAP_URL_ERR_BADSCHEME ) {
+ /* last chance: assume it's a(n exact) DN ... */
+ bv.bv_val = uri->bv_val;
+ *scope = LDAP_X_SCOPE_EXACT;
+ goto is_dn;
+ }
+
+ if ( rc != LDAP_URL_SUCCESS ) {
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ if (( ludp->lud_host && *ludp->lud_host )
+ || ludp->lud_attrs || ludp->lud_exts )
+ {
+ /* host part must be empty */
+ /* attrs and extensions parts must be empty */
+ rc = LDAP_PROTOCOL_ERROR;
+ goto done;
+ }
+
+ /* Grab the scope */
+ *scope = ludp->lud_scope;
+
+ /* Grab the filter */
+ if ( ludp->lud_filter ) {
+ *filter = str2filter_x( op, ludp->lud_filter );
+ if ( *filter == NULL ) {
+ rc = LDAP_PROTOCOL_ERROR;
+ goto done;
+ }
+ ber_str2bv( ludp->lud_filter, 0, 0, fstr );
+ }
+
+ /* Grab the searchbase */
+ ber_str2bv( ludp->lud_dn, 0, 0, base );
+ rc = dnNormalize( 0, NULL, NULL, base, nbase, op->o_tmpmemctx );
+
+done:
+ if( rc != LDAP_SUCCESS ) {
+ if( *filter ) filter_free_x( op, *filter );
+ base->bv_val = NULL;
+ base->bv_len = 0;
+ fstr->bv_val = NULL;
+ fstr->bv_len = 0;
+ } else {
+ /* Don't free these, return them to caller */
+ ludp->lud_filter = NULL;
+ ludp->lud_dn = NULL;