mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-22 07:39:35 -05:00
First stable an implementing latest namedref specification.
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.
This commit is contained in:
parent
f3f72c5d2a
commit
82fad7d0c8
25 changed files with 678 additions and 301 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ ldbm_back_add(
|
|||
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);
|
||||
|
||||
|
|
@ -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,13 +97,14 @@ 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
|
||||
|
|
@ -116,15 +116,12 @@ ldbm_back_add(
|
|||
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 );
|
||||
}
|
||||
|
||||
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 );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -41,11 +41,10 @@ ldbm_back_delete(
|
|||
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,
|
||||
|
|
@ -55,24 +54,24 @@ ldbm_back_delete(
|
|||
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 );
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -88,25 +88,25 @@ ldbm_back_modrdn(
|
|||
/* 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 );
|
||||
}
|
||||
|
||||
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 ));
|
||||
#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
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ ldbm_back_modrdn(
|
|||
LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
|
||||
"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
|
||||
|
||||
|
|
@ -337,8 +337,8 @@ ldbm_back_modrdn(
|
|||
"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,
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ 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 );
|
||||
|
|
@ -57,32 +57,42 @@ ldbm_back_referrals(
|
|||
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,
|
||||
|
|
@ -94,13 +104,18 @@ ldbm_back_referrals(
|
|||
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 );
|
||||
|
|
|
|||
|
|
@ -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,34 +96,42 @@ 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 );
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
|
|
@ -136,13 +145,24 @@ ldbm_back_search(
|
|||
0, 0, 0 );
|
||||
#endif
|
||||
|
||||
if( erefs ) {
|
||||
refs = referral_rewrite( erefs, matched_dn,
|
||||
base, scope );
|
||||
|
||||
ber_bvecfree( erefs );
|
||||
}
|
||||
|
||||
if( refs ) {
|
||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
||||
matched_dn, NULL, refs, NULL );
|
||||
|
||||
ber_bvecfree( refs );
|
||||
free( matched_dn );
|
||||
|
||||
} 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 );
|
||||
}
|
||||
|
|
@ -175,7 +198,6 @@ searchit:
|
|||
0, 0, 0 );
|
||||
#endif
|
||||
|
||||
|
||||
send_search_result( conn, op,
|
||||
LDAP_SUCCESS,
|
||||
NULL, NULL, NULL, NULL, 0 );
|
||||
|
|
@ -291,7 +313,6 @@ searchit:
|
|||
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 );
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,31 +1798,45 @@ 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
} else {
|
||||
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 ) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 ));
|
||||
|
||||
|
|
|
|||
336
servers/slapd/referral.c
Normal file
336
servers/slapd/referral.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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 )
|
||||
|
|
@ -511,15 +430,10 @@ send_ldap_result(
|
|||
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
|
||||
)
|
||||
|
|
@ -1227,7 +1138,6 @@ send_search_reference(
|
|||
Debug( LDAP_DEBUG_TRACE, "<= send_search_reference\n", 0, 0, 0 );
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -268,9 +268,13 @@ do_search(
|
|||
* if we don't hold it.
|
||||
*/
|
||||
if ( (be = select_backend( nbase, manageDSAit )) == NULL ) {
|
||||
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
|
||||
NULL, NULL, default_referral, NULL );
|
||||
struct berval **ref = referral_rewrite( default_referral,
|
||||
NULL, base, scope );
|
||||
|
||||
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
|
||||
NULL, NULL, ref ? ref : default_referral, NULL );
|
||||
|
||||
ber_bvecfree( ref );
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue