#include "portable.h"
+#ifdef SLAPD_ALIAS_DEREF
+
#include <stdio.h>
#include <string.h>
#include <ac/socket.h> /* Get struct sockaddr for slap.h */
Debug( LDAP_DEBUG_TRACE, "<= %s is an alias for %s\n",
e->e_dn, a->a_vals[0]->bv_val, 0 );
- newDN = strdup (a->a_vals[0]->bv_val);
- oldDN = strdup (e->e_dn);
+ newDN = ch_strdup (a->a_vals[0]->bv_val);
+ oldDN = ch_strdup (e->e_dn);
/*
* ok, so what happens if there is an alias in the DN of a dereferenced
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
- char *matched;
- char *newDN;
- int depth;
+ char *matched = 0;
+ char *newDN = NULL;
+ int depth, i;
Entry *eMatched;
Entry *eDeref;
Entry *eNew;
Debug( LDAP_DEBUG_TRACE,
- "<= dereferencing dn %s\n",
+ "<= dereferencing dn: \"%s\"\n",
dn, 0, 0 );
- newDN = strdup ( dn );
-
+ newDN = ch_strdup ( dn );
+
/* while we don't have a matched dn, deref the DN */
for ( depth = 0;
( (eMatched = dn2entry_r( be, newDN, &matched )) == NULL) &&
(depth < be->be_maxDerefDepth);
++depth ) {
- /* free reader lock */
- cache_return_entry_r(&li->li_cache, eMatched);
-
- if (*matched) {
+ if ((matched != NULL) && *matched) {
char *submatch;
/*
if ((eNew = derefAlias_r( be, conn, op, eMatched )) == NULL) {
free (matched);
+ matched = NULL;
free (newDN);
+ newDN = NULL;
free (remainder);
+ remainder = NULL;
break; /* no associated entry, dont deref */
}
else {
Debug( LDAP_DEBUG_TRACE, "<= l&g we have %s vs %s \n", matched, eNew->e_dn, 0 );
- if (!strcasecmp (matched, eNew->e_dn)) {
+ i = strcasecmp (matched, eNew->e_dn);
+ /* free reader lock */
+ cache_return_entry_r(&li->li_cache, eNew);
+ if (! i) {
/* newDN same as old so not an alias, no need to go further */
free (newDN);
+ newDN = NULL;
free (matched);
+ matched = NULL;
free (remainder);
break;
}
* the new dn together
*/
free (newDN);
- free (matched);
-
newDN = ch_malloc (strlen(eMatched->e_dn) + rlen + 1);
strcpy (newDN, remainder);
strcat (newDN, eMatched->e_dn);
Debug( LDAP_DEBUG_TRACE, "<= expanded to %s\n", newDN, 0, 0 );
+ free (matched);
+ matched = NULL;
free (remainder);
-
- /* free reader lock */
- cache_return_entry_r(&li->li_cache, eNew);
}
/* free reader lock */
cache_return_entry_r(&li->li_cache, eMatched);
}
}
+ if(eMatched != NULL) {
+ /* free reader lock */
+ cache_return_entry_r(&li->li_cache, eMatched);
+ }
+
/*
* the final part of the DN might be an alias
* so try to dereference it.
if ( (eNew = dn2entry_r( be, newDN, &matched )) != NULL) {
if ((eDeref = derefAlias_r( be, conn, op, eNew )) != NULL) {
free (newDN);
- newDN = strdup (eDeref->e_dn);
+ newDN = ch_strdup (eDeref->e_dn);
/* free reader lock */
cache_return_entry_r(&li->li_cache, eDeref);
}
*/
if (depth >= be->be_maxDerefDepth) {
Debug( LDAP_DEBUG_TRACE,
- "<= max deref depth exceeded in derefDN for %s, result %s\n",
+ "<= max deref depth exceeded in derefDN for \"%s\", result \"%s\"\n",
dn, newDN, 0 );
send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM, "",
"Maximum alias dereference depth exceeded for base" );
}
-
- Debug( LDAP_DEBUG_TRACE, "<= returning deref DN of %s\n", newDN, 0, 0 );
- free(matched);
+ if (newDN == NULL) {
+ newDN = ch_strdup ( dn );
+ }
+
+ Debug( LDAP_DEBUG_TRACE, "<= returning deref DN of \"%s\"\n", newDN, 0, 0 );
+ if (matched != NULL) free(matched);
return newDN;
}
+
+#endif /* SLAPD_ALIAS_DEREF */