X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fbackend.c;h=3233f65e8fe44a12493a5c08a3ae6b1c38efca6f;hb=b60644a07fc620d8e1f367e828355e6babc8d44f;hp=3256dd05f09e106feb7d0f70fb1bfcec29881ddb;hpb=f9a104bf4ddd1825f7b40f8691d185a72fe9bbc7;p=openldap diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index 3256dd05f0..3233f65e8f 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -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 ) ) ); } @@ -818,27 +882,26 @@ backend_check_controls( /* unrecognized control */ if ( (*ctrls)->ldctl_iscritical ) { /* should not be reachable */ - Debug( LDAP_DEBUG_ANY, - "backend_check_controls: unrecognized control: %s\n", + Debug( LDAP_DEBUG_ANY, "backend_check_controls: " + "unrecognized critical control: %s\n", (*ctrls)->ldctl_oid, 0, 0 ); assert( 0 ); + } else { + Debug( LDAP_DEBUG_TRACE, "backend_check_controls: " + "unrecognized non-critical control: %s\n", + (*ctrls)->ldctl_oid, 0, 0 ); } break; 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; @@ -860,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; } @@ -1416,13 +1478,8 @@ backend_group( be_orig = op->o_bd; op->o_bd = frontendDB; -#ifdef SLAP_OVERLAY_ACCESS rc = frontendDB->be_group( op, target, gr_ndn, op_ndn, group_oc, group_at ); -#else /* ! SLAP_OVERLAY_ACCESS */ - rc = fe_acl_group( op, target, gr_ndn, - op_ndn, group_oc, group_at ); -#endif /* ! SLAP_OVERLAY_ACCESS */ op->o_bd = be_orig; return rc; @@ -1569,13 +1626,8 @@ backend_attribute( be_orig = op->o_bd; op->o_bd = frontendDB; -#ifdef SLAP_OVERLAY_ACCESS rc = frontendDB->be_attribute( op, target, edn, entry_at, vals, access ); -#else /* !SLAP_OVERLAY_ACCESS */ - rc = fe_acl_attribute( op, target, edn, - entry_at, vals, access ); -#endif /* !SLAP_OVERLAY_ACCESS */ op->o_bd = be_orig; return rc; @@ -1695,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 */ ; @@ -1705,28 +1756,30 @@ fe_aux_operational( * and the backend supports specific operational attributes, * add them to the attribute list */ - if ( SLAP_OPATTRS( rs->sr_attr_flags ) || ( rs->sr_attrs && - ad_inlist( slap_schema.si_ad_entryDN, rs->sr_attrs ) ) ) + if ( !( rs->sr_flags & REP_NO_ENTRYDN ) + && ( SLAP_OPATTRS( rs->sr_attr_flags ) || ( rs->sr_attrs && + ad_inlist( slap_schema.si_ad_entryDN, rs->sr_attrs ) ) ) ) { *ap = slap_operational_entryDN( rs->sr_entry ); ap = &(*ap)->a_next; } - if ( SLAP_OPATTRS( rs->sr_attr_flags ) || ( rs->sr_attrs && - ad_inlist( slap_schema.si_ad_subschemaSubentry, rs->sr_attrs ) ) ) + if ( !( rs->sr_flags & REP_NO_SUBSCHEMA) + && ( SLAP_OPATTRS( rs->sr_attr_flags ) || ( rs->sr_attrs && + ad_inlist( slap_schema.si_ad_subschemaSubentry, rs->sr_attrs ) ) ) ) { *ap = slap_operational_subschemaSubentry( op->o_bd ); 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 ); }