Commit bf6c1e0a authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Added Will Ballantyne's General Aliasing code.

Not quite sure if the entry lock handling is correct yet.
parent d4c5308b
......@@ -284,6 +284,8 @@ Please try again later.\r\n"
*/
/* location of the default slapd config file */
#define SLAPD_DEFAULT_CONFIGFILE "%ETCDIR%/slapd.conf"
/* default max deref depth for aliases */
#define SLAPD_DEFAULT_MAXDEREFDEPTH 15
/* default sizelimit on number of entries from a search */
#define SLAPD_DEFAULT_SIZELIMIT 500
/* default timelimit to spend on a search */
......
......@@ -23,14 +23,16 @@ SRCS = main.c daemon.c connection.c search.c filter.c add.c charray.c \
value.c ava.c bind.c unbind.c abandon.c filterentry.c \
phonetic.c acl.c str2filter.c aclparse.c init.c \
detach.c strdup.c tempnam.c repl.c lock.c \
schema.c schemaparse.c monitor.c configinfo.c
schema.c schemaparse.c monitor.c configinfo.c \
suffixalias.c
OBJS = main.o daemon.o connection.o search.o filter.o add.o charray.o \
attr.o entry.o config.o backend.o result.o operation.o \
dn.o compare.o modify.o delete.o modrdn.o ch_malloc.o \
value.o ava.o bind.o unbind.o abandon.o filterentry.o \
phonetic.o acl.o str2filter.o aclparse.o init.o \
detach.o strdup.o tempnam.o repl.o lock.o \
schema.o schemaparse.o monitor.o configinfo.o
schema.o schemaparse.o monitor.o configinfo.o \
suffixalias.o
INCLUDES= -I. -I$(HDIR) $(KRBINCLUDEFLAG)
DEFINES = $(DEFS) $(SERVERDEFS)
......
......@@ -20,11 +20,13 @@ VERSIONFILE = $(LDAPSRC)/build/version
SRCS = idl.c add.c search.c cache.c dbcache.c dn2id.c id2entry.c \
index.c id2children.c nextid.c abandon.c compare.c \
modify.c modrdn.c delete.c init.c config.c bind.c attr.c \
filterindex.c unbind.c kerberos.c close.c group.c
filterindex.c unbind.c kerberos.c close.c group.c \
alias.c
OBJS = idl.o add.o search.o cache.o dbcache.o dn2id.o id2entry.o \
index.o id2children.o nextid.o abandon.o compare.o \
modify.o modrdn.o delete.o init.o config.o bind.o attr.o \
filterindex.o unbind.o kerberos.o close.o group.o
filterindex.o unbind.o kerberos.o close.o group.o \
alias.o
INCLUDES= -I. -I.. -I$(HDIR) $(KRBINCLUDEFLAG)
DEFINES = $(DEFS) $(SERVERDEFS) $(THREADS)
......
#ifndef _PROTO_BACK_LDBM
#define _PROTO_BACK_LDBM
/*
* alias.c
*/
Entry *derefAlias ( Backend *be,
Connection *conn,
Operation *op,
Entry *e
);
char *derefDN ( Backend *be,
Connection *conn,
Operation *op,
char *dn
);
/*
* attr.c
*/
......@@ -41,7 +55,6 @@ int ldbm_cache_delete( struct dbcache *db, Datum key );
int dn2id_add( Backend *be, char *dn, ID id );
ID dn2id( Backend *be, char *dn );
int dn2id_delete( Backend *be, char *dn );
/*Entry * dn2entry( Backend *be, char *dn, char **matched );*/
Entry * dn2entry_r( Backend *be, char *dn, char **matched );
Entry * dn2entry_w( Backend *be, char *dn, char **matched );
......
......@@ -59,6 +59,7 @@ ldbm_back_search(
int rmaxsize, nrefs;
char *rbuf, *rcur, *r;
int nentries = 0;
char *realBase;
Debug(LDAP_DEBUG_ARGS, "=> ldbm_back_search\n", 0, 0, 0);
......@@ -76,19 +77,37 @@ ldbm_back_search(
be->be_sizelimit : slimit;
}
/*
* check and apply aliasing where the dereferencing applies to
* the subordinates of the base
*/
realBase = strdup (base);
switch ( deref ) {
case LDAP_DEREF_FINDING:
case LDAP_DEREF_ALWAYS:
free (realBase);
realBase = derefDN ( be, conn, op, base );
break;
}
(void) dn_normalize (realBase);
Debug( LDAP_DEBUG_TRACE, "using base %s\n",
realBase, 0, 0 );
switch ( scope ) {
case LDAP_SCOPE_BASE:
candidates = base_candidates( be, conn, op, base, filter,
candidates = base_candidates( be, conn, op, realBase, filter,
attrs, attrsonly, &matched, &err );
break;
case LDAP_SCOPE_ONELEVEL:
candidates = onelevel_candidates( be, conn, op, base, filter,
candidates = onelevel_candidates( be, conn, op, realBase, filter,
attrs, attrsonly, &matched, &err );
break;
case LDAP_SCOPE_SUBTREE:
candidates = subtree_candidates( be, conn, op, base, filter,
candidates = subtree_candidates( be, conn, op, realBase, filter,
attrs, attrsonly, &matched, NULL, &err, 1 );
break;
......@@ -165,7 +184,7 @@ ldbm_back_search(
MAKE_SPACE( ref->a_vals[i]->bv_len + 2 );
*rcur++ = '\n';
strncpy( rcur, ref->a_vals[i]->bv_val,
ref->a_vals[i]->bv_len );
ref->a_vals[i]->bv_len );
rcur = rcur + ref->a_vals[i]->bv_len;
*rcur = '\0';
nrefs++;
......@@ -184,15 +203,15 @@ ldbm_back_search(
if ( scope == LDAP_SCOPE_ONELEVEL ) {
if ( (dn = dn_parent( be, e->e_dn )) != NULL ) {
(void) dn_normalize( dn );
scopeok = (dn == base) ? 1 : (! strcasecmp( dn, base ));
scopeok = (dn == realBase) ? 1 : (! strcasecmp( dn, realBase ));
} else {
scopeok = (base == NULL || *base == '\0');
scopeok = (realBase == NULL || *realBase == '\0');
}
free( dn );
} else if ( scope == LDAP_SCOPE_SUBTREE ) {
dn = strdup( e->e_dn );
(void) dn_normalize( dn );
scopeok = dn_issuffix( dn, base );
scopeok = dn_issuffix( dn, realBase );
free( dn );
}
......@@ -208,6 +227,17 @@ ldbm_back_search(
return( 0 );
}
/*
* check and apply aliasing where the dereferencing applies to
* the subordinates of the base
*/
switch ( deref ) {
case LDAP_DEREF_SEARCHING:
case LDAP_DEREF_ALWAYS:
e = derefAlias ( be, conn, op, e );
break;
}
switch ( send_search_entry( be, conn, op, e,
attrs, attrsonly ) ) {
case 0: /* entry sent ok */
......
......@@ -186,6 +186,27 @@ select_backend( char * dn )
}
}
/* if no proper suffix could be found then check for aliases */
for ( i = 0; i < nbackends; i++ ) {
for ( j = 0;
backends[i].be_suffixAlias != NULL &&
backends[i].be_suffixAlias[j] != NULL;
j += 2 )
{
len = strlen( backends[i].be_suffixAlias[j] );
if ( len > dnlen ) {
continue;
}
if ( strcasecmp( backends[i].be_suffixAlias[j],
dn + (dnlen - len) ) == 0 ) {
return( &backends[i] );
}
}
}
return( NULL );
}
......
......@@ -19,6 +19,7 @@
#include "slap.h"
extern Backend *select_backend();
extern char *suffixAlias();
extern char *default_referral;
......@@ -155,6 +156,9 @@ do_bind(
return;
}
/* alias suffix */
dn = suffixAlias ( dn, op, be );
if ( be->be_bind != NULL ) {
if ( (*be->be_bind)( be, conn, op, dn, method, &cred ) == 0 ) {
pthread_mutex_lock( &conn->c_dnmutex );
......
......@@ -81,6 +81,9 @@ read_config( char *fname, Backend **bep, FILE *pfp )
*bep = new_backend( cargv[1] );
be = *bep;
/* assign a default depth limit for alias deref */
be->be_maxDerefDepth = SLAPD_DEFAULT_MAXDEREFDEPTH;
/* set size limit */
} else if ( strcasecmp( cargv[0], "sizelimit" ) == 0 ) {
if ( cargc < 2 ) {
......@@ -131,6 +134,54 @@ read_config( char *fname, Backend **bep, FILE *pfp )
charray_add( &be->be_suffix, dn );
}
/* set database suffixAlias */
} else if ( strcasecmp( cargv[0], "suffixAlias" ) == 0 ) {
if ( cargc < 2 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing alias and aliased_dn in \"suffixAlias <alias> <aliased_dn>\" line\n",
fname, lineno, 0 );
exit( 1 );
} else if ( cargc < 3 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing aliased_dn in \"suffixAlias <alias> <aliased_dn>\" line\n",
fname, lineno, 0 );
exit( 1 );
} else if ( cargc > 3 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: extra cruft in suffixAlias line (ignored)\n",
fname, lineno, 0 );
}
if ( be == NULL ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: suffixAlias line must appear inside a database definition (ignored)\n",
fname, lineno, 0 );
} else {
dn = strdup( cargv[1] );
(void) dn_normalize( dn );
charray_add( &be->be_suffixAlias, dn );
dn = strdup( cargv[2] );
(void) dn_normalize( dn );
charray_add( &be->be_suffixAlias, dn );
}
/* set max deref depth */
} else if ( strcasecmp( cargv[0], "maxDerefDepth" ) == 0 ) {
if ( cargc < 2 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing depth in \"maxDerefDepth <depth>\" line\n",
fname, lineno, 0 );
exit( 1 );
}
if ( be == NULL ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: depth line must appear inside a database definition (ignored)\n",
fname, lineno, 0 );
} else {
be->be_maxDerefDepth = atoi (cargv[1]);
}
/* set magic "root" dn for this database */
} else if ( strcasecmp( cargv[0], "rootdn" ) == 0 ) {
if ( cargc < 2 ) {
......
......@@ -17,6 +17,7 @@
#include "slap.h"
extern Backend *select_backend();
extern char *suffixAlias();
extern char *default_referral;
......@@ -62,6 +63,9 @@ do_delete(
return;
}
/* alias suffix if approp */
dn = suffixAlias ( dn, op, be );
/*
* do the delete if 1 && (2 || 3)
* 1) there is a delete function implemented in this backend;
......
......@@ -27,6 +27,8 @@ extern int global_lastmod;
static void modlist_free();
static void add_lastmods();
extern char *suffixAlias();
void
do_modify(
......@@ -147,6 +149,9 @@ do_modify(
return;
}
/* alias suffix if approp */
dn = suffixAlias ( dn, op, be );
/*
* do the modify if 1 && (2 || 3)
* 1) there is a modify function implemented in this backend;
......
......@@ -210,4 +210,9 @@ int value_ncmp( struct berval *v1, struct berval *v2, int syntax, int len,
int value_find( struct berval **vals, struct berval *v, int syntax,
int normalize );
/*
* suffixAlias.c
*/
char *suffixAlias ( char *dn, Operation *op, Backend *be );
#endif /* _proto_slap */
......@@ -19,6 +19,7 @@
extern int get_filter();
extern Backend *select_backend();
extern char *suffixAlias();
extern char *default_referral;
......@@ -161,6 +162,9 @@ do_search( conn, op )
return;
}
/* translate the base if it matches an aliased base part */
base = suffixAlias ( base, op, be );
/* actually do the search and send the result(s) */
if ( be->be_search != NULL ) {
(*be->be_search)( be, conn, op, base, scope, deref, sizelimit,
......
......@@ -178,9 +178,11 @@ struct objclass {
typedef struct backend {
char **be_suffix; /* the DN suffixes of data in this backend */
char **be_suffixAlias; /* the DN suffix aliases of data in this backend */
char *be_rootdn; /* the magic "root" dn for this db */
char *be_rootpw; /* the magic "root" password for this db */
int be_readonly; /* 1 => db is in "read only" mode */
int be_maxDerefDepth; /* limit for depth of an alias deref */
int be_sizelimit; /* size limit for this backend */
int be_timelimit; /* time limit for this backend */
struct acl *be_acl; /* access control list for this backend */
......@@ -221,6 +223,8 @@ typedef struct op {
unsigned long o_tag; /* tag of the request */
time_t o_time; /* time op was initiated */
char *o_dn; /* dn bound when op was initiated */
char *o_suffix; /* suffix if aliased */
char *o_suffixAliased; /* pending suffix translation */
int o_authtype; /* auth method used to bind dn */
/* values taken from ldap.h */
/* LDAP_AUTH_* */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment