X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fbackover.c;h=7ce420f40da2ada6bfd1aa0279e3852706d48b92;hb=9c550e7235830af9d031d8d7ba86b87f36dcc99f;hp=bb13448a46acb76a465d4f954e32d54abe993679;hpb=0bb0551381d051c62ad09acc531e47e195351500;p=openldap diff --git a/servers/slapd/backover.c b/servers/slapd/backover.c index bb13448a46..7ce420f40d 100644 --- a/servers/slapd/backover.c +++ b/servers/slapd/backover.c @@ -1,16 +1,21 @@ /* backover.c - backend overlay routines */ /* $OpenLDAP$ */ -/* - * Copyright 2003 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file - */ - -/* - * Functions to overlay other modules over a backend. +/* This work is part of OpenLDAP Software . + * + * Copyright 2003-2004 The OpenLDAP Foundation. + * All rights reserved. * - * -- Howard Chu + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . */ +/* Functions to overlay other modules over a backend. */ + #include "portable.h" #include @@ -31,27 +36,26 @@ over_db_func( enum db_which which ) { - slap_overinfo *oi = (slap_overinfo *) be->bd_info; + slap_overinfo *oi = be->bd_info->bi_private; slap_overinst *on = oi->oi_list; - BackendDB bd; + BackendInfo *bi_orig = be->bd_info; BI_db_open **func; int rc = 0; - func = &oi->oi_bd.bd_info->bi_db_open; + func = &oi->oi_orig->bi_db_open; if ( func[which] ) { - rc = func[which]( &oi->oi_bd ); - if ( rc ) return rc; + be->bd_info = oi->oi_orig; + rc = func[which]( be ); } - bd = *be; - for (; on; on=on->on_next) { - bd.bd_info = &on->on_bi; + for (; on && rc == 0; on=on->on_next) { + be->bd_info = &on->on_bi; func = &on->on_bi.bi_db_open; if (func[which]) { - rc = func[which]( &bd ); - if ( rc ) break; + rc = func[which]( be ); } } + be->bd_info = bi_orig; return rc; } @@ -64,26 +68,28 @@ over_db_config( char **argv ) { - slap_overinfo *oi = (slap_overinfo *) be->bd_info; + slap_overinfo *oi = be->bd_info->bi_private; slap_overinst *on = oi->oi_list; - BackendDB bd; + BackendInfo *bi_orig = be->bd_info; int rc = 0; - if ( oi->oi_bd.bd_info->bi_db_config ) { - rc = oi->oi_bd.bd_info->bi_db_config( &oi->oi_bd, fname, lineno, + if ( oi->oi_orig->bi_db_config ) { + be->bd_info = oi->oi_orig; + rc = oi->oi_orig->bi_db_config( be, fname, lineno, argc, argv ); - if ( rc ) return rc; + be->bd_info = (BackendInfo *)oi; + if ( rc != SLAP_CONF_UNKNOWN ) return rc; } - bd = *be; for (; on; on=on->on_next) { - bd.bd_info = &on->on_bi; if (on->on_bi.bi_db_config) { - rc = on->on_bi.bi_db_config( &bd, fname, lineno, + be->bd_info = &on->on_bi; + rc = on->on_bi.bi_db_config( be, fname, lineno, argc, argv ); - if ( rc ) break; + if ( rc != SLAP_CONF_UNKNOWN ) break; } } + be->bd_info = bi_orig; return rc; } @@ -108,7 +114,7 @@ over_db_destroy( BackendDB *be ) { - slap_overinfo *oi = (slap_overinfo *) be->bd_info; + slap_overinfo *oi = be->bd_info->bi_private; slap_overinst *on = oi->oi_list, *next; int rc; @@ -125,15 +131,12 @@ over_db_destroy( static int over_back_response ( Operation *op, SlapReply *rs ) { - slap_overinfo *oi = (slap_overinfo *) op->o_bd->bd_info; + slap_overinfo *oi = op->o_callback->sc_private; slap_overinst *on = oi->oi_list; int rc = SLAP_CB_CONTINUE; BackendDB *be = op->o_bd, db = *op->o_bd; - slap_callback *sc = op->o_callback->sc_private; - slap_callback *s0 = op->o_callback; op->o_bd = &db; - op->o_callback = sc; for (; on; on=on->on_next ) { if ( on->on_response ) { db.bd_info = (BackendInfo *)on; @@ -141,17 +144,46 @@ over_back_response ( Operation *op, SlapReply *rs ) if ( rc != SLAP_CB_CONTINUE ) break; } } - if ( sc && (rc == SLAP_CB_CONTINUE) ) { - rc = sc->sc_response( op, rs ); - } op->o_bd = be; - op->o_callback = s0; return rc; } -enum op_which { op_bind = 0, op_unbind, op_search, op_compare, - op_modify, op_modrdn, op_add, op_delete, op_abandon, - op_cancel, op_extended }; +enum op_which { + op_bind = 0, + op_unbind, + op_search, + op_compare, + op_modify, + op_modrdn, + op_add, + op_delete, + op_abandon, + op_cancel, + op_extended, + op_aux_operational, + op_aux_chk_referrals, + op_last +}; + +/* + * default return code in case of missing backend function + * and overlay stack returning SLAP_CB_CONTINUE + */ +static int op_rc[] = { + LDAP_UNWILLING_TO_PERFORM, /* bind */ + LDAP_UNWILLING_TO_PERFORM, /* unbind */ + LDAP_UNWILLING_TO_PERFORM, /* search */ + LDAP_UNWILLING_TO_PERFORM, /* compare */ + LDAP_UNWILLING_TO_PERFORM, /* modify */ + LDAP_UNWILLING_TO_PERFORM, /* modrdn */ + LDAP_UNWILLING_TO_PERFORM, /* add */ + LDAP_UNWILLING_TO_PERFORM, /* delete */ + LDAP_UNWILLING_TO_PERFORM, /* abandon */ + LDAP_UNWILLING_TO_PERFORM, /* cancel */ + LDAP_UNWILLING_TO_PERFORM, /* extended */ + LDAP_SUCCESS, /* aux_operational */ + LDAP_SUCCESS /* aux_chk_referrals */ +}; static int over_op_func( @@ -160,15 +192,16 @@ over_op_func( enum op_which which ) { - slap_overinfo *oi = (slap_overinfo *) op->o_bd->bd_info; + slap_overinfo *oi = op->o_bd->bd_info->bi_private; slap_overinst *on = oi->oi_list; BI_op_bind **func; BackendDB *be = op->o_bd, db = *op->o_bd; - slap_callback cb = {over_back_response, NULL}; + slap_callback cb = {NULL, over_back_response, NULL, NULL}; int rc = SLAP_CB_CONTINUE; op->o_bd = &db; - cb.sc_private = op->o_callback; + cb.sc_next = op->o_callback; + cb.sc_private = oi; op->o_callback = &cb; for (; on; on=on->on_next ) { @@ -180,15 +213,17 @@ over_op_func( } } - func = &oi->oi_bd.bd_info->bi_op_bind; + func = &oi->oi_orig->bi_op_bind; if ( func[which] && rc == SLAP_CB_CONTINUE ) { + db.bd_info = oi->oi_orig; rc = func[which]( op, rs ); } /* should not fall thru this far without anything happening... */ if ( rc == SLAP_CB_CONTINUE ) { - rc = LDAP_UNWILLING_TO_PERFORM; + rc = op_rc[ which ]; } op->o_bd = be; + op->o_callback = cb.sc_next; return rc; } @@ -258,6 +293,18 @@ over_op_extended( Operation *op, SlapReply *rs ) return over_op_func( op, rs, op_extended ); } +static int +over_aux_operational( Operation *op, SlapReply *rs ) +{ + return over_op_func( op, rs, op_aux_operational ); +} + +static int +over_aux_chk_referrals( Operation *op, SlapReply *rs ) +{ + return over_op_func( op, rs, op_aux_chk_referrals ); +} + int overlay_register( slap_overinst *on @@ -268,20 +315,95 @@ overlay_register( return 0; } +/* + * iterator on registered overlays; overlay_next( NULL ) returns the first + * overlay; * subsequent calls with the previously returned value allow to + * iterate * over the entire list; returns NULL when no more overlays are + * registered. + */ + +slap_overinst * +overlay_next( + slap_overinst *on +) +{ + if ( on == NULL ) { + return overlays; + } + + return on->on_next; +} + +/* + * returns a specific registered overlay based on the type; NULL if not + * registered. + */ + +slap_overinst * +overlay_find( const char *over_type ) +{ + slap_overinst *on = overlays; + + assert( over_type ); + + for ( ; on; on = on->on_next ) { + if ( strcmp( on->on_bi.bi_type, over_type ) == 0 ) { + break; + } + } + + return on; +} + static const char overtype[] = "over"; +/* + * returns TRUE (1) if the database is actually an overlay instance; + * FALSE (0) otherwise. + */ + +int +overlay_is_over( BackendDB *be ) +{ + return be->bd_info->bi_type == overtype; +} + +/* + * returns TRUE (1) if the given database is actually an overlay + * instance and, somewhere in the list, contains the requested overlay; + * FALSE (0) otherwise. + */ + +int +overlay_is_inst( BackendDB *be, const char *over_type ) +{ + slap_overinst *on; + + assert( be ); + + if ( !overlay_is_over( be ) ) { + return 0; + } + + on = ((slap_overinfo *)be->bd_info->bi_private)->oi_list; + for ( ; on; on = on->on_next ) { + if ( strcmp( on->on_bi.bi_type, over_type ) == 0 ) { + return 1; + } + } + + return 0; +} + /* add an overlay to a particular backend. */ int overlay_config( BackendDB *be, const char *ov ) { - slap_overinst *on, *on2, *prev; - slap_overinfo *oi; - BackendInfo *bi; + slap_overinst *on = NULL, *on2 = NULL; + slap_overinfo *oi = NULL; + BackendInfo *bi = NULL; - for ( on = overlays; on; on=on->on_next ) { - if (!strcmp( ov, on->on_bi.bi_type ) ) - break; - } + on = overlay_find( ov ); if (!on) { Debug( LDAP_DEBUG_ANY, "overlay %s not found\n", ov, 0, 0 ); return 1; @@ -290,10 +412,16 @@ overlay_config( BackendDB *be, const char *ov ) /* If this is the first overlay on this backend, set up the * overlay info structure */ - if ( be->bd_info->bi_type != overtype ) { + if ( !overlay_is_over( be ) ) { oi = ch_malloc( sizeof(slap_overinfo) ); - oi->oi_bd = *be; + oi->oi_orig = be->bd_info; oi->oi_bi = *be->bd_info; + + /* Save a pointer to ourself in bi_private. + * This allows us to keep working in conjunction + * with backglue... + */ + oi->oi_bi.bi_private = oi; oi->oi_list = NULL; bi = (BackendInfo *)oi; @@ -314,25 +442,32 @@ overlay_config( BackendDB *be, const char *ov ) bi->bi_op_delete = over_op_delete; bi->bi_op_abandon = over_op_abandon; bi->bi_op_cancel = over_op_cancel; + bi->bi_extended = over_op_extended; + /* + * this is fine because it has the same + * args of the operations; we need to rework + * all the hooks to share the same args + * of the operations... + */ + bi->bi_operational = over_aux_operational; + bi->bi_chk_referrals = over_aux_chk_referrals; + be->bd_info = bi; + + } else { + oi = be->bd_info->bi_private; } - /* Walk to the end of the list of overlays, add the new - * one onto the end + /* Insert new overlay on head of list. Overlays are executed + * in reverse of config order... */ - oi = (slap_overinfo *) be->bd_info; - for ( prev=NULL, on2 = oi->oi_list; on2; prev=on2, on2=on2->on_next ); on2 = ch_calloc( 1, sizeof(slap_overinst) ); - if ( !prev ) { - oi->oi_list = on2; - } else { - prev->on_next = on2; - } *on2 = *on; - on2->on_next = NULL; on2->on_info = oi; + on2->on_next = oi->oi_list; + oi->oi_list = on2; /* Any initialization needed? */ if ( on->on_bi.bi_db_init ) {