From 09d05a57c2b197b0243c0878e76fd4b8336636b0 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 11 Jun 2003 04:36:35 +0000 Subject: [PATCH] More overlay tweaks. Added LDAP chaining overlay. --- servers/slapd/back-ldap/Makefile.in | 4 +- servers/slapd/back-ldap/back-ldap.h | 2 + servers/slapd/back-ldap/chain.c | 166 ++++++++++++++++++++++++++++ servers/slapd/back-ldap/init.c | 2 + servers/slapd/backover.c | 20 +++- servers/slapd/slap.h | 4 +- 6 files changed, 192 insertions(+), 6 deletions(-) create mode 100644 servers/slapd/back-ldap/chain.c diff --git a/servers/slapd/back-ldap/Makefile.in b/servers/slapd/back-ldap/Makefile.in index bbeba6b0c7..554bdf69cf 100644 --- a/servers/slapd/back-ldap/Makefile.in +++ b/servers/slapd/back-ldap/Makefile.in @@ -4,10 +4,10 @@ SRCS = init.c config.c search.c bind.c unbind.c add.c compare.c \ delete.c modify.c modrdn.c \ - suffixmassage.c map.c extended.c + suffixmassage.c map.c extended.c chain.c OBJS = init.lo config.lo search.lo bind.lo unbind.lo add.lo compare.lo \ delete.lo modify.lo modrdn.lo \ - suffixmassage.lo map.lo extended.lo + suffixmassage.lo map.lo extended.lo chain.lo LDAP_INCDIR= ../../../include LDAP_LIBDIR= ../../../libraries diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index dc67f7e158..97cc6eff86 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -194,6 +194,8 @@ extern int suffix_massage_config( struct rewrite_info *info, extern int ldap_dnattr_rewrite( dncookie *dc, BerVarray a_vals ); extern int ldap_dnattr_result_rewrite( dncookie *dc, BerVarray a_vals ); +extern int ldap_chain_setup(); + LDAP_END_DECL #endif /* SLAPD_LDAP_H */ diff --git a/servers/slapd/back-ldap/chain.c b/servers/slapd/back-ldap/chain.c new file mode 100644 index 0000000000..214a250649 --- /dev/null +++ b/servers/slapd/back-ldap/chain.c @@ -0,0 +1,166 @@ +/* chain.c - chain LDAP operations */ +/* $OpenLDAP$ */ +/* + * Copyright 2003 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ +/* + * Copyright 2003, Howard Chu, All rights reserved. + * + * Permission is granted to anyone to use this software for any purpose + * on any computer system, and to alter it and redistribute it, subject + * to the following restrictions: + * + * 1. The author is not responsible for the consequences of use of this + * software, no matter how awful, even if they arise from flaws in it. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Since few users ever read sources, + * credits should appear in the documentation. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. Since few users + * ever read sources, credits should appear in the documentation. + * + * 4. This notice may not be removed or altered. + */ + +#include "portable.h" + +#include + +#include +#include + +#include "slap.h" +#include "back-ldap.h" + +static int +ldap_chain_response( Operation *op, SlapReply *rs ) +{ + slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; + void *private = op->o_bd->be_private; + LDAPControl **prev = op->o_ctrls; + LDAPControl **ctrls, authz; + int i, nctrls, rc; + int cache = op->o_do_not_cache; + + if ( rs->sr_err != LDAP_REFERRAL ) + return SLAP_CB_CONTINUE; + + op->o_bd->be_private = on->on_bi.bi_private; + for (i=0; prev && prev[i]; i++); + nctrls = i; + + ctrls = op->o_tmpalloc((i+1)*sizeof(LDAPControl *), op->o_tmpmemctx); + for (i=0; i o_dn; + + /* Chaining is performed by a privileged user on behalf + * of a normal user + */ + op->o_do_not_cache = 1; + op->o_ctrls = ctrls; + + switch( op->o_tag ) { + case LDAP_REQ_BIND: + rc = ldap_back_bind( op, rs ); + break; + case LDAP_REQ_ADD: + rc = ldap_back_add( op, rs ); + break; + case LDAP_REQ_DELETE: + rc = ldap_back_delete( op, rs ); + break; + case LDAP_REQ_MODRDN: + rc = ldap_back_modrdn( op, rs ); + break; + case LDAP_REQ_MODIFY: + rc = ldap_back_modify( op, rs ); + break; + case LDAP_REQ_COMPARE: + rc = ldap_back_compare( op, rs ); + break; + case LDAP_REQ_SEARCH: + rc = ldap_back_search( op, rs ); + break; + case LDAP_REQ_EXTENDED: + rc = ldap_back_extended( op, rs ); + break; + default: + rc = SLAP_CB_CONTINUE; + break; + } + op->o_do_not_cache = cache; + op->o_ctrls = prev; + op->o_bd->be_private = private; + op->o_tmpfree( ctrls, op->o_tmpmemctx ); + + return rc; +} + +static int ldap_chain_config( + BackendDB *be, + const char *fname, + int lineno, + int argc, + char **argv +) +{ + slap_overinst *on = (slap_overinst *) be->bd_info; + void *private = be->be_private; + int rc; + + be->be_private = on->on_bi.bi_private; + rc = ldap_back_db_config( be, fname, lineno, argc, argv ); + be->be_private = private; + return rc; +} + +static int ldap_chain_init( + BackendDB *be +) +{ + slap_overinst *on = (slap_overinst *) be->bd_info; + void *private = be->be_private; + int rc; + + be->be_private = NULL; + rc = ldap_back_db_init( be ); + on->on_bi.bi_private = be->be_private; + be->be_private = private; + return rc; +} + +static int ldap_chain_destroy( + BackendDB *be +) +{ + slap_overinst *on = (slap_overinst *) be->bd_info; + void *private = be->be_private; + int rc; + + be->be_private = on->on_bi.bi_private; + rc = ldap_back_db_destroy( be ); + on->on_bi.bi_private = be->be_private; + be->be_private = private; + return rc; +} + +static slap_overinst ldapchain; + +int ldap_chain_setup() +{ + ldapchain.on_bi.bi_type = "chain"; + ldapchain.on_bi.bi_db_init = ldap_chain_init; + ldapchain.on_bi.bi_db_config = ldap_chain_config; + ldapchain.on_bi.bi_db_destroy = ldap_chain_destroy; + ldapchain.on_response = ldap_chain_response; + + return overlay_register( &ldapchain ); +} diff --git a/servers/slapd/back-ldap/init.c b/servers/slapd/back-ldap/init.c index 5bf32766f2..58585303ce 100644 --- a/servers/slapd/back-ldap/init.c +++ b/servers/slapd/back-ldap/init.c @@ -96,6 +96,8 @@ ldap_back_initialize( bi->bi_connection_init = 0; bi->bi_connection_destroy = ldap_back_conn_destroy; + ldap_chain_setup(); + return 0; } diff --git a/servers/slapd/backover.c b/servers/slapd/backover.c index 61f8acbe35..6b29007eb1 100644 --- a/servers/slapd/backover.c +++ b/servers/slapd/backover.c @@ -127,7 +127,7 @@ over_back_response ( Operation *op, SlapReply *rs ) { slap_overinfo *oi = (slap_overinfo *) op->o_bd->bd_info; slap_overinst *on = oi->oi_list; - int rc = 0; + int rc = SLAP_CB_CONTINUE; BackendDB *be = op->o_bd, db = *op->o_bd; slap_callback *sc = op->o_callback->sc_private; @@ -136,14 +136,15 @@ over_back_response ( Operation *op, SlapReply *rs ) if ( on->on_response ) { db.bd_info = (BackendInfo *)on; rc = on->on_response( op, rs ); - if ( rc ) break; + if ( ! (rc & SLAP_CB_CONTINUE) ) break; } } op->o_callback = sc; - if ( rc == 0 && sc ) { + if ( sc && (rc & SLAP_CB_CONTINUE) ) { rc = sc->sc_response( op, rs ); } op->o_bd = be; + rc &= ~SLAP_CB_CONTINUE; return rc; } @@ -282,6 +283,9 @@ overlay_config( BackendDB *be, const char *ov ) return 1; } + /* If this is the first overlay on this backend, set up the + * overlay info structure + */ if ( be->bd_info->bi_type != overtype ) { oi = ch_malloc( sizeof(slap_overinfo) ); oi->oi_bd = *be; @@ -311,6 +315,9 @@ overlay_config( BackendDB *be, const char *ov ) be->bd_info = bi; } + /* Walk to the end of the list of overlays, add the new + * one onto the end + */ oi = (slap_overinfo *) be->bd_info; for ( prev=NULL, on2 = oi->oi_list; on2; prev=on2, on2=on2->on_next ); on2 = ch_malloc( sizeof(slap_overinst) ); @@ -321,6 +328,13 @@ overlay_config( BackendDB *be, const char *ov ) } *on2 = *on; + /* Any initialization needed? */ + if ( on->on_bi.bi_db_init ) { + be->bd_info = (BackendInfo *)on2; + on2->on_bi.bi_db_init( be ); + be->bd_info = (BackendInfo *)oi; + } + return 0; } diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index e453346cf8..47d2453210 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1768,7 +1768,6 @@ struct slap_overinfo; typedef struct slap_overinst { BackendInfo on_bi; slap_response *on_response; - void *on_private; struct slap_overinfo *on_info; struct slap_overinst *on_next; } slap_overinst; @@ -1779,6 +1778,9 @@ typedef struct slap_overinfo { slap_overinst *oi_list; } slap_overinfo; +/* Should successive callbacks in a chain be processed? */ +#define SLAP_CB_CONTINUE 0x8000 + /* * Paged Results state */ -- 2.39.5