X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=servers%2Fslapd%2Fbackend.c;h=1cd5a622231256f63194687d30ee82c501e1cc6e;hb=fb2e448e877a8a387084dde517362c9f7bf1b6b7;hp=f054e506779869b28d4dff99642f0e24174e7102;hpb=eb9a3c18767fe87d2a1f7fbbc6b3d676779eb5b7;p=openldap diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index f054e50677..1cd5a62223 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2006 The OpenLDAP Foundation. + * Copyright 1998-2007 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -248,6 +248,8 @@ int backend_startup(Backend *be) return rc; } } + /* append global access controls */ + acl_append( &be->be_acl, frontendDB->be_acl, -1 ); return backend_startup_one( be ); } @@ -382,16 +384,18 @@ int backend_shutdown( Backend *be ) return 0; } -void backend_destroy_one( BackendDB *bd, int dynamic ) +/* + * This function is supposed to be the exact counterpart + * of backend_startup_one(), although this one calls bi_db_destroy() + * while backend_startup_one() calls bi_db_open(). + * + * Make sure backend_stopdown_one() destroys resources allocated + * by backend_startup_one(); only call backend_destroy_one() when + * all stuff in a BackendDB needs to be destroyed + */ +void +backend_stopdown_one( BackendDB *bd ) { - if ( dynamic ) { - LDAP_STAILQ_REMOVE(&backendDB, bd, slap_backend_db, be_next ); - } - - if ( bd->be_syncinfo ) { - syncinfo_free( bd->be_syncinfo ); - } - if ( bd->be_pending_csn_list ) { struct slap_csn_entry *csne; csne = LDAP_TAILQ_FIRST( bd->be_pending_csn_list ); @@ -409,6 +413,20 @@ void backend_destroy_one( BackendDB *bd, int dynamic ) if ( bd->bd_info->bi_db_destroy ) { bd->bd_info->bi_db_destroy( bd ); } +} + +void backend_destroy_one( BackendDB *bd, int dynamic ) +{ + if ( dynamic ) { + LDAP_STAILQ_REMOVE(&backendDB, bd, slap_backend_db, be_next ); + } + + if ( bd->be_syncinfo ) { + syncinfo_free( bd->be_syncinfo ); + } + + backend_stopdown_one( bd ); + ber_bvarray_free( bd->be_suffix ); ber_bvarray_free( bd->be_nsuffix ); if ( !BER_BVISNULL( &bd->be_rootdn ) ) { @@ -512,13 +530,48 @@ BackendInfo* backend_info(const char *type) return NULL; } +void +backend_db_insert( + BackendDB *be, + int idx +) +{ + /* If idx < 0, just add to end of list */ + if ( idx < 0 ) { + LDAP_STAILQ_INSERT_TAIL(&backendDB, be, be_next); + } else if ( idx == 0 ) { + LDAP_STAILQ_INSERT_HEAD(&backendDB, be, be_next); + } else { + int i; + BackendDB *b2; + + b2 = LDAP_STAILQ_FIRST(&backendDB); + idx--; + for (i=0; i= nbackends ) + idx = -1; nbackends++; - LDAP_STAILQ_INSERT_TAIL(&backendDB, be, be_next); + backend_db_insert( be, idx ); } be->bd_info = bi; @@ -556,11 +612,16 @@ backend_db_init( if ( rc != 0 ) { fprintf( stderr, "database init failed (%s)\n", type ); - nbackends--; - return NULL; + /* If we created and linked this be, remove it and free it */ + if ( !b0 ) { + LDAP_STAILQ_REMOVE(&backendDB, be, slap_backend_db, be_next); + ch_free( be ); + be = NULL; + nbackends--; + } + } else { + bi->bi_nDB++; } - - bi->bi_nDB++; return( be ); } @@ -576,7 +637,7 @@ be_db_close( void ) } if ( frontendDB->bd_info->bi_db_close ) { - (*frontendDB->bd_info->bi_db_close)( frontendDB ); + frontendDB->bd_info->bi_db_close( frontendDB ); } } @@ -592,7 +653,7 @@ select_backend( Backend *be, *b2 = NULL; LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) { - if ( be->be_nsuffix == NULL ) { + if ( be->be_nsuffix == NULL || SLAP_DBHIDDEN( be )) { continue; } @@ -687,7 +748,10 @@ be_slurp_update( Operation *op ) int be_shadow_update( Operation *op ) { - return ( SLAP_SYNC_SHADOW( op->o_bd ) || + /* This assumes that all internal ops (connid == -1) on a syncrepl + * database are syncrepl operations. + */ + return (( SLAP_SYNC_SHADOW( op->o_bd ) && op->o_connid == -1 ) || ( SLAP_SHADOW( op->o_bd ) && be_isupdate_dn( op->o_bd, &op->o_ndn ) ) ); } @@ -831,18 +895,13 @@ backend_check_controls( case LDAP_COMPARE_FALSE: if ( !op->o_bd->be_ctrls[cid] && (*ctrls)->ldctl_iscritical ) { - /* Per RFC 2251 (and LDAPBIS discussions), if the control - * is recognized and appropriate for the operation (which - * we've already verified), then the server should make - * use of the control when performing the operation. - * - * Here we find that operation extended by the control - * is unavailable in a particular context, and the control - * is marked Critical, hence the return of - * unwillingToPerform. + /* RFC 4511 allows unavailableCriticalExtension to be + * returned when the server is unwilling to perform + * an operation extended by a recognized critical + * control. */ rs->sr_text = "critical control unavailable in context"; - rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + rs->sr_err = LDAP_UNAVAILABLE_CRITICAL_EXTENSION; goto done; } break; @@ -864,10 +923,9 @@ backend_check_controls( } } - /* temporarily removed */ -#if 0 +#if 0 /* temporarily removed */ /* check should be generalized */ - if( get_manageDIT(op) && !be_isroot(op)) { + if( get_relax(op) && !be_isroot(op)) { rs->sr_text = "requires manager authorization"; rs->sr_err = LDAP_UNWILLING_TO_PERFORM; } @@ -1689,7 +1747,6 @@ fe_aux_operational( { Attribute **ap; int rc = 0; - BackendDB *be_orig; for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) /* just count them */ ; @@ -1715,14 +1772,14 @@ fe_aux_operational( ap = &(*ap)->a_next; } - if ( op->o_bd != NULL ) - { + if ( op->o_bd != NULL ) { + BackendDB *be_orig = op->o_bd; + /* Let the overlays have a chance at this */ - be_orig = op->o_bd; op->o_bd = select_backend( &op->o_req_ndn, 0, 0 ); - if ( !be_match( op->o_bd, frontendDB ) && + if ( op->o_bd != NULL && !be_match( op->o_bd, frontendDB ) && ( SLAP_OPATTRS( rs->sr_attr_flags ) || rs->sr_attrs ) && - op->o_bd != NULL && op->o_bd->be_operational != NULL ) + op->o_bd->be_operational != NULL ) { rc = op->o_bd->be_operational( op, rs ); }