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)
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)
*/
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;
}
#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 {
return LDAP_SUCCESS;
}
-
#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);
#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 );
/* 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);
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;
/* 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 */
0 );
#endif
-
send_ldap_result( conn, op,
rc > 0 ? LDAP_ALREADY_EXISTS : LDAP_OTHER,
NULL, rc > 0 ? NULL : "cache add failed", NULL, NULL );
#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
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 */
NULL, NULL, NULL, NULL );
}
- if ( matched != NULL ) {
- ber_bvecfree( refs );
- free( matched_dn );
- }
+ ber_bvecfree( refs );
+ free( matched_dn );
return( rc );
}
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,
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 );
}
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,
#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 );
}
/* 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,
#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
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
*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);
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
*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);
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
*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);
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
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);
*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);
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 );
#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
/* 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 );
}
/* 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,
#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 );
}
/* 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
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
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);
/* 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,
#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;
#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 */
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 );
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;
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;
}
}
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 );
}
/* 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 );
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 );
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;
}
/* 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
}
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 );
} 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:
ldap_pvt_thread_yield();
}
+
send_search_result( conn, op,
v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
NULL, NULL, v2refs, NULL, nentries );
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 */
* 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;
}
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 );
} 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
}
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 ) {
* 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;
}
}
#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
}
&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 ) {
* 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;
}
#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 {
* 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;
}
}
#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 {
} 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 {
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,
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 ));
--- /dev/null
+/* 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;
+}
+
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 )
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;
assert( err != LDAP_PARTIAL_RESULTS );
- trim_refs_urls( refs );
-
if( op->o_protocol < LDAP_VERSION3 ) {
/* send references in search results */
if( err == LDAP_REFERRAL ) {
Operation *op,
Entry *e,
struct berval **refs,
- int scope,
LDAPControl **ctrls,
struct berval ***v2refs
)
#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",
{
#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",
{
#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",
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",
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 );
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 );
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;
}
* 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;
}
../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
Operation *op,
Entry *e,
struct berval **refs,
- int scope,
LDAPControl **ctrls,
struct berval ***v2refs
)
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;
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