3 * Copyright 1998-2003 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 void new_superior(
19 struct berval *oldSup,
20 struct berval *newSup,
23 static int dnlist_subordinate(
27 Entry *deref_internal_r(
36 struct ldbminfo *li = (struct ldbminfo *) be->be_private;
42 assert( ( alias != NULL && dn_in == NULL )
43 || ( alias == NULL && dn_in != NULL ) );
46 *err = LDAP_NO_SUCH_OBJECT;
50 ber_dupbv( &dn, dn_in );
51 entry = dn2entry_r( be, &dn, &sup );
54 ber_dupbv( &dn, &alias->e_nname );
60 ber_bvarray_add( &dnlist, &dn );
62 for( depth=0 ; ; depth++ ) {
65 struct berval aliasDN;
67 /* have entry, may be an alias */
69 if( !is_entry_alias( entry ) ) {
70 /* entry is not an alias */
75 if( depth > be->be_max_deref_depth ) {
78 *err = LDAP_ALIAS_DEREF_PROBLEM;
79 *text = "maximum deref depth exceeded";
84 if( get_alias_dn( entry, &aliasDN, err, text )) {
90 /* check if aliasDN is a subordinate of any DN in our list */
91 if( dnlist_subordinate( dnlist, &aliasDN ) ) {
92 ch_free( aliasDN.bv_val );
95 *err = LDAP_ALIAS_PROBLEM;
96 *text = "circular alias";
100 /* attempt to dereference alias */
102 newe = dn2entry_r( be, &aliasDN, &sup );
103 ch_free( aliasDN.bv_val );
106 cache_return_entry_r(&li->li_cache, entry );
108 ber_dupbv( &dn, &entry->e_nname );
109 ber_bvarray_add( &dnlist, &dn );
114 cache_return_entry_r(&li->li_cache, entry );
119 /* no newe and no superior, we're done */
122 } else if( sup != NULL ) {
123 /* have superior, may be an alias */
127 struct berval aliasDN;
129 if( !is_entry_alias( sup ) ) {
130 /* entry is not an alias */
137 if( depth > be->be_max_deref_depth ) {
140 *err = LDAP_ALIAS_DEREF_PROBLEM;
141 *text = "maximum deref depth exceeded";
146 if( get_alias_dn( sup, &supDN, err, text )) {
151 new_superior( &dn, &sup->e_nname, &supDN, &aliasDN );
154 /* check if aliasDN is a subordinate of any DN in our list */
155 if( dnlist_subordinate( dnlist, &aliasDN ) ) {
156 free(aliasDN.bv_val);
159 *err = LDAP_ALIAS_PROBLEM;
160 *text = "subordinate circular alias";
164 /* attempt to dereference alias */
165 newe = dn2entry_r( be, &aliasDN, &newSup );
168 free(aliasDN.bv_val);
169 cache_return_entry_r(&li->li_cache, sup );
171 ber_dupbv( &dn, &entry->e_nname );
172 ber_bvarray_add( &dnlist, &dn );
176 if ( newSup != NULL ) {
177 cache_return_entry_r(&li->li_cache, sup );
179 ber_dupbv( &dn, &aliasDN );
186 /* no newe and no superior, we're done */
191 ber_bvarray_free( dnlist );
196 static void new_superior(
198 struct berval *oldSup,
199 struct berval *newSup,
200 struct berval *newDN )
202 size_t dnlen, olen, nlen;
203 assert( dn && oldSup && newSup && newDN );
206 olen = oldSup->bv_len;
207 nlen = newSup->bv_len;
209 newDN->bv_val = ch_malloc( dnlen - olen + nlen + 1 );
211 AC_MEMCPY( newDN->bv_val, dn->bv_val, dnlen - olen );
212 AC_MEMCPY( &newDN->bv_val[dnlen - olen], newSup->bv_val, nlen );
213 newDN->bv_val[dnlen - olen + nlen] = '\0';
218 static int dnlist_subordinate(
224 for( ; dnlist->bv_val != NULL; dnlist++ ) {
225 if( dnIsSuffix( dnlist, dn ) ) {