X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fbackover.c;h=1be6cfa3e9000e8034454bd54e9ac0a83a65832b;hb=5a1b1088608b3871447ff6ab8f9a6cd77fd8251c;hp=9a7b4df76114a88412287ed5cc529d32c0f85138;hpb=6020a6d81d1f5decdb244e2bb082978272c0c4a7;p=openldap diff --git a/servers/slapd/backover.c b/servers/slapd/backover.c index 9a7b4df761..1be6cfa3e9 100644 --- a/servers/slapd/backover.c +++ b/servers/slapd/backover.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2003-2006 The OpenLDAP Foundation. + * Copyright 2003-2009 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,42 +29,6 @@ static slap_overinst *overlays; -enum db_which { - db_open = 0, - db_close, - db_destroy, - db_last -}; - -static int -over_db_func( - BackendDB *be, - enum db_which which -) -{ - slap_overinfo *oi = be->bd_info->bi_private; - slap_overinst *on = oi->oi_list; - BackendInfo *bi_orig = be->bd_info; - BI_db_open **func; - int rc = 0; - - func = &oi->oi_orig->bi_db_open; - if ( func[which] ) { - be->bd_info = oi->oi_orig; - rc = func[which]( be ); - } - - 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]( be ); - } - } - be->bd_info = bi_orig; - return rc; -} - static int over_db_config( BackendDB *be, @@ -139,6 +103,8 @@ over_db_config( ca.be = be; snprintf( ca.log, sizeof( ca.log ), "%s: line %d", ca.fname, ca.lineno ); + ca.op = SLAP_CONFIG_ADD; + ca.valx = -1; for (; on; on=on->on_next) { rc = SLAP_CONF_UNKNOWN; @@ -147,6 +113,7 @@ over_db_config( ca.bi = &on->on_bi; ct = config_find_keyword( on->on_bi.bi_cf_ocs->co_table, &ca ); if ( ct ) { + ca.table = on->on_bi.bi_cf_ocs->co_type; rc = config_add_vals( ct, &ca ); if ( rc != SLAP_CONF_UNKNOWN ) break; @@ -167,15 +134,35 @@ over_db_config( static int over_db_open( - BackendDB *be + BackendDB *be, + ConfigReply *cr ) { - return over_db_func( be, db_open ); + slap_overinfo *oi = be->bd_info->bi_private; + slap_overinst *on = oi->oi_list; + BackendDB db = *be; + int rc = 0; + + db.be_flags |= SLAP_DBFLAG_OVERLAY; + db.bd_info = oi->oi_orig; + if ( db.bd_info->bi_db_open ) { + rc = db.bd_info->bi_db_open( &db, cr ); + } + + for (; on && rc == 0; on=on->on_next) { + db.bd_info = &on->on_bi; + if ( db.bd_info->bi_db_open ) { + rc = db.bd_info->bi_db_open( &db, cr ); + } + } + + return rc; } static int over_db_close( - BackendDB *be + BackendDB *be, + ConfigReply *cr ) { slap_overinfo *oi = be->bd_info->bi_private; @@ -186,13 +173,13 @@ over_db_close( for (; on && rc == 0; on=on->on_next) { be->bd_info = &on->on_bi; if ( be->bd_info->bi_db_close ) { - rc = be->bd_info->bi_db_close( be ); + rc = be->bd_info->bi_db_close( be, cr ); } } if ( oi->oi_orig->bi_db_close ) { be->bd_info = oi->oi_orig; - rc = be->bd_info->bi_db_close( be ); + rc = be->bd_info->bi_db_close( be, cr ); } be->bd_info = bi_orig; @@ -201,22 +188,35 @@ over_db_close( static int over_db_destroy( - BackendDB *be + BackendDB *be, + ConfigReply *cr ) { slap_overinfo *oi = be->bd_info->bi_private; slap_overinst *on = oi->oi_list, *next; - int rc; + BackendInfo *bi_orig = be->bd_info; + int rc = 0; - rc = over_db_func( be, db_destroy ); + be->bd_info = oi->oi_orig; + if ( be->bd_info->bi_db_destroy ) { + rc = be->bd_info->bi_db_destroy( be, cr ); + } + + for (; on && rc == 0; on=on->on_next) { + be->bd_info = &on->on_bi; + if ( be->bd_info->bi_db_destroy ) { + rc = be->bd_info->bi_db_destroy( be, cr ); + } + } + on = oi->oi_list; if ( on ) { for (next = on->on_next; on; on=next) { next = on->on_next; free( on ); } } - + be->bd_info = bi_orig; free( oi ); return rc; } @@ -322,6 +322,147 @@ over_access_allowed( return rc; } +int +overlay_entry_get_ov( + Operation *op, + struct berval *dn, + ObjectClass *oc, + AttributeDescription *ad, + int rw, + Entry **e, + slap_overinst *on ) +{ + slap_overinfo *oi = on->on_info; + BackendDB *be = op->o_bd, db; + BackendInfo *bi = op->o_bd->bd_info; + int rc = SLAP_CB_CONTINUE; + + for ( ; on; on = on->on_next ) { + if ( on->on_bi.bi_entry_get_rw ) { + /* NOTE: do not copy the structure until required */ + if ( !SLAP_ISOVERLAY( op->o_bd ) ) { + db = *op->o_bd; + db.be_flags |= SLAP_DBFLAG_OVERLAY; + op->o_bd = &db; + } + + op->o_bd->bd_info = (BackendInfo *)on; + rc = on->on_bi.bi_entry_get_rw( op, dn, + oc, ad, rw, e ); + if ( rc != SLAP_CB_CONTINUE ) break; + } + } + + if ( rc == SLAP_CB_CONTINUE ) { + /* if the database structure was changed, o_bd points to a + * copy of the structure; put the original bd_info in place */ + if ( SLAP_ISOVERLAY( op->o_bd ) ) { + op->o_bd->bd_info = oi->oi_orig; + } + + if ( oi->oi_orig->bi_entry_get_rw ) { + rc = oi->oi_orig->bi_entry_get_rw( op, dn, + oc, ad, rw, e ); + } + } + /* should not fall thru this far without anything happening... */ + if ( rc == SLAP_CB_CONTINUE ) { + rc = LDAP_UNWILLING_TO_PERFORM; + } + + op->o_bd = be; + op->o_bd->bd_info = bi; + + return rc; +} + +static int +over_entry_get_rw( + Operation *op, + struct berval *dn, + ObjectClass *oc, + AttributeDescription *ad, + int rw, + Entry **e ) +{ + slap_overinfo *oi; + slap_overinst *on; + + assert( op->o_bd != NULL ); + + oi = op->o_bd->bd_info->bi_private; + on = oi->oi_list; + + return overlay_entry_get_ov( op, dn, oc, ad, rw, e, on ); +} + +int +overlay_entry_release_ov( + Operation *op, + Entry *e, + int rw, + slap_overinst *on ) +{ + slap_overinfo *oi = on->on_info; + BackendDB *be = op->o_bd, db; + BackendInfo *bi = op->o_bd->bd_info; + int rc = SLAP_CB_CONTINUE; + + for ( ; on; on = on->on_next ) { + if ( on->on_bi.bi_entry_release_rw ) { + /* NOTE: do not copy the structure until required */ + if ( !SLAP_ISOVERLAY( op->o_bd ) ) { + db = *op->o_bd; + db.be_flags |= SLAP_DBFLAG_OVERLAY; + op->o_bd = &db; + } + + op->o_bd->bd_info = (BackendInfo *)on; + rc = on->on_bi.bi_entry_release_rw( op, e, rw ); + if ( rc != SLAP_CB_CONTINUE ) break; + } + } + + if ( rc == SLAP_CB_CONTINUE ) { + /* if the database structure was changed, o_bd points to a + * copy of the structure; put the original bd_info in place */ + if ( SLAP_ISOVERLAY( op->o_bd ) ) { + op->o_bd->bd_info = oi->oi_orig; + } + + if ( oi->oi_orig->bi_entry_release_rw ) { + rc = oi->oi_orig->bi_entry_release_rw( op, e, rw ); + } + } + /* should not fall thru this far without anything happening... */ + if ( rc == SLAP_CB_CONTINUE ) { + entry_free( e ); + rc = 0; + } + + op->o_bd = be; + op->o_bd->bd_info = bi; + + return rc; +} + +static int +over_entry_release_rw( + Operation *op, + Entry *e, + int rw ) +{ + slap_overinfo *oi; + slap_overinst *on; + + assert( op->o_bd != NULL ); + + oi = op->o_bd->bd_info->bi_private; + on = oi->oi_list; + + return overlay_entry_release_ov( op, e, rw, on ); +} + static int over_acl_group( Operation *op, @@ -458,6 +599,27 @@ over_acl_attribute( return rc; } +int +overlay_callback_after_backover( Operation *op, slap_callback *sc, int append ) +{ + slap_callback **scp; + + for ( scp = &op->o_callback; *scp != NULL; scp = &(*scp)->sc_next ) { + if ( (*scp)->sc_response == over_back_response ) { + sc->sc_next = (*scp)->sc_next; + (*scp)->sc_next = sc; + return 0; + } + } + + if ( append ) { + *scp = sc; + return 0; + } + + return 1; +} + /* * default return code in case of missing backend function * and overlay stack returning SLAP_CB_CONTINUE @@ -903,7 +1065,7 @@ overlay_register_control( BackendDB *be, const char *oid ) /* add to all backends... */ LDAP_STAILQ_FOREACH( bd, &backendDB, be_next ) { - if ( be == bd ) { + if ( bd == be->bd_self ) { gotit = 1; } @@ -914,8 +1076,8 @@ overlay_register_control( BackendDB *be, const char *oid ) } if ( !gotit ) { - be->be_ctrls[ cid ] = 1; - be->be_ctrls[ SLAP_MAX_CIDS ] = 1; + be->bd_self->be_ctrls[ cid ] = 1; + be->bd_self->be_ctrls[ SLAP_MAX_CIDS ] = 1; } return 0; @@ -933,7 +1095,7 @@ overlay_destroy_one( BackendDB *be, slap_overinst *on ) if ( on->on_bi.bi_db_destroy ) { BackendInfo *bi_orig = be->bd_info; be->bd_info = (BackendInfo *)on; - on->on_bi.bi_db_destroy( be ); + on->on_bi.bi_db_destroy( be, NULL ); be->bd_info = bi_orig; } free( on ); @@ -942,6 +1104,44 @@ overlay_destroy_one( BackendDB *be, slap_overinst *on ) } } +#ifdef SLAP_CONFIG_DELETE +void +overlay_remove( BackendDB *be, slap_overinst *on ) +{ + slap_overinfo *oi = on->on_info; + slap_overinst **oidx; + BackendInfo *bi_orig; + + /* remove overlay from oi_list an call db_close and db_destroy + * handlers */ + for ( oidx = &oi->oi_list; *oidx; oidx = &(*oidx)->on_next ) { + if ( *oidx == on ) { + *oidx = on->on_next; + bi_orig = be->bd_info; + be->bd_info = (BackendInfo *)on; + if ( on->on_bi.bi_db_close ) { + on->on_bi.bi_db_close( be, NULL ); + } + if ( on->on_bi.bi_db_destroy ) { + on->on_bi.bi_db_destroy( be, NULL ); + } + be->bd_info = bi_orig; + free( on ); + break; + } + } + + /* clean up after removing last overlay */ + if ( ! oi->oi_list ) + { + /* reset db flags and bd_info to orig */ + SLAP_DBFLAGS( be ) &= ~SLAP_DBFLAG_GLOBAL_OVERLAY; + be->bd_info = oi->oi_orig; + ch_free(oi); + } +} +#endif /* SLAP_CONFIG_DELETE */ + void overlay_insert( BackendDB *be, slap_overinst *on2, slap_overinst ***prev, int idx ) @@ -1004,7 +1204,7 @@ overlay_move( BackendDB *be, slap_overinst *on, int idx ) /* add an overlay to a particular backend. */ int -overlay_config( BackendDB *be, const char *ov, int idx, BackendInfo **res ) +overlay_config( BackendDB *be, const char *ov, int idx, BackendInfo **res, ConfigReply *cr ) { slap_overinst *on = NULL, *on2 = NULL, **prev; slap_overinfo *oi = NULL; @@ -1090,6 +1290,8 @@ overlay_config( BackendDB *be, const char *ov, int idx, BackendInfo **res ) bi->bi_chk_controls = over_aux_chk_controls; /* these have specific arglists */ + bi->bi_entry_get_rw = over_entry_get_rw; + bi->bi_entry_release_rw = over_entry_release_rw; bi->bi_access_allowed = over_access_allowed; bi->bi_acl_group = over_acl_group; bi->bi_acl_attribute = over_acl_attribute; @@ -1101,10 +1303,10 @@ overlay_config( BackendDB *be, const char *ov, int idx, BackendInfo **res ) } else { if ( overlay_is_inst( be, ov ) ) { - Debug( LDAP_DEBUG_ANY, "overlay_config(): " - "overlay \"%s\" already in list\n", - ov, 0, 0 ); if ( SLAPO_SINGLE( be ) ) { + Debug( LDAP_DEBUG_ANY, "overlay_config(): " + "overlay \"%s\" already in list\n", + ov, 0, 0 ); return 1; } } @@ -1137,7 +1339,7 @@ overlay_config( BackendDB *be, const char *ov, int idx, BackendInfo **res ) if ( on2->on_bi.bi_db_init ) { int rc; be->bd_info = (BackendInfo *)on2; - rc = on2->on_bi.bi_db_init( be ); + rc = on2->on_bi.bi_db_init( be, cr); be->bd_info = (BackendInfo *)oi; if ( rc ) { *prev = on2->on_next;