3 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
10 #include <ac/string.h>
11 #include <ac/socket.h>
13 #include "back-ldbm.h"
14 #include "proto-back-ldbm.h"
17 static char* get_alias_dn(
22 static char* new_superior(
27 static int dnlist_subordinate(
31 Entry *deref_internal_r(
39 struct ldbminfo *li = (struct ldbminfo *) be->be_private;
45 assert( ( alias != NULL && dn == NULL ) || ( alias == NULL && dn != NULL ) );
53 entry = dn2entry_r( be, dn, &sup );
56 dn = ch_strdup( alias->e_ndn );
62 charray_add( &dnlist, dn );
64 for( depth=0 ; ; depth++ ) {
69 /* have entry, may be an alias */
71 if( !is_entry_alias( entry ) ) {
72 /* entry is not an alias */
77 if( depth > be->be_max_deref_depth ) {
80 *err = LDAP_ALIAS_DEREF_PROBLEM;
81 *text = "maximum deref depth exceeded";
86 aliasDN = get_alias_dn( entry, err, text );
88 if( aliasDN == NULL ) {
94 /* check if aliasDN is a subordinate of any DN in our list */
95 if( dnlist_subordinate( dnlist, aliasDN ) ) {
98 *err = LDAP_ALIAS_PROBLEM;
99 *text = "circular alias";
103 /* attempt to dereference alias */
105 newe = dn2entry_r( be, aliasDN, &sup );
109 cache_return_entry_r(&li->li_cache, entry );
111 dn = ch_strdup( entry->e_ndn );
112 charray_add( &dnlist, dn );
118 cache_return_entry_r(&li->li_cache, entry );
123 /* no newe and no superior, we're done */
126 } else if( sup != NULL ) {
127 /* have superior, may be an alias */
133 if( !is_entry_alias( sup ) ) {
134 /* entry is not an alias */
141 if( depth > be->be_max_deref_depth ) {
144 *err = LDAP_ALIAS_DEREF_PROBLEM;
145 *text = "maximum deref depth exceeded";
150 supDN = get_alias_dn( sup, err, text );
152 if( supDN == NULL ) {
157 aliasDN = new_superior( dn, sup->e_ndn, supDN );
159 if( aliasDN == NULL ) {
162 *err = LDAP_ALIAS_PROBLEM;
163 *text = "superior alias problem";
167 /* check if aliasDN is a subordinate of any DN in our list */
168 if( dnlist_subordinate( dnlist, aliasDN ) ) {
172 *err = LDAP_ALIAS_PROBLEM;
173 *text = "subordinate circular alias";
177 /* attempt to dereference alias */
178 newe = dn2entry_r( be, aliasDN, &newSup );
183 cache_return_entry_r(&li->li_cache, sup );
185 dn = ch_strdup( entry->e_ndn );
186 charray_add( &dnlist, dn );
191 if ( newSup != NULL ) {
193 cache_return_entry_r(&li->li_cache, sup );
202 /* no newe and no superior, we're done */
208 charray_free( dnlist );
213 static char* get_alias_dn(
219 #ifdef SLAPD_SCHEMA_NOT_COMPAT
220 static AttributeDescription *aliasedObjectName = NULL;
222 static const char *aliasedObjectName = NULL;
225 a = attr_find( e->e_attrs, aliasedObjectName );
229 * there was an aliasedobjectname defined but no data.
231 *err = LDAP_ALIAS_PROBLEM;
232 *errmsg = "alias missing aliasedObjectName attribute";
237 * aliasedObjectName should be SINGLE-VALUED with a single value.
239 if ( a->a_vals[0] == NULL || a->a_vals[0]->bv_val == NULL ) {
241 * there was an aliasedobjectname defined but no data.
243 *err = LDAP_ALIAS_PROBLEM;
244 *errmsg = "alias missing aliasedObjectName value";
248 if( a->a_vals[1] != NULL ) {
249 *err = LDAP_ALIAS_PROBLEM;
250 *errmsg = "alias has multivalued aliasedObjectName";
254 return a->a_vals[0]->bv_val;
263 size_t dnlen, olen, nlen;
264 assert( dn && oldSup && newSup );
266 dnlen = strlen( dn );
267 olen = strlen( oldSup );
268 nlen = strlen( newSup );
270 newDN = ch_malloc( dnlen - olen + nlen + 1 );
272 memcpy( newDN, dn, dnlen - olen );
273 memcpy( &newDN[dnlen - olen], newSup, nlen );
274 newDN[dnlen - olen + nlen] = '\0';
279 static int dnlist_subordinate(
286 for( i = 0; dnlist[i] != NULL; i++ ) {
287 if( dn_issuffix( dnlist[i], dn ) ) {