2 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
10 #include <ac/socket.h>
12 #include "back-ldbm.h"
13 #include "proto-back-ldbm.h"
16 static char* get_alias_dn(
21 static char* new_superior(
26 static int dnlist_subordinate(
30 Entry *deref_internal_r(
38 struct ldbminfo *li = (struct ldbminfo *) be->be_private;
44 assert( ( alias != NULL && dn == NULL ) || ( alias == NULL && dn != NULL ) );
52 entry = dn2entry_r( be, dn, &sup );
55 dn = ch_strdup( alias->e_ndn );
61 charray_add( &dnlist, dn );
63 for( depth=0 ; ; depth++ ) {
68 /* have entry, may be an alias */
70 if( !is_entry_alias( entry ) ) {
71 /* entry is not an alias */
76 if( depth > be->be_max_deref_depth ) {
79 *err = LDAP_ALIAS_DEREF_PROBLEM;
80 *text = "maximum deref depth exceeded";
85 aliasDN = get_alias_dn( entry, err, text );
87 if( aliasDN == NULL ) {
93 /* check if aliasDN is a subordinate of any DN in our list */
94 if( dnlist_subordinate( dnlist, aliasDN ) ) {
97 *err = LDAP_ALIAS_PROBLEM;
98 *text = "circular alias";
102 /* attempt to dereference alias */
104 newe = dn2entry_r( be, aliasDN, &sup );
108 cache_return_entry_r(&li->li_cache, entry );
110 dn = ch_strdup( entry->e_ndn );
111 charray_add( &dnlist, dn );
117 cache_return_entry_r(&li->li_cache, entry );
122 /* no newe and no superior, we're done */
125 } else if( sup != NULL ) {
126 /* have superior, may be an alias */
132 if( !is_entry_alias( sup ) ) {
133 /* entry is not an alias */
140 if( depth > be->be_max_deref_depth ) {
143 *err = LDAP_ALIAS_DEREF_PROBLEM;
144 *text = "maximum deref depth exceeded";
149 supDN = get_alias_dn( sup, err, text );
151 if( supDN == NULL ) {
156 aliasDN = new_superior( dn, sup->e_ndn, supDN );
158 if( aliasDN == NULL ) {
161 *err = LDAP_ALIAS_PROBLEM;
162 *text = "superior alias problem";
166 /* check if aliasDN is a subordinate of any DN in our list */
167 if( dnlist_subordinate( dnlist, aliasDN ) ) {
171 *err = LDAP_ALIAS_PROBLEM;
172 *text = "subordinate circular alias";
176 /* attempt to dereference alias */
177 newe = dn2entry_r( be, aliasDN, &newSup );
182 cache_return_entry_r(&li->li_cache, sup );
184 dn = ch_strdup( entry->e_ndn );
185 charray_add( &dnlist, dn );
190 if ( newSup != NULL ) {
192 cache_return_entry_r(&li->li_cache, sup );
201 /* no newe and no superior, we're done */
211 static char* get_alias_dn(
216 Attribute *a = attr_find( e->e_attrs, "aliasedobjectname" );
220 * there was an aliasedobjectname defined but no data.
222 *err = LDAP_ALIAS_PROBLEM;
223 *errmsg = "alias missing aliasedObjectName attribute";
228 * aliasedObjectName should be SINGLE-VALUED with a single value.
230 if ( a->a_vals[0] == NULL || a->a_vals[0]->bv_val == NULL ) {
232 * there was an aliasedobjectname defined but no data.
234 *err = LDAP_ALIAS_PROBLEM;
235 *errmsg = "alias missing aliasedObjectName value";
239 if( a->a_vals[1] != NULL ) {
240 *err = LDAP_ALIAS_PROBLEM;
241 *errmsg = "alias has multivalued aliasedObjectName";
245 return a->a_vals[0]->bv_val;
254 size_t dnlen, olen, nlen;
255 assert( dn && oldSup && newSup );
257 dnlen = strlen( dn );
258 olen = strlen( oldSup );
259 nlen = strlen( newSup );
261 newDN = ch_malloc( dnlen - olen + nlen + 1 );
263 memcpy( newDN, dn, dnlen - olen );
264 memcpy( &newDN[dnlen - olen], newSup, nlen );
265 newDN[dnlen - olen + nlen] = '\0';
270 static int dnlist_subordinate(
277 for( i = 0; dnlist[i] != NULL; i++ ) {
278 if( dn_issuffix( dnlist[i], dn ) ) {