Skip to content
Snippets Groups Projects
Commit 6772a6e1 authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

new files for general aliasing

parent bf6c1e0a
No related branches found
No related tags found
No related merge requests found
/*
* Copyright (c) 1998 Will Ballantyne, ITSD, Government of BC
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to ITSD, Government of BC. The name of ITSD
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
#include <stdio.h>
#include <string.h>
#include "slap.h"
#include "back-ldbm.h"
extern Attribute *attr_find();
/*
* given an alias object, dereference it to its end point.
*/
Entry *derefAlias ( Backend *be,
Connection *conn,
Operation *op,
Entry *e
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
Attribute *a;
ID id;
int depth;
char **pastAliases;
Debug( LDAP_DEBUG_TRACE,
"<= checking for alias for dn %s\n", e->e_dn, 0, 0 );
/*
* try to deref fully, up to a maximum depth. If the max depth exceeded
* then send an error
*/
for ( depth = 0;
( ( a = attr_find( e->e_attrs, "aliasedobjectname" ) ) != NULL) &&
( depth < be->be_maxDerefDepth );
++depth) {
/*
* make sure there is a defined aliasedobjectname.
* can only have one value so just use first value (0) in the attr list.
*/
if (a->a_vals[0] && a->a_vals[0]->bv_val) {
char *newDN, *oldDN;
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);
/* free reader lock */
cache_return_entry_r( &li->li_cache, e );
e = NULL;
/*
* ok, so what happens if there is an alias in the DN of a dereferenced
* alias object?
*/
if ( (id = dn2id( be, newDN )) == NOID ||
(e = id2entry_r( be, id )) == NULL ) {
/* could not deref return error */
Debug( LDAP_DEBUG_TRACE,
"<= %s is a dangling alias to %s\n",
oldDN, newDN, 0 );
send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM, "",
"Dangling Alias" );
}
free (newDN);
free (oldDN);
}
else {
/*
* there was an aliasedobjectname defined but no data.
* this can't happen, right?
*/
Debug( LDAP_DEBUG_TRACE,
"<= %s has no data in aliasedobjectname attribute\n",
e->e_dn, 0, 0 );
send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM, "",
"Alias missing aliasedobjectname" );
}
}
/*
* warn if we pulled out due to exceeding the maximum deref depth
*/
if ( depth >= be->be_maxDerefDepth ) {
Debug( LDAP_DEBUG_TRACE,
"<= %s exceeded maximum deref depth %d\n",
e->e_dn, be->be_maxDerefDepth, 0 );
send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM, "",
"Maximum alias dereference depth exceeded" );
}
return e;
}
/*
* given a DN fully deref it and return the real DN or original DN if it fails
*/
char *derefDN ( Backend *be,
Connection *conn,
Operation *op,
char *dn
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
char *matched;
char *newDN;
int depth;
Entry *e = NULL;
Debug( LDAP_DEBUG_TRACE,
"<= dereferencing dn %s\n",
dn, 0, 0 );
newDN = strdup ( dn );
/* while we don't have a matched dn, deref the DN */
for ( depth = 0;
( (e = dn2entry_r( be, newDN, &matched )) == NULL) &&
(depth < be->be_maxDerefDepth);
++depth ) {
if (*matched) {
char *submatch;
if( e != NULL ) {
/* free reader lock */
cache_return_entry_r( &li->li_cache, e );
e = NULL;
}
/*
* make sure there actually is an entry for the matched part
*/
if ( (e = dn2entry_r( be, matched, &submatch )) != NULL) {
char *remainder; /* part before the aliased part */
Entry *newE;
int rlen = strlen(newDN) - strlen(matched);
Debug( LDAP_DEBUG_TRACE,
"<= matched %s\n",
matched, 0, 0 );
remainder = ch_malloc (rlen + 1);
strncpy ( remainder, newDN, rlen );
remainder[rlen] = '\0';
Debug( LDAP_DEBUG_TRACE,
"<= remainder %s\n",
remainder, 0, 0 );
if ((newE = derefAlias (be, conn, op, e)) == NULL) {
free (matched);
free (newDN);
break; /* no associated entry, dont deref */
}
else {
Debug( LDAP_DEBUG_TRACE,
"<= l&g we have %s vs %s \n",
matched, newE->e_dn, 0 );
if (!strcasecmp (matched, newE->e_dn)) {
/* newDN same as old so not an alias, no need to go further */
free (newDN);
free (matched);
break;
}
/*
* we have dereferenced the aliased part so put
* the new dn together
*/
free (newDN);
free (matched);
newDN = ch_malloc (strlen(e->e_dn) + rlen + 1);
strcpy (newDN, remainder);
strcat (newDN, e->e_dn);
Debug( LDAP_DEBUG_TRACE, "<= expanded to %s\n", newDN, 0, 0 );
}
}
else {
break; /* there was no entry for the matched part */
}
}
else {
break; /* there was no matched part */
}
if( e != NULL ) {
/* free reader lock */
cache_return_entry_r( &li->li_cache, e );
e = NULL;
}
}
if( e != NULL ) {
/* free reader lock */
cache_return_entry_r( &li->li_cache, e );
e = NULL;
}
/*
* the final part of the DN might be an alias
* so try to dereference it.
*/
if ( (e = dn2entry_r( be, newDN, &matched )) != NULL) {
if ((e = derefAlias (be, conn, op, e)) != NULL) {
free (newDN);
newDN = strdup (e->e_dn);
}
}
/*
* warn if we exceeded the max depth as the resulting DN may not be dereferenced
*/
if (depth >= be->be_maxDerefDepth) {
Debug( LDAP_DEBUG_TRACE,
"<= 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 );
return newDN;
}
/*
* Copyright (c) 1998 Will Ballantyne, ITSD, Government of BC
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to ITSD, Government of BC. The name of ITSD
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
#include <stdio.h>
#include <string.h>
#include "slap.h"
/*
* given a dn (or root part), return an aliased dn if any of the
* alias suffixes match
*/
char *suffixAlias ( dn, op, be )
char *dn;
Operation *op;
Backend *be;
{
int i, dnLength;
dnLength = strlen ( dn );
op->o_suffix = NULL;
op->o_suffixAliased = NULL;
for ( i = 0;
be->be_suffixAlias != NULL && be->be_suffixAlias[i] != NULL;
i += 2) {
int aliasLength = strlen (be->be_suffixAlias[i]);
if (aliasLength > dnLength) {
continue;
}
if (!strcasecmp(be->be_suffixAlias[i],
dn + (dnLength - aliasLength))) {
char *oldDN = dn;
op->o_suffixAliased = strdup ( be->be_suffixAlias[i] );
dn = ch_malloc ( (dnLength - aliasLength) +
strlen (be->be_suffixAlias[ i+1 ]) + 1);
strncpy (dn, oldDN, dnLength - aliasLength);
strcpy (dn + (dnLength - aliasLength), be->be_suffixAlias[ i+1 ]);
op->o_suffix = strdup (dn);
Debug( LDAP_DEBUG_ARGS, "ALIAS: converted %s to %s", oldDN, dn, 0);
free (oldDN);
break;
}
}
return dn;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment