]> git.sur5r.net Git - openldap/commitdiff
First stable an implementing latest namedref specification.
authorKurt Zeilenga <kurt@openldap.org>
Fri, 26 Oct 2001 02:05:14 +0000 (02:05 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Fri, 26 Oct 2001 02:05:14 +0000 (02:05 +0000)
Includes rewriting of URLs where the DN of the referral object
and the DN of the ref attribute attribute are not the same.
Also, always returns explicit DN and scope.
Currently, back-ldbm only.  Needs to be ported to back-bdb.

25 files changed:
servers/slapd/Makefile.in
servers/slapd/add.c
servers/slapd/back-ldbm/add.c
servers/slapd/back-ldbm/bind.c
servers/slapd/back-ldbm/compare.c
servers/slapd/back-ldbm/delete.c
servers/slapd/back-ldbm/modify.c
servers/slapd/back-ldbm/modrdn.c
servers/slapd/back-ldbm/referral.c
servers/slapd/back-ldbm/search.c
servers/slapd/bind.c
servers/slapd/compare.c
servers/slapd/config.c
servers/slapd/delete.c
servers/slapd/extended.c
servers/slapd/modify.c
servers/slapd/modrdn.c
servers/slapd/passwd.c
servers/slapd/proto-slap.h
servers/slapd/referral.c [new file with mode: 0644]
servers/slapd/result.c
servers/slapd/search.c
servers/slapd/tools/Makefile.in
servers/slapd/tools/mimic.c
tests/data/slapd-repl-slave.conf

index 75d8f5d25a7446fd72a4ca8eb4957448e1a7ab61..a8bdfa687f06fa98b307174a3e314d2dc5ecd281 100644 (file)
@@ -17,7 +17,7 @@ SRCS  = main.c daemon.c connection.c search.c filter.c add.c charray.c \
                repl.c lock.c controls.c extended.c kerberos.c passwd.c \
                schema.c schema_check.c schema_init.c schema_prep.c \
                schemaparse.c ad.c at.c mr.c syntax.c oc.c saslauthz.c \
-               configinfo.c starttls.c index.c sets.c \
+               configinfo.c starttls.c index.c sets.c referral.c \
                root_dse.c sasl.c module.c suffixalias.c mra.c mods.c \
                limits.c \
                $(@PLAT@_SRCS)
@@ -30,7 +30,7 @@ OBJS  = main.o daemon.o connection.o search.o filter.o add.o charray.o \
                repl.o lock.o controls.o extended.o kerberos.o passwd.o \
                schema.o schema_check.o schema_init.o schema_prep.o \
                schemaparse.o ad.o at.o mr.o syntax.o oc.o saslauthz.o \
-               configinfo.o starttls.o index.o sets.o \
+               configinfo.o starttls.o index.o sets.o referral.o \
                root_dse.o sasl.o module.o suffixalias.o mra.o mods.o \
                limits.o \
                $(@PLAT@_OBJS)
index 238c8f1d0b7068aaa17e0ea80b1eb6e816ba8572..6d733cf81d5bdd85cd95b23b2589de34cbeeba5c 100644 (file)
@@ -209,8 +209,13 @@ do_add( Connection *conn, Operation *op )
         */
        be = select_backend( e->e_ndn, manageDSAit );
        if ( be == NULL ) {
+               struct berval **ref = referral_rewrite( default_referral,
+                       NULL, e->e_dn, LDAP_SCOPE_DEFAULT );
+
                send_ldap_result( conn, op, rc = LDAP_REFERRAL,
-                       NULL, NULL, default_referral, NULL );
+                       NULL, NULL, ref ? ref : default_referral, NULL );
+
+               ber_bvecfree( ref );
                goto done;
        }
 
@@ -294,8 +299,15 @@ do_add( Connection *conn, Operation *op )
 
 #ifndef SLAPD_MULTIMASTER
                } else {
+                       struct berval **defref = be->be_update_refs
+                               ? be->be_update_refs : default_referral;
+                       struct berval **ref = referral_rewrite( defref,
+                               NULL, e->e_dn, LDAP_SCOPE_DEFAULT );
+
                        send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL, NULL,
-                               be->be_update_refs ? be->be_update_refs : default_referral, NULL );
+                               ref ? ref : defref, NULL );
+
+                       ber_bvecfree( ref );
 #endif
                }
        } else {
@@ -387,4 +399,3 @@ static int slap_mods2entry(
 
        return LDAP_SUCCESS;
 }
-
index 99dfe0fdb50c8ae4ba3c31d066f7ab254afa4562..71fb24b1859f1eb265b7353e4472f954ea30d4a5 100644 (file)
@@ -37,12 +37,11 @@ ldbm_back_add(
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,"ldbm_back_add: %s\n",
-                  e->e_dn ));
+               e->e_dn ));
 #else
        Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", e->e_dn, 0, 0);
 #endif
 
-
        /* nobody else can add until we lock our parent */
        ldap_pvt_thread_mutex_lock(&li->li_add_mutex);
 
@@ -62,8 +61,8 @@ ldbm_back_add(
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
-                          "ldbm_back_add: entry (%s) failed schema check.\n",
-                          e->e_dn ));
+                       "ldbm_back_add: entry (%s) failed schema check.\n",
+                       e->e_dn ));
 #else
                Debug( LDAP_DEBUG_TRACE, "entry failed schema check: %s\n",
                        text, 0, 0 );
@@ -90,7 +89,7 @@ ldbm_back_add(
 
                /* get parent with writer lock */
                if ( (p = dn2entry_w( be, pdn, &matched )) == NULL ) {
-                       char *matched_dn;
+                       char *matched_dn = NULL;
                        struct berval **refs;
 
                        ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
@@ -98,33 +97,31 @@ ldbm_back_add(
                        if ( matched != NULL ) {
                                matched_dn = ch_strdup( matched->e_dn );
                                refs = is_entry_referral( matched )
-                                       ? get_entry_referrals( be, conn, op, matched )
+                                       ? get_entry_referrals( be, conn, op, matched,
+                                               e->e_dn, LDAP_SCOPE_DEFAULT )
                                        : NULL;
                                cache_return_entry_r( &li->li_cache, matched );
 
                        } else {
-                               matched_dn = NULL;
-                               refs = default_referral;
+                               refs = referral_rewrite( default_referral,
+                                       NULL, e->e_dn, LDAP_SCOPE_DEFAULT );
                        }
 
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
-                                  "ldbm_back_add: Parent of (%s) does not exist.\n",
-                                  e->e_dn ));
+                               "ldbm_back_add: Parent of (%s) does not exist.\n",
+                               e->e_dn ));
 #else
                        Debug( LDAP_DEBUG_TRACE, "parent does not exist\n",
                                0, 0, 0 );
 #endif
 
-
                        send_ldap_result( conn, op, LDAP_REFERRAL, matched_dn,
                                refs == NULL ? "parent does not exist" : "parent is referral",
                                refs, NULL );
 
-                       if( matched != NULL ) {
-                               ber_bvecfree( refs );
-                               free( matched_dn );
-                       }
+                       ber_bvecfree( refs );
+                       free( matched_dn );
 
                        free( pdn );
                        return -1;
@@ -182,7 +179,8 @@ ldbm_back_add(
                        /* parent is a referral, don't allow add */
                        char *matched_dn = ch_strdup( p->e_dn );
                        struct berval **refs = is_entry_referral( p )
-                               ? get_entry_referrals( be, conn, op, p )
+                               ? get_entry_referrals( be, conn, op, p,
+                                       e->e_dn, LDAP_SCOPE_DEFAULT )
                                : NULL;
 
                        /* free parent and writer lock */
@@ -290,7 +288,6 @@ ldbm_back_add(
                    0 );
 #endif
 
-
                send_ldap_result( conn, op,
                        rc > 0 ? LDAP_ALREADY_EXISTS : LDAP_OTHER,
                        NULL, rc > 0 ? NULL : "cache add failed", NULL, NULL );
index d33ea5fd30fea15cff04784244e31be604d28e41..af73ca9a0da9840559556db89b32ac54eceb151e 100644 (file)
@@ -45,7 +45,7 @@ ldbm_back_bind(
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
-                  "ldbm_back_bind: dn: %s.\n", dn ));
+               "ldbm_back_bind: dn: %s.\n", dn ));
 #else
        Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_bind: dn: %s\n", dn, 0, 0);
 #endif
@@ -63,12 +63,15 @@ ldbm_back_bind(
                        matched_dn = ch_strdup( matched->e_dn );
 
                        refs = is_entry_referral( matched )
-                               ? get_entry_referrals( be, conn, op, matched )
+                               ? get_entry_referrals( be, conn, op, matched,
+                                       dn, LDAP_SCOPE_DEFAULT )
                                : NULL;
 
                        cache_return_entry_r( &li->li_cache, matched );
+
                } else {
-                       refs = default_referral;
+                       refs = referral_rewrite( default_referral,
+                               NULL, dn, LDAP_SCOPE_DEFAULT );
                }
 
                /* allow noauth binds */
@@ -96,10 +99,8 @@ ldbm_back_bind(
                                NULL, NULL, NULL, NULL );
                }
 
-               if ( matched != NULL ) {
-                       ber_bvecfree( refs );
-                       free( matched_dn );
-               }
+               ber_bvecfree( refs );
+               free( matched_dn );
                return( rc );
        }
 
@@ -128,7 +129,7 @@ ldbm_back_bind(
        if ( is_entry_referral( e ) ) {
                /* entry is a referral, don't allow bind */
                struct berval **refs = get_entry_referrals( be,
-                       conn, op, e );
+                       conn, op, e, dn, LDAP_SCOPE_DEFAULT );
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
index b722de01fb592a12f620e50463389b686b4953da..4134bb115fe5500ffca26344fe73d2e034255d52 100644 (file)
@@ -41,20 +41,20 @@ ldbm_back_compare(
                if ( matched != NULL ) {
                        matched_dn = ch_strdup( matched->e_dn );
                        refs = is_entry_referral( matched )
-                               ? get_entry_referrals( be, conn, op, matched )
+                               ? get_entry_referrals( be, conn, op, matched,
+                                       dn, LDAP_SCOPE_DEFAULT )
                                : NULL;
                        cache_return_entry_r( &li->li_cache, matched );
                } else {
-                       refs = default_referral;
+                       refs = referral_rewrite( default_referral,
+                               NULL, dn, LDAP_SCOPE_DEFAULT );
                }
 
                send_ldap_result( conn, op, LDAP_REFERRAL,
                        matched_dn, NULL, refs, NULL );
 
-               if( matched != NULL ) {
-                       ber_bvecfree( refs );
-                       free( matched_dn );
-               }
+               ber_bvecfree( refs );
+               free( matched_dn );
 
                return( 1 );
        }
@@ -62,7 +62,7 @@ ldbm_back_compare(
        if (!manageDSAit && is_entry_referral( e ) ) {
                /* entry is a referral, don't allow add */
                struct berval **refs = get_entry_referrals( be,
-                       conn, op, e );
+                       conn, op, e, dn, LDAP_SCOPE_DEFAULT );
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
index 9e14f260f31bcc239a4ff6643ea320bc2aff1496..1dd4696ed34f9245756dc0ef143e8fac622774eb 100644 (file)
@@ -36,43 +36,42 @@ ldbm_back_delete(
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
-                  "ldbm_back_delete: %s\n", dn ));
+               "ldbm_back_delete: %s\n", dn ));
 #else
        Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_delete: %s\n", dn, 0, 0);
 #endif
 
-
        /* get entry with writer lock */
        if ( (e = dn2entry_w( be, ndn, &matched )) == NULL ) {
                char *matched_dn = NULL;
-               struct berval **refs = NULL;
+               struct berval **refs;
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
-                          "ldbm_back_delete: no such object %s\n", dn ));
+                       "ldbm_back_delete: no such object %s\n", dn ));
 #else
                Debug(LDAP_DEBUG_ARGS, "<=- ldbm_back_delete: no such object %s\n",
                        dn, 0, 0);
 #endif
 
-
                if ( matched != NULL ) {
                        matched_dn = ch_strdup( matched->e_dn );
                        refs = is_entry_referral( matched )
-                               ? get_entry_referrals( be, conn, op, matched )
+                               ? get_entry_referrals( be, conn, op, matched,
+                                       dn, LDAP_SCOPE_DEFAULT )
                                : NULL;
                        cache_return_entry_r( &li->li_cache, matched );
+
                } else {
-                       refs = default_referral;
+                       refs = referral_rewrite( default_referral,
+                               NULL, dn, LDAP_SCOPE_DEFAULT );
                }
 
                send_ldap_result( conn, op, LDAP_REFERRAL,
                        matched_dn, NULL, refs, NULL );
 
-               if ( matched != NULL ) {
-                       ber_bvecfree( refs );
-                       free( matched_dn );
-               }
+               ber_bvecfree( refs );
+               free( matched_dn );
 
                return( -1 );
        }
@@ -81,7 +80,7 @@ ldbm_back_delete(
                /* parent is a referral, don't allow add */
                /* parent is an alias, don't allow add */
                struct berval **refs = get_entry_referrals( be,
-                       conn, op, e );
+                       conn, op, e, dn, LDAP_SCOPE_DEFAULT );
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
index 18c83efc7c8883a71b232c1a6a050e0fbc94443e..37fb844dd937ed23f0b5312ecb6792e6a3719570 100644 (file)
@@ -46,7 +46,7 @@ int ldbm_modify_internal(
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
-                  "ldbm_modify_internal: %s\n", dn ));
+               "ldbm_modify_internal: %s\n", dn ));
 #else
        Debug(LDAP_DEBUG_TRACE, "ldbm_modify_internal: %s\n", dn, 0, 0);
 #endif
@@ -66,7 +66,7 @@ int ldbm_modify_internal(
                case LDAP_MOD_ADD:
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
-                                  "ldbm_modify_internal: add\n" ));
+                               "ldbm_modify_internal: add\n" ));
 #else
                        Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: add\n", 0, 0, 0);
 #endif
@@ -77,8 +77,8 @@ int ldbm_modify_internal(
                                *text = "modify: add values failed";
 #ifdef NEW_LOGGING
                                LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
-                                          "ldbm_modify_internal: failed %d (%s)\n",
-                                          err, *text ));
+                                       "ldbm_modify_internal: failed %d (%s)\n",
+                                       err, *text ));
 #else
                                Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n",
                                        err, *text, 0);
@@ -89,7 +89,7 @@ int ldbm_modify_internal(
                case LDAP_MOD_DELETE:
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
-                                  "ldbm_modify_internal: delete\n" ));
+                               "ldbm_modify_internal: delete\n" ));
 #else
                        Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: delete\n", 0, 0, 0);
 #endif
@@ -100,7 +100,7 @@ int ldbm_modify_internal(
                                *text = "modify: delete values failed";
 #ifdef NEW_LOGGING
                                LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
-                                          "ldbm_modify_internal: failed %d (%s)\n", err, *text ));
+                                       "ldbm_modify_internal: failed %d (%s)\n", err, *text ));
 #else
                                Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n",
                                        err, *text, 0);
@@ -111,7 +111,7 @@ int ldbm_modify_internal(
                case LDAP_MOD_REPLACE:
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
-                                  "ldbm_modify_internal:  replace\n" ));
+                               "ldbm_modify_internal:  replace\n" ));
 #else
                        Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: replace\n", 0, 0, 0);
 #endif
@@ -122,7 +122,7 @@ int ldbm_modify_internal(
                                *text = "modify: replace values failed";
 #ifdef NEW_LOGGING
                                LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
-                                          "ldbm_modify_internal: failed %d (%s)\n", err, *text ));
+                                       "ldbm_modify_internal: failed %d (%s)\n", err, *text ));
 #else
                                Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n",
                                        err, *text, 0);
@@ -134,7 +134,7 @@ int ldbm_modify_internal(
                case SLAP_MOD_SOFTADD:
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
-                                  "ldbm_modify_internal: softadd\n" ));
+                               "ldbm_modify_internal: softadd\n" ));
 #else
                        Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: softadd\n", 0, 0, 0);
 #endif
@@ -165,7 +165,7 @@ int ldbm_modify_internal(
                default:
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
-                                  "ldbm_modify_internal: invalid op %d\n", mod->sm_op ));
+                               "ldbm_modify_internal: invalid op %d\n", mod->sm_op ));
 #else
                        Debug(LDAP_DEBUG_ANY, "ldbm_modify_internal: invalid op %d\n",
                                mod->sm_op, 0, 0);
@@ -175,7 +175,7 @@ int ldbm_modify_internal(
                        *text = "Invalid modify operation";
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
-                                  "ldbm_modify_internal: %d (%s)\n", err, *text ));
+                               "ldbm_modify_internal: %d (%s)\n", err, *text ));
 #else
                        Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: %d %s\n",
                                err, *text, 0);
@@ -208,8 +208,8 @@ int ldbm_modify_internal(
                e->e_attrs = save_attrs;
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
-                          "ldbm_modify_internal: entry failed schema check: %s\n",
-                          *text ));
+                       "ldbm_modify_internal: entry failed schema check: %s\n",
+                       *text ));
 #else
                Debug( LDAP_DEBUG_ANY, "entry failed schema check: %s\n",
                        *text, 0, 0 );
@@ -261,7 +261,7 @@ ldbm_back_modify(
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
-                  "ldbm_back_modify: enter\n" ));
+               "ldbm_back_modify: enter\n" ));
 #else
        Debug(LDAP_DEBUG_ARGS, "ldbm_back_modify:\n", 0, 0, 0);
 #endif
@@ -270,25 +270,25 @@ ldbm_back_modify(
        /* acquire and lock entry */
        if ( (e = dn2entry_w( be, ndn, &matched )) == NULL ) {
                char* matched_dn = NULL;
-               struct berval **refs = NULL;
+               struct berval **refs;
 
                if ( matched != NULL ) {
                        matched_dn = ch_strdup( matched->e_dn );
                        refs = is_entry_referral( matched )
-                               ? get_entry_referrals( be, conn, op, matched )
+                               ? get_entry_referrals( be, conn, op, matched,
+                                       dn, LDAP_SCOPE_DEFAULT )
                                : NULL;
                        cache_return_entry_r( &li->li_cache, matched );
                } else {
-                       refs = default_referral;
+                       refs = referral_rewrite( default_referral,
+                               NULL, dn, LDAP_SCOPE_DEFAULT );
                }
 
                send_ldap_result( conn, op, LDAP_REFERRAL,
                        matched_dn, NULL, refs, NULL );
 
-               if ( matched != NULL ) {
-                       ber_bvecfree( refs );
-                       free( matched_dn );
-               }
+               ber_bvecfree( refs );
+               free( matched_dn );
 
                return( -1 );
        }
@@ -297,7 +297,7 @@ ldbm_back_modify(
                /* parent is a referral, don't allow add */
                /* parent is an alias, don't allow add */
                struct berval **refs = get_entry_referrals( be,
-                       conn, op, e );
+                       conn, op, e, dn, LDAP_SCOPE_DEFAULT );
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
index 0d1cd28f71f141760f5acc4bab6f34eb9f96bd37..2851f80359599135a39860f11a0e69ec8e6f55b5 100644 (file)
@@ -77,36 +77,36 @@ ldbm_back_modrdn(
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
-                  "ldbm_back_modrdn: dn: %s newSuperior=%s\n", 
-                  dn ? dn : "NULL", newSuperior ? newSuperior : "NULL" ));
+               "ldbm_back_modrdn: dn: %s newSuperior=%s\n", 
+               dn ? dn : "NULL", newSuperior ? newSuperior : "NULL" ));
 #else
        Debug( LDAP_DEBUG_TRACE, "==>ldbm_back_modrdn(newSuperior=%s)\n",
-              (newSuperior ? newSuperior : "NULL"),
-              0, 0 );
+           (newSuperior ? newSuperior : "NULL"),
+           0, 0 );
 #endif
 
        /* get entry with writer lock */
        if ( (e = dn2entry_w( be, ndn, &matched )) == NULL ) {
                char* matched_dn = NULL;
-               struct berval** refs = NULL;
+               struct berval** refs;
 
                if( matched != NULL ) {
                        matched_dn = strdup( matched->e_dn );
                        refs = is_entry_referral( matched )
-                               ? get_entry_referrals( be, conn, op, matched )
+                               ? get_entry_referrals( be, conn, op, matched,
+                                       dn, LDAP_SCOPE_DEFAULT )
                                : NULL;
                        cache_return_entry_r( &li->li_cache, matched );
                } else {
-                       refs = default_referral;
+                       refs = referral_rewrite( default_referral,
+                               NULL, dn, LDAP_SCOPE_DEFAULT );
                }
 
                send_ldap_result( conn, op, LDAP_REFERRAL,
                        matched_dn, NULL, refs, NULL );
 
-               if ( matched != NULL ) {
-                       ber_bvecfree( refs );
-                       free( matched_dn );
-               }
+               ber_bvecfree( refs );
+               free( matched_dn );
 
                return( -1 );
        }
@@ -115,13 +115,13 @@ ldbm_back_modrdn(
                /* parent is a referral, don't allow add */
                /* parent is an alias, don't allow add */
                struct berval **refs = get_entry_referrals( be,
-                       conn, op, e );
+                       conn, op, e, dn, LDAP_SCOPE_DEFAULT );
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
-                          "ldbm_back_modrdn: entry %s is a referral\n", e->e_dn ));
+                       "ldbm_back_modrdn: entry %s is a referral\n", e->e_dn ));
 #else
-               Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
+               Debug( LDAP_DEBUG_TRACE, "entry %s is referral\n", e->e_dn,
                    0, 0 );
 #endif
 
@@ -135,9 +135,9 @@ ldbm_back_modrdn(
        if ( has_children( be, e ) ) {
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
-                          "ldbm_back_modrdn: entry %s has children\n", e->e_dn ));
+                       "ldbm_back_modrdn: entry %s has children\n", e->e_dn ));
 #else
-               Debug( LDAP_DEBUG_TRACE, "entry %s referral\n", e->e_dn,
+               Debug( LDAP_DEBUG_TRACE, "entry %s has children\n", e->e_dn,
                    0, 0 );
 #endif
 
@@ -154,7 +154,7 @@ ldbm_back_modrdn(
                if( (p = dn2entry_w( be, p_ndn, NULL )) == NULL) {
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
-                                  "ldbm_back_modrdn: parent of %s does not exist\n", e->e_ndn ));
+                               "ldbm_back_modrdn: parent of %s does not exist\n", e->e_ndn ));
 #else
                        Debug( LDAP_DEBUG_TRACE, "parent does not exist\n",
                                0, 0, 0);
@@ -334,11 +334,11 @@ ldbm_back_modrdn(
                        /* parent is an alias, don't allow add */
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
-                                  "ldbm_back_modrdn: entry (%s) is a referral\n",
-                                  np->e_dn ));
+                               "ldbm_back_modrdn: entry (%s) is a referral\n",
+                               np->e_dn ));
 #else
-                       Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
-                               0, 0 );
+                       Debug( LDAP_DEBUG_TRACE, "entry (%s) is referral\n",
+                               np->e_dn, 0, 0 );
 #endif
 
                        send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
@@ -349,11 +349,11 @@ ldbm_back_modrdn(
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
-                          "ldbm_back_modrdn: wr to new parent's children OK.\n" ));
+                       "ldbm_back_modrdn: wr to new parent's children OK.\n" ));
 #else
                Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: wr to new parent's children OK\n",
-                      0, 0 , 0 );
+                   "ldbm_back_modrdn: wr to new parent's children OK\n",
+                   0, 0, 0 );
 #endif
 
                new_parent_dn = np_dn;
@@ -367,10 +367,10 @@ ldbm_back_modrdn(
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
-                  "ldbm_back_modrdn: new ndn=%s\n", new_ndn ));
+               "ldbm_back_modrdn: new ndn=%s\n", new_ndn ));
 #else
        Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: new ndn=%s\n",
-              new_ndn, 0, 0 );
+           new_ndn, 0, 0 );
 #endif
 
        /* check for abandon */
index 678393aa4691ab87560ceaee6e3af8a8831b867b..ae80f3617f129d58df96b3cfdcfe9a8b4931f8df 100644 (file)
@@ -42,65 +42,80 @@ ldbm_back_referrals(
        e = dn2entry_r( be, ndn, &matched );
        if ( e == NULL ) {
                char *matched_dn = NULL;
-               struct berval **refs = default_referral;
+               struct berval **refs = NULL;
 
                if ( matched != NULL ) {
                        matched_dn = ch_strdup( matched->e_dn );
 
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
-                                  "ldbm_back_referrals: op=%ld target=\"%s\" matched=\"%s\"\n",
-                                  op->o_tag, dn, matched_dn ));
+                               "ldbm_back_referrals: op=%ld target=\"%s\" matched=\"%s\"\n",
+                               op->o_tag, dn, matched_dn ));
 #else
                        Debug( LDAP_DEBUG_TRACE,
                                "ldbm_referrals: op=%ld target=\"%s\" matched=\"%s\"\n",
                                op->o_tag, dn, matched_dn );
 #endif
 
-
-                       refs = is_entry_referral( matched )
-                               ? get_entry_referrals( be, conn, op, matched )
-                               : NULL;
+                       if( is_entry_referral( matched ) ) {
+                               rc = LDAP_OTHER;
+                               refs = get_entry_referrals( be, conn, op, matched,
+                                       dn, LDAP_SCOPE_DEFAULT );
+                       }
 
                        cache_return_entry_r( &li->li_cache, matched );
+
+               } else if ( default_referral != NULL ) {
+                       rc = LDAP_OTHER;
+                       refs = referral_rewrite( default_referral,
+                               NULL, dn, LDAP_SCOPE_DEFAULT );
                }
 
                if( refs != NULL ) {
                        /* send referrals */
                        send_ldap_result( conn, op, rc = LDAP_REFERRAL,
                                matched_dn, NULL, refs, NULL );
-               }
-
-               if( matched != NULL ) {
                        ber_bvecfree( refs );
-                       free( matched_dn );
+
+               } else if ( rc != LDAP_SUCCESS ) {
+                       send_ldap_result( conn, op, rc, matched_dn,
+                               matched_dn ? "bad referral object" : "bad default referral",
+                               NULL, NULL );
                }
 
+               free( matched_dn );
                return rc;
        }
 
        if ( is_entry_referral( e ) ) {
                /* entry is a referral */
                struct berval **refs = get_entry_referrals( be,
-                       conn, op, e );
+                       conn, op, e, dn, LDAP_SCOPE_DEFAULT );
+               struct berval **rrefs = referral_rewrite(
+                       refs, e->e_dn, dn, LDAP_SCOPE_DEFAULT );
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
-                          "ldbm_referrals: op=%ld target=\"%s\" matched=\"%s\"\n",
-                          op->o_tag, dn, e->e_dn ));
+                       "ldbm_referrals: op=%ld target=\"%s\" matched=\"%s\"\n",
+                       op->o_tag, dn, e->e_dn ));
 #else
                Debug( LDAP_DEBUG_TRACE,
                        "ldbm_referrals: op=%ld target=\"%s\" matched=\"%s\"\n",
                        op->o_tag, dn, e->e_dn );
 #endif
 
-
-               if( refs != NULL ) {
+               if( rrefs != NULL ) {
                        send_ldap_result( conn, op, rc = LDAP_REFERRAL,
-                       e->e_dn, NULL, refs, NULL );
+                               e->e_dn, NULL, rrefs, NULL );
+
+                       ber_bvecfree( rrefs );
+
+               } else {
+                       send_ldap_result( conn, op, rc = LDAP_OTHER, e->e_dn,
+                               "bad referral object", NULL, NULL );
                }
 
-               ber_bvecfree( refs );
+               if( refs != NULL ) ber_bvecfree( refs );
        }
 
        cache_return_entry_r( &li->li_cache, e );
index 5e0d46fd738ecdb9f080845a8b30fb47b71b03bd..ef0b4ab268710ad2916fcac0eb4f88116411ef66 100644 (file)
@@ -52,6 +52,7 @@ ldbm_back_search(
        char    *realbase = NULL;
        int             nentries = 0;
        int             manageDSAit = get_manageDSAit( op );
+       int             cscope = LDAP_SCOPE_DEFAULT;
 
        struct slap_limits_set *limit = NULL;
        int isroot = 0;
@@ -95,54 +96,73 @@ ldbm_back_search(
                struct berval **refs = NULL;
 
                if ( matched != NULL ) {
+                       struct berval **erefs;
                        matched_dn = ch_strdup( matched->e_dn );
 
-                       refs = is_entry_referral( matched )
-                               ? get_entry_referrals( be, conn, op, matched )
+                       erefs = is_entry_referral( matched )
+                               ? get_entry_referrals( be, conn, op, matched,
+                                       base, scope )
                                : NULL;
 
                        cache_return_entry_r( &li->li_cache, matched );
 
+                       if( erefs ) {
+                               refs = referral_rewrite( erefs, matched_dn,
+                                       base, scope );
+
+                               ber_bvecfree( erefs );
+                       }
+
                } else {
-                       refs = default_referral;
+                       refs = referral_rewrite( default_referral,
+                               NULL, base, scope );
                }
 
                send_ldap_result( conn, op, err,
                        matched_dn, text, refs, NULL );
 
-               if( matched != NULL ) {
-                       ber_bvecfree( refs );
-                       free( matched_dn );
-               }
-
+               ber_bvecfree( refs );
+               free( matched_dn );
                return 1;
        }
 
        if (!manageDSAit && is_entry_referral( e ) ) {
                /* entry is a referral, don't allow add */
                char *matched_dn = ch_strdup( e->e_dn );
-               struct berval **refs = get_entry_referrals( be,
-                       conn, op, e );
+               struct berval **erefs = get_entry_referrals( be,
+                       conn, op, e, base, scope );
+               struct berval **refs = NULL;
 
                cache_return_entry_r( &li->li_cache, e );
 
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
-                          "ldbm_search: entry (%s) is a referral.\n",
-                          e->e_dn ));
+                       "ldbm_search: entry (%s) is a referral.\n",
+                       e->e_dn ));
 #else
                Debug( LDAP_DEBUG_TRACE,
                        "ldbm_search: entry is referral\n",
                        0, 0, 0 );
 #endif
 
+               if( erefs ) {
+                       refs = referral_rewrite( erefs, matched_dn,
+                               base, scope );
 
-               send_ldap_result( conn, op, LDAP_REFERRAL,
-                   matched_dn, NULL, refs, NULL );
+                       ber_bvecfree( erefs );
+               }
 
-               ber_bvecfree( refs );
-               free( matched_dn );
+               if( refs ) {
+                       send_ldap_result( conn, op, LDAP_REFERRAL,
+                               matched_dn, NULL, refs, NULL );
+                       ber_bvecfree( refs );
+
+               } else {
+                       send_ldap_result( conn, op, LDAP_OTHER, matched_dn,
+                               "bad referral object", NULL, NULL );
+               }
 
+               free( matched_dn );
                return 1;
        }
 
@@ -152,9 +172,12 @@ ldbm_back_search(
        }
 
        if ( scope == LDAP_SCOPE_BASE ) {
+               cscope = LDAP_SCOPE_BASE;
                candidates = base_candidate( be, e );
 
        } else {
+               cscope = ( scope != LDAP_SCOPE_SUBTREE )
+                       ? LDAP_SCOPE_BASE : LDAP_SCOPE_SUBTREE;
                candidates = search_candidates( be, e, filter,
                    scope, deref, manageDSAit );
        }
@@ -169,13 +192,12 @@ searchit:
                /* no candidates */
 #ifdef NEW_LOGGING
                LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
-                          "ldbm_search: no candidates\n" ));
+                       "ldbm_search: no candidates\n" ));
 #else
                Debug( LDAP_DEBUG_TRACE, "ldbm_search: no candidates\n",
                        0, 0, 0 );
 #endif
 
-
                send_search_result( conn, op,
                        LDAP_SUCCESS,
                        NULL, NULL, NULL, NULL, 0 );
@@ -257,7 +279,7 @@ searchit:
        for ( id = idl_firstid( candidates, &cursor ); id != NOID;
            id = idl_nextid( candidates, &cursor ) )
        {
-               int             scopeok = 0;
+               int scopeok = 0;
 
                /* check for abandon */
                ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
@@ -284,14 +306,13 @@ searchit:
                if ( e == NULL ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
-                                  "ldbm_search: candidate %ld not found.\n", id ));
+                               "ldbm_search: candidate %ld not found.\n", id ));
 #else
                        Debug( LDAP_DEBUG_TRACE,
                                "ldbm_search: candidate %ld not found\n",
                                id, 0, 0 );
 #endif
 
-
                        goto loop_continue;
                }
 
@@ -327,10 +348,10 @@ searchit:
                                /* alias is within scope */
 #ifdef NEW_LOGGING
                                LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
-                                          "ldbm_search: \"%s\" in subtree\n", e->e_dn ));
+                                       "ldbm_search: alias \"%s\" in subtree\n", e->e_dn ));
 #else
                                Debug( LDAP_DEBUG_TRACE,
-                                       "ldbm_search: \"%s\" in subtree\n",
+                                       "ldbm_search: alias \"%s\" in subtree\n",
                                        e->e_dn, 0, 0 );
 #endif
 
@@ -373,11 +394,13 @@ searchit:
                        }
 
                        if( scopeok ) {
-                               struct berval **refs = get_entry_referrals(
-                                       be, conn, op, e );
+                               struct berval **erefs = get_entry_referrals(
+                                       be, conn, op, e, NULL, cscope );
+                               struct berval **refs = referral_rewrite( erefs, e->e_dn,
+                                       NULL, scope );
 
                                send_search_reference( be, conn, op,
-                                       e, refs, scope, NULL, &v2refs );
+                                       e, refs, NULL, &v2refs );
 
                                ber_bvecfree( refs );
 
@@ -452,24 +475,23 @@ searchit:
                        } else {
 #ifdef NEW_LOGGING
                                LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL2,
-                                          "ldbm_search: candidate %ld scope not okay\n", id ));
+                                       "ldbm_search: candidate entry %ld scope not okay\n", id ));
 #else
                                Debug( LDAP_DEBUG_TRACE,
-                                       "ldbm_search: candidate %ld scope not okay\n",
+                                       "ldbm_search: candidate entry %ld scope not okay\n",
                                        id, 0, 0 );
 #endif
-
                        }
+
                } else {
 #ifdef NEW_LOGGING
                        LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL2,
-                                  "ldbm_search: candidate %ld does not match filter\n", id ));
+                               "ldbm_search: candidate entry %ld does not match filter\n", id ));
 #else
                        Debug( LDAP_DEBUG_TRACE,
-                               "ldbm_search: candidate %ld does not match filter\n",
+                               "ldbm_search: candidate entry %ld does not match filter\n",
                                id, 0, 0 );
 #endif
-
                }
 
 loop_continue:
@@ -480,6 +502,7 @@ loop_continue:
 
                ldap_pvt_thread_yield();
        }
+
        send_search_result( conn, op,
                v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
                NULL, NULL, v2refs, NULL, nentries );
index a4a10047d19c11415aff8dfcbaf32cf3a27843a0..6480cf7fb82b5fcaa375e44e08ab3e2a9737df07 100644 (file)
@@ -430,8 +430,13 @@ do_bind(
 
        if ( (be = select_backend( ndn, 0 )) == NULL ) {
                if ( default_referral ) {
+                       struct berval **ref = referral_rewrite( default_referral,
+                               NULL, dn, LDAP_SCOPE_DEFAULT );
+
                        send_ldap_result( conn, op, rc = LDAP_REFERRAL,
-                               NULL, NULL, default_referral, NULL );
+                               NULL, NULL, ref ? ref : default_referral, NULL );
+
+                       ber_bvecfree( ref );
 
                } else {
                        /* noSuchObject is not allowed to be returned by bind */
index 1823ec18bab3fb4affa914ebf042928da5ceed90..2f4f03f6aed3f49bff2dbe7188fa4c08dec2c4fa 100644 (file)
@@ -224,8 +224,13 @@ do_compare(
         * if we don't hold it.
         */
        if ( (be = select_backend( ndn, manageDSAit )) == NULL ) {
+               struct berval **ref = referral_rewrite( default_referral,
+                       NULL, dn, LDAP_SCOPE_DEFAULT );
+
                send_ldap_result( conn, op, rc = LDAP_REFERRAL,
-                       NULL, NULL, default_referral, NULL );
+                       NULL, NULL, ref ? ref : default_referral, NULL );
+
+               ber_bvecfree( ref );
                rc = 0;
                goto cleanup;
        }
index cfeb8c1bae9042b068cc727c9701affdd776cf16..e912ddfe3f568235e19865e02858aa1b3f6c4b89 100644 (file)
@@ -1487,6 +1487,19 @@ read_config( const char *fname )
                                return( 1 );
                        }
 
+                       if( validate_global_referral( cargv[1] ) ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG(( "config", LDAP_LEVEL_CRIT, "%s: line %d: "
+                                       "invalid URL (%s) in \"referral\" line.\n",
+                                       fname, lineno, cargv[1] ));
+#else
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                       "invalid URL (%s) in \"referral\" line.\n",
+                                   fname, lineno, cargv[1] );
+#endif
+                               return 1;
+                       }
+
                        vals[0]->bv_val = cargv[1];
                        vals[0]->bv_len = strlen( vals[0]->bv_val );
                        value_add( &default_referral, vals );
@@ -1772,12 +1785,12 @@ read_config( const char *fname )
                } else if ( strcasecmp( cargv[0], "updateref" ) == 0 ) {
                        if ( cargc < 2 ) {
 #ifdef NEW_LOGGING
-                               LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
-                                          "%s: line %d: missing url in \"updateref <ldapurl>\" "
-                                          "line.\n", fname, lineno ));
+                               LDAP_LOG(( "config", LDAP_LEVEL_CRIT, "%s: line %d: "
+                                       "missing url in \"updateref <ldapurl>\" line.\n",
+                                       fname, lineno ));
 #else
-                               Debug( LDAP_DEBUG_ANY,
-                   "%s: line %d: missing url in \"updateref <ldapurl>\" line\n",
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                       "missing url in \"updateref <ldapurl>\" line\n",
                                    fname, lineno, 0 );
 #endif
 
@@ -1785,32 +1798,46 @@ read_config( const char *fname )
                        }
                        if ( be == NULL ) {
 #ifdef NEW_LOGGING
-                               LDAP_LOG(( "config", LDAP_LEVEL_INFO,
-                                          "%s: line %d: updateref line must appear inside "
-                                          "a database definition (ignored)\n", fname, lineno ));
+                               LDAP_LOG(( "config", LDAP_LEVEL_INFO, "%s: line %d: "
+                                       "updateref line must appear inside a database definition "
+                                       "(ignored)\n", fname, lineno ));
 #else
-                               Debug( LDAP_DEBUG_ANY,
-"%s: line %d: updateref line must appear inside a database definition (ignored)\n",
-                                   fname, lineno, 0 );
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                       "updateref line must appear inside a database definition "
+                                       "(ignored)\n", fname, lineno, 0 );
 #endif
+                               return 1;
 
                        } else if ( be->be_update_ndn == NULL ) {
 #ifdef NEW_LOGGING
-                               LDAP_LOG(( "config", LDAP_LEVEL_INFO,
-                                          "%s: line %d: updateref line must come after updatedn "
-                                          "(ignored).\n", fname, lineno ));
+                               LDAP_LOG(( "config", LDAP_LEVEL_INFO, "%s: line %d: "
+                                       "updateref line must come after updatedn (ignored).\n",
+                                       fname, lineno ));
 #else
-                               Debug( LDAP_DEBUG_ANY,
-"%s: line %d: updateref line must after updatedn (ignored)\n",
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                       "updateref line must after updatedn (ignored)\n",
                                    fname, lineno, 0 );
 #endif
+                               return 1;
+                       }
 
-                       } else {
-                               vals[0]->bv_val = cargv[1];
-                               vals[0]->bv_len = strlen( vals[0]->bv_val );
-                               value_add( &be->be_update_refs, vals );
+                       if( validate_global_referral( cargv[1] ) ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG(( "config", LDAP_LEVEL_CRIT, "%s: line %d: "
+                                       "invalid URL (%s) in \"updateref\" line.\n",
+                                       fname, lineno, cargv[1] ));
+#else
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                       "invalid URL (%s) in \"updateref\" line.\n",
+                                   fname, lineno, cargv[1] );
+#endif
+                               return 1;
                        }
 
+                       vals[0]->bv_val = cargv[1];
+                       vals[0]->bv_len = strlen( vals[0]->bv_val );
+                       value_add( &be->be_update_refs, vals );
+
                /* replication log file to which changes are appended */
                } else if ( strcasecmp( cargv[0], "replogfile" ) == 0 ) {
                        if ( cargc < 2 ) {
index 89ca8964dc4e39d58ef30e345beb1494aed355b0..433e20855b929c0e9b52de4cbd43d20c8ba2f92a 100644 (file)
@@ -125,8 +125,13 @@ do_delete(
         * if we don't hold it.
         */
        if ( (be = select_backend( ndn, manageDSAit )) == NULL ) {
+               struct berval **ref = referral_rewrite( default_referral,
+                       NULL, dn, LDAP_SCOPE_DEFAULT );
+
                send_ldap_result( conn, op, rc = LDAP_REFERRAL,
-                       NULL, NULL, default_referral, NULL );
+                       NULL, NULL, ref ? ref : default_referral, NULL );
+
+               ber_bvecfree( ref );
                goto cleanup;
        }
 
@@ -171,8 +176,15 @@ do_delete(
                        }
 #ifndef SLAPD_MULTIMASTER
                } else {
+                       struct berval **defref = be->be_update_refs
+                               ? be->be_update_refs : default_referral;
+                       struct berval **ref = referral_rewrite( default_referral,
+                               NULL, dn, LDAP_SCOPE_DEFAULT );
+
                        send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL, NULL,
-                               be->be_update_refs ? be->be_update_refs : default_referral, NULL );
+                               ref ? ref : defref, NULL );
+
+                       ber_bvecfree( ref );
 #endif
                }
 
index 9a011b818e4eb587586cb0a9b2424bd334d93ade..5ac0a4e0d2cee26b312d4c42c1f16fbd5496a737 100644 (file)
@@ -187,12 +187,15 @@ do_extended(
                &rspoid, &rspdata, &rspctrls, &text, &refs );
 
        if( rc != SLAPD_ABANDON ) {
-               if (rc == LDAP_REFERRAL) {
-                       refs = default_referral;
+               if ( rc == LDAP_REFERRAL && refs == NULL ) {
+                       refs = referral_rewrite( default_referral,
+                               NULL, NULL, LDAP_SCOPE_DEFAULT );
                }
 
                send_ldap_extended( conn, op, rc, NULL, text, refs,
                        rspoid, rspdata, rspctrls );
+
+               ber_bvecfree( refs );
        }
 
        if ( rspoid != NULL ) {
index c3e21d1b8e9cd859ae17c083928b13f698fdd0bf..e2086b81a517f61c69390b54a6140314133e394f 100644 (file)
@@ -252,8 +252,13 @@ do_modify(
         * if we don't hold it.
         */
        if ( (be = select_backend( ndn, manageDSAit )) == NULL ) {
+               struct berval **ref = referral_rewrite( default_referral,
+                       NULL, dn, LDAP_SCOPE_DEFAULT );
+
                send_ldap_result( conn, op, rc = LDAP_REFERRAL,
-                       NULL, NULL, default_referral, NULL );
+                       NULL, NULL, ref ? ref : default_referral, NULL );
+
+               ber_bvecfree( ref );
                goto cleanup;
        }
 
@@ -337,9 +342,15 @@ do_modify(
 #ifndef SLAPD_MULTIMASTER
                /* send a referral */
                } else {
+                       struct berval **defref = be->be_update_refs
+                               ? be->be_update_refs : default_referral;
+                       struct berval **ref = referral_rewrite( defref,
+                               NULL, dn, LDAP_SCOPE_DEFAULT );
+
                        send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL, NULL,
-                               be->be_update_refs ? be->be_update_refs : default_referral,
-                               NULL );
+                               ref ? ref : defref, NULL );
+
+                       ber_bvecfree( ref );
 #endif
                }
        } else {
index 9e4422d7e74533490c135b902366666bdbf8ded0..82908716c7a95d6ebf4883652c411a0729de3867 100644 (file)
@@ -250,8 +250,13 @@ do_modrdn(
         * if we don't hold it.
         */
        if ( (be = select_backend( ndn, manageDSAit )) == NULL ) {
+               struct berval **ref = referral_rewrite( default_referral,
+                       NULL, dn, LDAP_SCOPE_DEFAULT );
+
                send_ldap_result( conn, op, rc = LDAP_REFERRAL,
-                       NULL, NULL, default_referral, NULL );
+                       NULL, NULL, ref ? ref : default_referral, NULL );
+
+               ber_bvecfree( ref );
                goto cleanup;
        }
 
@@ -321,8 +326,15 @@ do_modrdn(
                        }
 #ifndef SLAPD_MULTIMASTER
                } else {
+                       struct berval **defref = be->be_update_refs
+                               ? be->be_update_refs : default_referral;
+                       struct berval **ref = referral_rewrite( defref,
+                               NULL, dn, LDAP_SCOPE_DEFAULT );
+
                        send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL, NULL,
-                               be->be_update_refs ? be->be_update_refs : default_referral, NULL );
+                               ref ? ref : defref, NULL );
+
+                       ber_bvecfree( ref );
 #endif
                }
        } else {
index 6e0b31b0e338bc53db8e096e3662010137f67a19..c5ada769ffce7cf6e69108099b9403d8de2d19f7 100644 (file)
@@ -45,7 +45,8 @@ int passwd_extop(
 
                } else if( conn->c_authz_backend->be_update_ndn != NULL ) {
                        /* we SHOULD return a referral in this case */
-                       *refs = conn->c_authz_backend->be_update_refs;
+                       *refs = referral_rewrite( conn->c_authz_backend->be_update_refs,
+                               NULL, NULL, LDAP_SCOPE_DEFAULT );
                        rc = LDAP_REFERRAL;
 
                } else {
index fad2d895b434e8809f2a126d56624e9567ceafa6..4bf68057d6cfb89af8eea421fb74553bcfd87366 100644 (file)
@@ -503,12 +503,24 @@ LDAP_SLAPD_F (int) add_replica_suffix LDAP_P(( Backend *be, int nr, const char *
 LDAP_SLAPD_F (void) replog LDAP_P(( Backend *be, Operation *op, char *dn, void *change ));
 
 /*
- * result.c
+ * referral.c
  */
+LDAP_SLAPD_F (int) validate_global_referral LDAP_P((
+       const char *url ));
 
 LDAP_SLAPD_F (struct berval **) get_entry_referrals LDAP_P((
        Backend *be, Connection *conn, Operation *op,
-       Entry *e ));
+       Entry *e, const char *target, int scope ));
+
+LDAP_SLAPD_F (struct berval **) referral_rewrite LDAP_P((
+       struct berval **refs,
+       const char *base,
+       const char *target,
+       int scope ));
+
+/*
+ * result.c
+ */
 
 LDAP_SLAPD_F (void) send_ldap_result LDAP_P((
        Connection *conn, Operation *op,
@@ -549,7 +561,7 @@ LDAP_SLAPD_F (void) send_search_result LDAP_P((
 
 LDAP_SLAPD_F (int) send_search_reference LDAP_P((
        Backend *be, Connection *conn, Operation *op,
-       Entry *e, struct berval **refs, int scope,
+       Entry *e, struct berval **refs,
        LDAPControl **ctrls,
        struct berval ***v2refs ));
 
diff --git a/servers/slapd/referral.c b/servers/slapd/referral.c
new file mode 100644 (file)
index 0000000..178761e
--- /dev/null
@@ -0,0 +1,336 @@
+/* referral.c - muck with referrals */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2001 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/errno.h>
+#include <ac/signal.h>
+#include <ac/string.h>
+#include <ac/ctype.h>
+#include <ac/time.h>
+#include <ac/unistd.h>
+
+#include "slap.h"
+
+/*
+ * This routine generates the DN appropriate to return in
+ * an LDAP referral.
+ */
+static char * referral_dn_muck(
+       const char * refDN,
+       const char * baseDN,
+       const char * targetDN )
+{
+       char *tmp;
+       char *nrefDN = NULL;
+       char *nbaseDN = NULL;
+       char *ntargetDN = NULL;
+
+       if( !baseDN ) {
+               /* no base, return target */
+               return targetDN ? ch_strdup( targetDN ) : NULL;
+       }
+
+       if( refDN ) {
+               nrefDN = dn_validate( tmp = ch_strdup( refDN ) );
+               if( !nrefDN ) {
+                       /* Invalid refDN */
+                       ch_free( tmp );
+                       return NULL;
+               }
+       }
+
+       if( !targetDN ) {
+               /* continuation reference
+                *      if refDN present return refDN
+                *  else return baseDN
+                */
+               return nrefDN ? nrefDN : ch_strdup( baseDN );
+       }
+
+       ntargetDN = dn_validate( tmp = ch_strdup( targetDN ) );
+       if( !ntargetDN ) {
+               ch_free( tmp );
+               ch_free( nrefDN );
+               return NULL;
+       }
+
+       if( nrefDN ) {
+               nbaseDN = dn_validate( tmp = ch_strdup( baseDN ) );
+               if( !nbaseDN ) {
+                       /* Invalid baseDN */
+                       ch_free( ntargetDN );
+                       ch_free( nrefDN );
+                       ch_free( tmp );
+                       return NULL;
+               }
+
+               if( strcasecmp( nbaseDN, nrefDN ) == 0 ) {
+                       ch_free( nrefDN );
+                       ch_free( nbaseDN );
+                       return ntargetDN;
+               }
+
+               {
+                       /*
+                        * FIXME: string based mucking
+                        */
+                       char *muck;
+                       size_t reflen, baselen, targetlen, mucklen;
+
+                       reflen = strlen( nrefDN );
+                       baselen = strlen( nbaseDN );
+                       targetlen = strlen( ntargetDN );
+
+                       if( targetlen < baselen ) {
+                               ch_free( nrefDN );
+                               ch_free( nbaseDN );
+                               return ntargetDN;
+                       }
+
+                       if( strcasecmp( &ntargetDN[targetlen-baselen], nbaseDN ) ) {
+                               /* target not subordinate to base */
+                               ch_free( nrefDN );
+                               ch_free( nbaseDN );
+                               return ntargetDN;
+                       }
+
+                       mucklen = targetlen + reflen - baselen;
+                       muck = ch_malloc( 1 + mucklen );
+
+                       strncpy( muck, ntargetDN, targetlen-baselen );
+                       strcpy( &muck[targetlen-baselen], nrefDN );
+
+                       ch_free( nrefDN );
+                       ch_free( nbaseDN );
+                       ch_free( ntargetDN );
+
+                       return muck;
+               }
+       }
+
+       return ntargetDN;
+}
+
+
+/* validate URL for global referral use
+ *   LDAP URLs must not have:
+ *     DN, attrs, scope, nor filter
+ *   Any non-LDAP URL is okay
+ *
+ *   XXYYZ: should return an error string
+ */
+int validate_global_referral( const char *url )
+{
+       int rc;
+       LDAPURLDesc *lurl;
+
+       rc = ldap_url_parse_ext( url, &lurl );
+
+       switch( rc ) {
+       case LDAP_URL_SUCCESS:
+               break;
+
+       case LDAP_URL_ERR_BADSCHEME:
+               /* not LDAP hence valid */
+               return 0;
+
+       default:
+               /* other error, bail */
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+                       "referral: invalid URL (%s): %s (%d)\n",
+                       url, "" /* ldap_url_error2str(rc) */, rc ));
+#else
+               Debug( LDAP_DEBUG_ANY,
+                       "referral: invalid URL (%s): %s (%d)\n",
+                       url, "" /* ldap_url_error2str(rc) */, rc );
+#endif
+               return 1;
+       }
+
+       rc = 0;
+
+       if( lurl->lud_dn && *lurl->lud_dn ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+                       "referral: URL (%s): contains DN\n",
+                       url ));
+#else
+               Debug( LDAP_DEBUG_ANY,
+                       "referral: URL (%s): contains DN\n",
+                       url, 0, 0 );
+#endif
+               rc = 1;
+
+       } else if( lurl->lud_attrs ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+                       "referral: URL (%s): requests attributes\n",
+                       url ));
+#else
+               Debug( LDAP_DEBUG_ANY,
+                       "referral: URL (%s): requests attributes\n",
+                       url, 0, 0 );
+#endif
+               rc = 1;
+
+       } else if( lurl->lud_scope != LDAP_SCOPE_DEFAULT ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+                       "referral: URL (%s): contains explicit scope\n",
+                       url ));
+#else
+               Debug( LDAP_DEBUG_ANY,
+                       "referral: URL (%s): contains explicit scope\n",
+                       url, 0, 0 );
+#endif
+               rc = 1;
+
+       } else if( lurl->lud_filter ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
+                       "referral: URL (%s): contains explicit filter\n",
+                       url ));
+#else
+               Debug( LDAP_DEBUG_ANY,
+                       "referral: URL (%s): contains explicit filter\n",
+                       url, 0, 0 );
+#endif
+               rc = 1;
+       }
+
+       ldap_free_urldesc( lurl );
+       return rc;
+}
+
+struct berval ** referral_rewrite(
+       struct berval **in,
+       const char *base,
+       const char *target,
+       int scope )
+{
+       int i, j;
+       struct berval **refs;
+
+       if( in == NULL ) return NULL;
+
+       for( i=0; in[i] != NULL ; i++ ) {
+               /* just count them */
+       }
+
+       if( i < 1 ) return NULL;
+
+       refs = ch_malloc( (i+1) * sizeof( struct berval * ) );
+
+       for( i=0,j=0; in[i] != NULL ; i++ ) {
+               LDAPURLDesc *url;
+               int rc = ldap_url_parse_ext( in[i]->bv_val, &url );
+
+               if( rc == LDAP_URL_ERR_BADSCHEME ) {
+                       refs[j++] = ber_bvdup( in[i] );
+                       continue;
+
+               } else if( rc != LDAP_URL_SUCCESS ) {
+                       continue;
+               }
+
+               {
+                       char *dn = url->lud_dn;
+                       url->lud_dn = referral_dn_muck(
+                               ( dn && *dn ) ? dn : NULL, base, target ); 
+
+                       ldap_memfree( dn );
+               }
+
+               if( url->lud_scope == LDAP_SCOPE_DEFAULT ) {
+                       url->lud_scope = scope;
+               }
+
+               refs[j] = ch_malloc( sizeof( struct berval ) );
+
+               refs[j]->bv_val = ldap_url_desc2str( url );
+               refs[j]->bv_len = strlen( refs[j]->bv_val );
+
+               ldap_free_urldesc( url );
+               j++;
+       }
+
+       if( j == 0 ) {
+               ch_free( refs );
+               refs = NULL;
+
+       } else {
+               refs[j] = NULL;
+       }
+
+       return refs;
+}
+
+
+struct berval **get_entry_referrals(
+       Backend *be,
+       Connection *conn,
+       Operation *op,
+       Entry *e,
+       const char *dn,
+       int scope )
+{
+       Attribute *attr;
+       struct berval **refs;
+       unsigned i, j;
+
+       AttributeDescription *ad_ref = slap_schema.si_ad_ref;
+
+       attr = attr_find( e->e_attrs, ad_ref );
+
+       if( attr == NULL ) return NULL;
+
+       for( i=0; attr->a_vals[i] != NULL; i++ ) {
+               /* count references */
+       }
+
+       if( i < 1 ) return NULL;
+
+       refs = ch_malloc( (i + 1) * sizeof(struct berval *));
+
+       for( i=0, j=0; attr->a_vals[i] != NULL; i++ ) {
+               unsigned k;
+               struct berval *ref = ber_bvdup( attr->a_vals[i] );
+
+               /* trim the label */
+               for( k=0; k<ref->bv_len; k++ ) {
+                       if( isspace(ref->bv_val[k]) ) {
+                               ref->bv_val[k] = '\0';
+                               ref->bv_len = k;
+                               break;
+                       }
+               }
+
+               if(     ref->bv_len > 0 ) {
+                       refs[j++] = ref;
+
+               } else {
+                       ber_bvfree( ref );
+               }
+       }
+
+       if( j == 0 ) {
+               ber_bvecfree( refs );
+               refs = NULL;
+
+       } else {
+               refs[j] = NULL;
+       }
+
+       /* we should check that a referral value exists... */
+       return refs;
+}
+
index 0248a659aca0330a079ad52cb70ec6e898fe3625..c71972fe50a3e83212e0594eee245a580033a1e9 100644 (file)
@@ -95,87 +95,6 @@ static ber_tag_t req2res( ber_tag_t tag )
        return tag;
 }
 
-static void trim_refs_urls(
-       struct berval **refs )
-{
-       unsigned i;
-
-       if( refs == NULL ) return;
-
-       for( i=0; refs[i] != NULL; i++ ) {
-               if(     refs[i]->bv_len > sizeof("ldap://")-1 &&
-                       strncasecmp( refs[i]->bv_val, "ldap://",
-                               sizeof("ldap://")-1 ) == 0 )
-               {
-                       unsigned j;
-                       for( j=sizeof("ldap://")-1; j<refs[i]->bv_len ; j++ ) {
-                               if( refs[i]->bv_val[j] == '/' ) {
-                                       refs[i]->bv_val[j] = '\0';
-                                       refs[i]->bv_len = j;
-                                       break;
-                               }
-                       }
-               }
-       }
-}
-
-struct berval **get_entry_referrals(
-       Backend *be,
-       Connection *conn,
-       Operation *op,
-       Entry *e )
-{
-       Attribute *attr;
-       struct berval **refs;
-       unsigned i, j;
-
-       AttributeDescription *ad_ref = slap_schema.si_ad_ref;
-
-       attr = attr_find( e->e_attrs, ad_ref );
-
-       if( attr == NULL ) return NULL;
-
-       for( i=0; attr->a_vals[i] != NULL; i++ ) {
-               /* count references */
-       }
-
-       if( i < 1 ) return NULL;
-
-       refs = ch_malloc( (i + 1) * sizeof(struct berval *));
-
-       for( i=0, j=0; attr->a_vals[i] != NULL; i++ ) {
-               unsigned k;
-               struct berval *ref = ber_bvdup( attr->a_vals[i] );
-
-               /* trim the label */
-               for( k=0; k<ref->bv_len; k++ ) {
-                       if( isspace(ref->bv_val[k]) ) {
-                               ref->bv_val[k] = '\0';
-                               ref->bv_len = k;
-                               break;
-                       }
-               }
-
-               if(     ref->bv_len > 0 ) {
-                       refs[j++] = ref;
-
-               } else {
-                       ber_bvfree( ref );
-               }
-       }
-
-       refs[j] = NULL;
-
-       if( j == 0 ) {
-               ber_bvecfree( refs );
-               refs = NULL;
-       }
-
-       /* we should check that a referral value exists... */
-
-       return refs;
-}
-
 static long send_ldap_ber(
        Connection *conn,
        BerElement *ber )
@@ -503,23 +422,18 @@ send_ldap_result(
        if( ref ) {
 #ifdef NEW_LOGGING
                LDAP_LOG(( "operation", LDAP_LEVEL_ARGS,
-                          "send_ldap_result: referral=\"%s\"\n",
-                          ref[0] && ref[0]->bv_val ? ref[0]->bv_val : "NULL" ));
+                       "send_ldap_result: referral=\"%s\"\n",
+                       ref[0] && ref[0]->bv_val ? ref[0]->bv_val : "NULL" ));
 #else
                Debug( LDAP_DEBUG_ARGS,
                        "send_ldap_result: referral=\"%s\"\n",
                        ref[0] && ref[0]->bv_val ? ref[0]->bv_val : "NULL",
                        NULL, NULL );
 #endif
-
        }
 
        assert( err != LDAP_PARTIAL_RESULTS );
 
-       if( op->o_tag != LDAP_REQ_SEARCH ) {
-               trim_refs_urls( ref );
-       }
-
        if ( err == LDAP_REFERRAL ) {
                if( ref == NULL ) {
                        err = LDAP_NO_SUCH_OBJECT;
@@ -654,8 +568,6 @@ send_search_result(
 
        assert( err != LDAP_PARTIAL_RESULTS );
 
-       trim_refs_urls( refs );
-
        if( op->o_protocol < LDAP_VERSION3 ) {
                /* send references in search results */
                if( err == LDAP_REFERRAL ) {
@@ -1095,7 +1007,6 @@ send_search_reference(
     Operation  *op,
     Entry      *e,
        struct berval **refs,
-       int scope,
        LDAPControl **ctrls,
     struct berval ***v2refs
 )
@@ -1109,8 +1020,8 @@ send_search_reference(
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "operation", LDAP_LEVEL_ENTRY,
-                  "send_search_reference: conn %d  dn=\"%s\"\n",
-                  op->o_connid, e->e_dn ));
+               "send_search_reference: conn %d  dn=\"%s\"\n",
+               op->o_connid, e->e_dn ));
 #else
        Debug( LDAP_DEBUG_TRACE,
                "=> send_search_reference: dn=\"%s\"\n",
@@ -1123,8 +1034,8 @@ send_search_reference(
        {
 #ifdef NEW_LOGGING
                LDAP_LOG(( "acl", LDAP_LEVEL_INFO,
-                          "send_search_reference: conn %d      access to entry %s not allowed\n",
-                          op->o_connid, e->e_dn ));
+                       "send_search_reference: conn %d access to entry %s not allowed\n",
+                       op->o_connid, e->e_dn ));
 #else
                Debug( LDAP_DEBUG_ACL,
                        "send_search_reference: access to entry not allowed\n",
@@ -1139,8 +1050,8 @@ send_search_reference(
        {
 #ifdef NEW_LOGGING
                LDAP_LOG(( "acl", LDAP_LEVEL_INFO,
-                          "send_search_reference: conn %d access to reference not allowed.\n",
-                          op->o_connid ));
+                       "send_search_reference: conn %d access to reference not allowed.\n",
+                       op->o_connid ));
 #else
                Debug( LDAP_DEBUG_ACL,
                        "send_search_reference: access to reference not allowed\n",
@@ -1153,8 +1064,8 @@ send_search_reference(
        if( refs == NULL ) {
 #ifdef NEW_LOGGING
                LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
-                          "send_search_reference: null ref in (%s).\n",
-                          op->o_connid, e->e_dn ));
+                       "send_search_reference: null ref in (%s).\n",
+                       op->o_connid, e->e_dn ));
 #else
                Debug( LDAP_DEBUG_ANY,
                        "send_search_reference: null ref in (%s)\n", 
@@ -1177,8 +1088,8 @@ send_search_reference(
        if ( ber == NULL ) {
 #ifdef NEW_LOGGING
                LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
-                          "send_search_reference: conn %d ber_alloc failed\n",
-                          op->o_connid ));
+                       "send_search_reference: conn %d ber_alloc failed\n",
+                       op->o_connid ));
 #else
                Debug( LDAP_DEBUG_ANY,
                        "send_search_reference: ber_alloc failed\n", 0, 0, 0 );
@@ -1195,8 +1106,8 @@ send_search_reference(
        if ( rc == -1 ) {
 #ifdef NEW_LOGGING
                LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
-                          "send_search_reference: conn %d      ber_printf failed.\n",
-                          op->o_connid ));
+                       "send_search_reference: conn %d ber_printf failed.\n",
+                       op->o_connid ));
 #else
                Debug( LDAP_DEBUG_ANY,
                        "send_search_reference: ber_printf failed\n", 0, 0, 0 );
@@ -1218,16 +1129,15 @@ send_search_reference(
        ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
 
        Statslog( LDAP_DEBUG_STATS2, "conn=%ld op=%ld REF dn=\"%s\"\n",
-           (long) conn->c_connid, (long) op->o_opid, e->e_dn, 0, 0 );
+               (long) conn->c_connid, (long) op->o_opid, e->e_dn, 0, 0 );
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "operation", LDAP_LEVEL_ENTRY,
-                  "send_search_reference: conn %d exit.\n", op->o_connid ));
+               "send_search_reference: conn %d exit.\n", op->o_connid ));
 #else
        Debug( LDAP_DEBUG_TRACE, "<= send_search_reference\n", 0, 0, 0 );
 #endif
 
-
        return 0;
 }
 
index 63379e60b6a5d1c97ecc97773712fc02c779960f..086e924137d72af0b60ef1a82b200d7ec3919a21 100644 (file)
@@ -268,9 +268,13 @@ do_search(
         * if we don't hold it.
         */
        if ( (be = select_backend( nbase, manageDSAit )) == NULL ) {
+               struct berval **ref = referral_rewrite( default_referral,
+                       NULL, base, scope );
+
                send_ldap_result( conn, op, rc = LDAP_REFERRAL,
-                       NULL, NULL, default_referral, NULL );
+                       NULL, NULL, ref ? ref : default_referral, NULL );
 
+               ber_bvecfree( ref );
                goto return_results;
        }
 
index 3231855856cc5a2efb32592d939af04a45e138e1..4cf42801d89e54103afbcd334e81597ff3b8961e 100644 (file)
@@ -47,7 +47,8 @@ SLAPD_OBJS = ../config.o ../ch_malloc.o ../backend.o ../charray.o \
                ../acl.o ../phonetic.o ../attr.o ../value.o ../entry.o \
                ../dn.o ../filter.o ../str2filter.o ../ava.o ../init.o \
                ../controls.o ../kerberos.o ../passwd.o ../index.o \
-               ../extended.o ../starttls.o ../sets.o ../mra.o
+               ../extended.o ../starttls.o ../sets.o ../mra.o \
+               ../referral.o
 
 SLAPOBJS = $(SLAPD_OBJS) slapcommon.o mimic.o
 
index 6783a55402d4c7f904ed2bd4e371c6e72a4f8add..b5dc9e24aa0a331d31da1053f4ace0b0a6d8a72e 100644 (file)
@@ -123,7 +123,6 @@ int send_search_reference(
        Operation   *op,
        Entry   *e,
        struct berval **refs,
-       int scope,
        LDAPControl **ctrls,
        struct berval ***v2refs
 )
@@ -132,13 +131,6 @@ int send_search_reference(
        return -1;
 }
 
-struct berval **get_entry_referrals(
-       Backend *be, Connection *conn, Operation *op, Entry *e )
-{
-       assert(0);
-       return NULL;
-}
-
 int slap_sasl_init(void)
 {
        return LDAP_SUCCESS;
index 9c4101c85ec754c9cc9e8eada9b6ec2fc0f5302d..925464dacfc72fb9bfd237a8e86c8b41c3dcefb5 100644 (file)
@@ -24,7 +24,7 @@ directory     ./test-repl
 rootdn         "cn=Replica, o=University of Michigan, c=US"
 rootpw         secret
 updatedn       "cn=Replica, o=University of Michigan, c=US"
-updateref      "ldap://localhost:9009/o=University%20of%20Michigan,c=US"
+updateref      "ldap://localhost:9009"
 #ldbm#index            objectClass     eq
 #ldbm#index            cn,sn,uid       pres,eq,sub
 #bdb#index             objectClass     eq