1 /* referral.c - muck with referrals */
4 * Copyright 1998-2001 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
12 #include <ac/socket.h>
14 #include <ac/signal.h>
15 #include <ac/string.h>
18 #include <ac/unistd.h>
23 * This routine generates the DN appropriate to return in
26 static char * referral_dn_muck(
29 const char * targetDN )
34 char *ntargetDN = NULL;
37 /* no base, return target */
38 return targetDN ? ch_strdup( targetDN ) : NULL;
42 nrefDN = dn_validate( tmp = ch_strdup( refDN ) );
51 /* continuation reference
52 * if refDN present return refDN
55 return nrefDN ? nrefDN : ch_strdup( baseDN );
58 ntargetDN = dn_validate( tmp = ch_strdup( targetDN ) );
66 nbaseDN = dn_validate( tmp = ch_strdup( baseDN ) );
75 if( strcasecmp( nbaseDN, nrefDN ) == 0 ) {
83 * FIXME: string based mucking
86 size_t reflen, baselen, targetlen, mucklen;
88 reflen = strlen( nrefDN );
89 baselen = strlen( nbaseDN );
90 targetlen = strlen( ntargetDN );
92 if( targetlen < baselen ) {
98 if( strcasecmp( &ntargetDN[targetlen-baselen], nbaseDN ) ) {
99 /* target not subordinate to base */
105 mucklen = targetlen + reflen - baselen;
106 muck = ch_malloc( 1 + mucklen );
108 strncpy( muck, ntargetDN, targetlen-baselen );
109 strcpy( &muck[targetlen-baselen], nrefDN );
113 ch_free( ntargetDN );
123 /* validate URL for global referral use
124 * LDAP URLs must not have:
125 * DN, attrs, scope, nor filter
126 * Any non-LDAP URL is okay
128 * XXYYZ: should return an error string
130 int validate_global_referral( const char *url )
135 rc = ldap_url_parse_ext( url, &lurl );
138 case LDAP_URL_SUCCESS:
141 case LDAP_URL_ERR_BADSCHEME:
142 /* not LDAP hence valid */
146 /* other error, bail */
148 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
149 "referral: invalid URL (%s): %s (%d)\n",
150 url, "" /* ldap_url_error2str(rc) */, rc ));
152 Debug( LDAP_DEBUG_ANY,
153 "referral: invalid URL (%s): %s (%d)\n",
154 url, "" /* ldap_url_error2str(rc) */, rc );
161 if( lurl->lud_dn && *lurl->lud_dn ) {
163 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
164 "referral: URL (%s): contains DN\n",
167 Debug( LDAP_DEBUG_ANY,
168 "referral: URL (%s): contains DN\n",
173 } else if( lurl->lud_attrs ) {
175 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
176 "referral: URL (%s): requests attributes\n",
179 Debug( LDAP_DEBUG_ANY,
180 "referral: URL (%s): requests attributes\n",
185 } else if( lurl->lud_scope != LDAP_SCOPE_DEFAULT ) {
187 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
188 "referral: URL (%s): contains explicit scope\n",
191 Debug( LDAP_DEBUG_ANY,
192 "referral: URL (%s): contains explicit scope\n",
197 } else if( lurl->lud_filter ) {
199 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
200 "referral: URL (%s): contains explicit filter\n",
203 Debug( LDAP_DEBUG_ANY,
204 "referral: URL (%s): contains explicit filter\n",
210 ldap_free_urldesc( lurl );
214 struct berval ** referral_rewrite(
221 struct berval **refs;
223 if( in == NULL ) return NULL;
225 for( i=0; in[i] != NULL ; i++ ) {
226 /* just count them */
229 if( i < 1 ) return NULL;
231 refs = ch_malloc( (i+1) * sizeof( struct berval * ) );
233 for( i=0,j=0; in[i] != NULL ; i++ ) {
235 int rc = ldap_url_parse_ext( in[i]->bv_val, &url );
237 if( rc == LDAP_URL_ERR_BADSCHEME ) {
238 refs[j++] = ber_bvdup( in[i] );
241 } else if( rc != LDAP_URL_SUCCESS ) {
246 char *dn = url->lud_dn;
247 url->lud_dn = referral_dn_muck(
248 ( dn && *dn ) ? dn : NULL, base, target );
253 if( url->lud_scope == LDAP_SCOPE_DEFAULT ) {
254 url->lud_scope = scope;
257 refs[j] = ch_malloc( sizeof( struct berval ) );
259 refs[j]->bv_val = ldap_url_desc2str( url );
260 refs[j]->bv_len = strlen( refs[j]->bv_val );
262 ldap_free_urldesc( url );
278 struct berval **get_entry_referrals(
287 struct berval **refs;
290 AttributeDescription *ad_ref = slap_schema.si_ad_ref;
292 attr = attr_find( e->e_attrs, ad_ref );
294 if( attr == NULL ) return NULL;
296 for( i=0; attr->a_vals[i] != NULL; i++ ) {
297 /* count references */
300 if( i < 1 ) return NULL;
302 refs = ch_malloc( (i + 1) * sizeof(struct berval *));
304 for( i=0, j=0; attr->a_vals[i] != NULL; i++ ) {
306 struct berval *ref = ber_bvdup( attr->a_vals[i] );
309 for( k=0; k<ref->bv_len; k++ ) {
310 if( isspace(ref->bv_val[k]) ) {
311 ref->bv_val[k] = '\0';
317 if( ref->bv_len > 0 ) {
326 ber_bvecfree( refs );
333 /* we should check that a referral value exists... */