From bf6c1e0ad2a9bb7e7ecce016aaa22cd5ffb87a1f Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Sat, 24 Oct 1998 02:42:38 +0000 Subject: [PATCH] Added Will Ballantyne's General Aliasing code. Not quite sure if the entry lock handling is correct yet. --- include/ldapconfig.h.edit | 2 + servers/slapd/Make-template | 6 ++- servers/slapd/back-ldbm/Make-template | 6 ++- servers/slapd/back-ldbm/proto-back-ldbm.h | 15 ++++++- servers/slapd/back-ldbm/search.c | 44 +++++++++++++++---- servers/slapd/backend.c | 21 ++++++++++ servers/slapd/bind.c | 4 ++ servers/slapd/config.c | 51 +++++++++++++++++++++++ servers/slapd/delete.c | 4 ++ servers/slapd/modify.c | 5 +++ servers/slapd/proto-slap.h | 5 +++ servers/slapd/search.c | 4 ++ servers/slapd/slap.h | 4 ++ 13 files changed, 159 insertions(+), 12 deletions(-) diff --git a/include/ldapconfig.h.edit b/include/ldapconfig.h.edit index 9bf23812d4..ea88f22a5d 100644 --- a/include/ldapconfig.h.edit +++ b/include/ldapconfig.h.edit @@ -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 */ diff --git a/servers/slapd/Make-template b/servers/slapd/Make-template index 9ce0c6cf1c..116ae69a51 100644 --- a/servers/slapd/Make-template +++ b/servers/slapd/Make-template @@ -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) diff --git a/servers/slapd/back-ldbm/Make-template b/servers/slapd/back-ldbm/Make-template index 4cc4e0a173..2a4d5b3493 100644 --- a/servers/slapd/back-ldbm/Make-template +++ b/servers/slapd/back-ldbm/Make-template @@ -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) diff --git a/servers/slapd/back-ldbm/proto-back-ldbm.h b/servers/slapd/back-ldbm/proto-back-ldbm.h index 1bc9fdd0e1..e834e8eeaf 100644 --- a/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -1,6 +1,20 @@ #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 ); diff --git a/servers/slapd/back-ldbm/search.c b/servers/slapd/back-ldbm/search.c index fd9db48491..f41483c620 100644 --- a/servers/slapd/back-ldbm/search.c +++ b/servers/slapd/back-ldbm/search.c @@ -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 */ diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index 67dafc69ec..076910a4e5 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -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 ); } diff --git a/servers/slapd/bind.c b/servers/slapd/bind.c index fbffeebc9f..5f6ec17621 100644 --- a/servers/slapd/bind.c +++ b/servers/slapd/bind.c @@ -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 ); diff --git a/servers/slapd/config.c b/servers/slapd/config.c index 66050586ab..6c03ebb5fd 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -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 \" line\n", + fname, lineno, 0 ); + exit( 1 ); + } else if ( cargc < 3 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing aliased_dn in \"suffixAlias \" 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 \" 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 ) { diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c index bbab47806c..001d8e161c 100644 --- a/servers/slapd/delete.c +++ b/servers/slapd/delete.c @@ -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; diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index 2629291563..2d9958362b 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -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; diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 83e4872d15..095b785bc9 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -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 */ diff --git a/servers/slapd/search.c b/servers/slapd/search.c index fc96d2fd02..0cadfed276 100644 --- a/servers/slapd/search.c +++ b/servers/slapd/search.c @@ -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, diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 43f1eae8d1..5cffeab89c 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -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_* */ -- 2.39.5