+#endif
+ ber_bvfree( pdn );
+ ber_bvfree( ndn );
+
+ } else if ( tmp_be != NULL ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_INFO,
+ "%s: line %d: suffix already served by a preceding "
+ "backend \"%s\"\n", fname, lineno,
+ tmp_be->be_suffix[0]->bv_val ));
+#else
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix "
+ "already served by a preceeding backend \"%s\"\n",
+ fname, lineno, tmp_be->be_suffix[0]->bv_val );
+#endif
+ ber_bvfree( pdn );
+ ber_bvfree( ndn );
+ return( 1 );
+
+ } else if( pdn->bv_len == 0 && default_search_nbase.bv_len ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_INFO,
+ "%s: line %d: suffix DN empty and default search "
+ "base provided \"%s\" (assuming okay).\n",
+ fname, lineno, default_search_base.bv_val ));
+#else
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "suffix DN empty and default "
+ "search base provided \"%s\" (assuming okay)\n",
+ fname, lineno, default_search_base.bv_val );
+#endif
+ }
+
+ ber_bvecadd( &be->be_suffix, pdn );
+ ber_bvecadd( &be->be_nsuffix, ndn );
+
+ /* set database suffixAlias */
+ } else if ( strcasecmp( cargv[0], "suffixAlias" ) == 0 ) {
+ Backend *tmp_be;
+ struct berval alias, *palias, nalias;
+ struct berval aliased, *paliased, naliased;
+
+ if ( cargc < 2 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+ "%s: line %d: missing alias and aliased_dn in "
+ "\"suffixAlias <alias> <aliased_dn>\" line.\n",
+ fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing alias and aliased_dn in "
+ "\"suffixAlias <alias> <aliased_dn>\" line.\n",
+ fname, lineno, 0 );
+#endif
+
+ return( 1 );
+ } else if ( cargc < 3 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+ "%s: line %d: missing aliased_dn in "
+ "\"suffixAlias <alias> <aliased_dn>\" line\n",
+ fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing aliased_dn in "
+ "\"suffixAlias <alias> <aliased_dn>\" line\n",
+ fname, lineno, 0 );
+#endif
+
+ return( 1 );
+ } else if ( cargc > 3 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+ "%s: line %d: extra cruft in suffixAlias line (ignored)\n",
+ fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: extra cruft in suffixAlias line (ignored)\n",
+ fname, lineno, 0 );
+#endif
+
+ }
+
+ if ( be == NULL ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_INFO,
+ "%s: line %d: suffixAlias line must appear inside a "
+ "database definition (ignored).\n", fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: suffixAlias line"
+ " must appear inside a database definition (ignored)\n",
+ fname, lineno, 0 );
+#endif
+ }
+
+ if ( load_ucdata( NULL ) < 0 ) return 1;
+
+ alias.bv_val = cargv[1];
+ alias.bv_len = strlen( cargv[1] );
+ palias = ch_malloc(sizeof(struct berval));
+
+ rc = dnPrettyNormal( NULL, &alias, palias, &nalias );
+ if( rc != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+ "%s: line %d: alias DN is invalid.\n",
+ fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: alias DN is invalid\n",
+ fname, lineno, 0 );
+#endif
+ return( 1 );
+ }
+
+ tmp_be = select_backend( &nalias, 0, 0 );
+ free( nalias.bv_val );
+ if ( tmp_be && tmp_be != be ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_INFO,
+ "%s: line %d: suffixAlias served by a preceeding "
+ "backend \"%s\"\n",
+ fname, lineno, tmp_be->be_suffix[0]->bv_val ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: suffixAlias served by"
+ " a preceeding backend \"%s\"\n",
+ fname, lineno, tmp_be->be_suffix[0]->bv_val );
+#endif
+ ber_bvfree( palias );
+ return -1;
+ }
+
+ aliased.bv_val = cargv[2];
+ aliased.bv_len = strlen( cargv[2] );
+ paliased = ch_malloc(sizeof(struct berval));
+
+ rc = dnPrettyNormal( NULL, &aliased, paliased, &naliased );
+ if( rc != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+ "%s: line %d: aliased DN is invalid.\n",
+ fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: aliased DN is invalid\n",
+ fname, lineno, 0 );
+#endif
+ ber_bvfree( palias );
+ return( 1 );
+ }
+
+ tmp_be = select_backend( &naliased, 0, 0 );
+ free( naliased.bv_val );
+ if ( tmp_be && tmp_be != be ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_INFO,
+ "%s: line %d: suffixAlias derefs to a different backend "
+ "a preceeding backend \"%s\"\n",
+ fname, lineno, tmp_be->be_suffix[0]->bv_val ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: suffixAlias derefs to differnet backend"
+ " a preceeding backend \"%s\"\n",
+ fname, lineno, tmp_be->be_suffix[0]->bv_val );
+#endif
+ ber_bvfree( palias );
+ ber_bvfree( paliased );
+ return -1;
+ }
+
+ ber_bvecadd( &be->be_suffixAlias, palias );
+ ber_bvecadd( &be->be_suffixAlias, paliased );
+
+ /* set max deref depth */
+ } else if ( strcasecmp( cargv[0], "maxDerefDepth" ) == 0 ) {
+ int i;
+ if ( cargc < 2 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+ "%s: line %d: missing depth in \"maxDerefDepth <depth>\""
+ " line\n", fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing depth in \"maxDerefDepth <depth>\" line\n",
+ fname, lineno, 0 );
+#endif
+
+ return( 1 );
+ }
+ if ( be == NULL ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_INFO,
+ "%s: line %d: depth line must appear inside a database "
+ "definition (ignored)\n", fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+"%s: line %d: depth line must appear inside a database definition (ignored)\n",
+ fname, lineno, 0 );
+#endif
+
+ } else if ((i = atoi(cargv[1])) < 0) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_INFO,
+ "%s: line %d: depth must be positive (ignored).\n",
+ fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+"%s: line %d: depth must be positive (ignored)\n",
+ fname, lineno, 0 );
+#endif
+
+
+ } else {
+ be->be_max_deref_depth = i;
+ }
+
+
+ /* set magic "root" dn for this database */
+ } else if ( strcasecmp( cargv[0], "rootdn" ) == 0 ) {
+ if ( cargc < 2 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_INFO,
+ "%s: line %d: missing dn in \"rootdn <dn>\" line.\n",
+ fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing dn in \"rootdn <dn>\" line\n",
+ fname, lineno, 0 );
+#endif
+
+ return( 1 );
+ }
+ if ( be == NULL ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_INFO,
+ "%s: line %d: rootdn line must appear inside a database "
+ "definition (ignored).\n", fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+"%s: line %d: rootdn line must appear inside a database definition (ignored)\n",
+ fname, lineno, 0 );
+#endif
+
+ } else {
+ struct berval dn;
+
+ if ( load_ucdata( NULL ) < 0 ) return 1;
+
+ dn.bv_val = cargv[1];
+ dn.bv_len = strlen( cargv[1] );
+
+ rc = dnPrettyNormal( NULL, &dn,
+ &be->be_rootdn,
+ &be->be_rootndn );
+
+ if( rc != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+ "%s: line %d: rootdn DN is invalid.\n",
+ fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: rootdn DN is invalid\n",
+ fname, lineno, 0 );
+#endif
+ return( 1 );
+ }
+ }
+
+ /* set super-secret magic database password */
+ } else if ( strcasecmp( cargv[0], "rootpw" ) == 0 ) {
+ if ( cargc < 2 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+ "%s: line %d: missing passwd in \"rootpw <passwd>\""
+ " line\n", fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing passwd in \"rootpw <passwd>\" line\n",
+ fname, lineno, 0 );
+#endif
+
+ return( 1 );
+ }
+ if ( be == NULL ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_INFO,
+ "%s: line %d: rootpw line must appear inside a database "
+ "definition (ignored)\n", fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+"%s: line %d: rootpw line must appear inside a database definition (ignored)\n",
+ fname, lineno, 0 );
+#endif
+
+ } else {
+ be->be_rootpw.bv_val = ch_strdup( cargv[1] );
+ be->be_rootpw.bv_len = strlen( be->be_rootpw.bv_val );
+ }
+
+ /* make this database read-only */
+ } else if ( strcasecmp( cargv[0], "readonly" ) == 0 ) {
+ if ( cargc < 2 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+ "%s: line %d: missing on|off in \"readonly <on|off>\" line.\n",
+ fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing on|off in \"readonly <on|off>\" line\n",
+ fname, lineno, 0 );
+#endif
+
+ return( 1 );
+ }
+ if ( be == NULL ) {
+ if ( strcasecmp( cargv[1], "on" ) == 0 ) {
+ global_restrictops |= SLAP_RESTRICT_OP_WRITES;
+ } else {
+ global_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
+ }
+ } else {
+ if ( strcasecmp( cargv[1], "on" ) == 0 ) {
+ be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
+ } else {
+ be->be_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
+ }
+ }
+
+
+ /* allow these features */
+ } else if ( strcasecmp( cargv[0], "allows" ) == 0 ||
+ strcasecmp( cargv[0], "allow" ) == 0 )
+ {
+ slap_mask_t allows;
+
+ if ( be != NULL ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_INFO,
+ "%s: line %d: allow line must appear prior to "
+ "database definitions.\n", fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+"%s: line %d: allow line must appear prior to database definitions\n",
+ fname, lineno, 0 );
+#endif
+
+ }
+
+ if ( cargc < 2 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+ "%s: line %d: missing feature(s) in \"allow <features>\""
+ " line\n", fname, lineno ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing feature(s) in \"allow <features>\" line\n",
+ fname, lineno, 0 );
+#endif
+
+ return( 1 );
+ }
+
+ allows = 0;
+
+ for( i=1; i < cargc; i++ ) {
+ if( strcasecmp( cargv[i], "bind_v2" ) == 0 ) {
+ allows |= SLAP_ALLOW_BIND_V2;
+
+ } else if( strcasecmp( cargv[i], "bind_anon_cred" ) == 0 ) {
+ allows |= SLAP_ALLOW_BIND_ANON_CRED;
+
+ } else if( strcasecmp( cargv[i], "bind_anon_dn" ) == 0 ) {
+ allows |= SLAP_ALLOW_BIND_ANON_DN;
+
+ } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+ "%s: line %d: unknown feature %s in "
+ "\"allow <features>\" line.\n",
+ fname, lineno, cargv[1] ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: unknown feature %s in \"allow <features>\" line\n",
+ fname, lineno, cargv[i] );
+#endif
+
+ return( 1 );
+ }
+ }
+
+ global_allows = allows;
+
+ /* disallow these features */
+ } else if ( strcasecmp( cargv[0], "disallows" ) == 0 ||
+ strcasecmp( cargv[0], "disallow" ) == 0 )
+ {
+ slap_mask_t disallows;
+
+ if ( be != NULL ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "config", LDAP_LEVEL_INFO,
+ "%s: line %d: disallow line must appear prior to "
+ "database definitions.\n", fname, lineno ));
+#else