X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fbackend.c;h=3256dd05f09e106feb7d0f70fb1bfcec29881ddb;hb=21be582df7e13ae2c8d44e1f7f02478eb9ec0762;hp=34d004d6629134dfc920a454d1d45d5c90423a63;hpb=9cb512bc03b55447e75ef81d537ad644a479feeb;p=openldap diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index 34d004d662..3256dd05f0 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-2005 The OpenLDAP Foundation. + * Copyright 1998-2006 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -196,7 +196,7 @@ int backend_startup_one(Backend *be) assert( be != NULL ); be->be_pending_csn_list = (struct be_pcl *) - ch_calloc( 1, sizeof( struct be_pcl )); + ch_calloc( 1, sizeof( struct be_pcl ) ); LDAP_TAILQ_INIT( be->be_pending_csn_list ); @@ -421,6 +421,24 @@ void backend_destroy_one( BackendDB *bd, int dynamic ) free( bd->be_rootpw.bv_val ); } acl_destroy( bd->be_acl, frontendDB->be_acl ); + limits_destroy( bd->be_limits ); + if ( bd->be_replogfile ) { + ch_free( bd->be_replogfile ); + } + if ( bd->be_replica_argsfile ) { + ch_free( bd->be_replica_argsfile ); + } + if ( bd->be_replica_pidfile ) { + ch_free( bd->be_replica_pidfile ); + } + destroy_replica_info( bd ); + if ( !BER_BVISNULL( &bd->be_update_ndn ) ) { + ch_free( bd->be_update_ndn.bv_val ); + } + if ( bd->be_update_refs ) { + ber_bvarray_free( bd->be_update_refs ); + } + if ( dynamic ) { free( bd ); } @@ -464,6 +482,17 @@ int backend_destroy(void) free( bd->be_rootpw.bv_val ); } acl_destroy( bd->be_acl, frontendDB->be_acl ); + + if ( bd->be_replogfile != NULL ) { + free( bd->be_replogfile ); + } + if ( bd->be_replica_argsfile ) { + ch_free( bd->be_replica_argsfile ); + } + if ( bd->be_replica_pidfile ) { + ch_free( bd->be_replica_pidfile ); + } + assert( bd->be_replica == NULL ); } return 0; @@ -486,9 +515,9 @@ BackendInfo* backend_info(const char *type) BackendDB * backend_db_init( - const char *type ) + const char *type, + BackendDB *be ) { - Backend *be; BackendInfo *bi = backend_info(type); int rc = 0; @@ -497,9 +526,14 @@ backend_db_init( return NULL; } - be = ch_calloc( 1, sizeof(Backend) ); - nbackends++; - LDAP_STAILQ_INSERT_TAIL(&backendDB, be, be_next); + /* If be is provided, treat it as private. Otherwise allocate + * one and add it to the global list. + */ + if ( !be ) { + be = ch_calloc( 1, sizeof(Backend) ); + nbackends++; + LDAP_STAILQ_INSERT_TAIL(&backendDB, be, be_next); + } be->bd_info = bi; @@ -597,7 +631,13 @@ select_backend( continue; } } else { - b2 = be; + /* If any parts of the tree are glued, use the first + * match regardless of manageDSAit. Otherwise use the + * last match. + */ + if( !( SLAP_DBFLAGS( be ) & ( SLAP_DBFLAG_GLUE_INSTANCE | + SLAP_DBFLAG_GLUE_SUBORDINATE ))) + b2 = be; } return b2; } @@ -820,11 +860,14 @@ backend_check_controls( } } + /* temporarily removed */ +#if 0 /* check should be generalized */ if( get_manageDIT(op) && !be_isroot(op)) { rs->sr_text = "requires manager authorization"; rs->sr_err = LDAP_UNWILLING_TO_PERFORM; } +#endif done:; return rs->sr_err; @@ -1166,19 +1209,17 @@ be_entry_get_rw( int rw, Entry **e ) { - int rc; - *e = NULL; - if (op->o_bd == NULL) { - rc = LDAP_NO_SUCH_OBJECT; - } else if ( op->o_bd->be_fetch ) { - rc = ( op->o_bd->be_fetch )( op, ndn, - oc, at, rw, e ); - } else { - rc = LDAP_UNWILLING_TO_PERFORM; + if ( op->o_bd == NULL ) { + return LDAP_NO_SUCH_OBJECT; } - return rc; + + if ( op->o_bd->be_fetch ) { + return op->o_bd->be_fetch( op, ndn, oc, at, rw, e ); + } + + return LDAP_UNWILLING_TO_PERFORM; } int @@ -1191,6 +1232,7 @@ fe_acl_group( AttributeDescription *group_at ) { Entry *e; + void *o_priv = op->o_private, *e_priv = NULL; Attribute *a; int rc; GroupAssertion *g; @@ -1218,7 +1260,10 @@ fe_acl_group( e = target; rc = 0; } else { + op->o_private = NULL; rc = be_entry_get_rw( op, gr_ndn, group_oc, group_at, 0, &e ); + e_priv = op->o_private; + op->o_private = o_priv; } if ( e ) { a = attr_find( e->e_attrs, group_at ); @@ -1234,13 +1279,17 @@ fe_acl_group( struct berval bv, nbase; Filter *filter; Entry *user; + void *user_priv = NULL; Backend *b2 = op->o_bd; if ( target && dn_match( &target->e_nname, op_ndn ) ) { user = target; } else { op->o_bd = select_backend( op_ndn, 0, 0 ); + op->o_private = NULL; rc = be_entry_get_rw(op, op_ndn, NULL, NULL, 0, &user ); + user_priv = op->o_private; + op->o_private = o_priv; } if ( rc == 0 ) { @@ -1282,14 +1331,12 @@ fe_acl_group( goto loopit; } break; -#ifdef LDAP_SCOPE_SUBORDINATE case LDAP_SCOPE_SUBORDINATE: if ( dn_match( &nbase, op_ndn ) || !dnIsSuffix( op_ndn, &nbase ) ) { goto loopit; } -#endif } filter = str2filter_x( op, ludp->lud_filter ); if ( filter ) { @@ -1308,7 +1355,9 @@ loopit: if ( rc == 0 ) break; } if ( user != target ) { + op->o_private = user_priv; be_entry_release_r( op, user ); + op->o_private = o_priv; } } op->o_bd = b2; @@ -1323,8 +1372,10 @@ loopit: } else { rc = LDAP_NO_SUCH_ATTRIBUTE; } - if (e != target ) { + if ( e != target ) { + op->o_private = e_priv; be_entry_release_r( op, e ); + op->o_private = o_priv; } } else { rc = LDAP_NO_SUCH_OBJECT; @@ -1365,8 +1416,13 @@ 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; @@ -1382,6 +1438,7 @@ fe_acl_attribute( slap_access_t access ) { Entry *e = NULL; + void *o_priv = op->o_private, *e_priv = NULL; Attribute *a = NULL; int freeattr = 0, i, j, rc = LDAP_SUCCESS; AccessControlState acl_state = ACL_STATE_INIT; @@ -1393,10 +1450,26 @@ fe_acl_attribute( e = target; } else { + op->o_private = NULL; rc = be_entry_get_rw( op, edn, NULL, entry_at, 0, &e ); + e_priv = op->o_private; + op->o_private = o_priv; } if ( e ) { + if ( entry_at == slap_schema.si_ad_entry || entry_at == slap_schema.si_ad_children ) { + assert( vals == NULL ); + + rc = LDAP_SUCCESS; + if ( op->o_conn && access > ACL_NONE && + access_allowed( op, e, entry_at, NULL, + access, &acl_state ) == 0 ) + { + rc = LDAP_INSUFFICIENT_ACCESS; + } + goto freeit; + } + a = attr_find( e->e_attrs, entry_at ); if ( a == NULL ) { SlapReply rs = { 0 }; @@ -1469,7 +1542,9 @@ fe_acl_attribute( } } freeit: if ( e != target ) { + op->o_private = e_priv; be_entry_release_r( op, e ); + op->o_private = o_priv; } if ( freeattr ) { attr_free( a ); @@ -1494,8 +1569,13 @@ 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; @@ -1512,6 +1592,7 @@ backend_access( slap_mask_t *mask ) { Entry *e = NULL; + void *o_priv = op->o_private, *e_priv = NULL; int rc = LDAP_INSUFFICIENT_ACCESS; Backend *be = op->o_bd; @@ -1527,7 +1608,10 @@ backend_access( e = target; } else { + op->o_private = NULL; rc = be_entry_get_rw( op, edn, NULL, entry_at, 0, &e ); + e_priv = op->o_private; + op->o_private = o_priv; } if ( e ) { @@ -1591,7 +1675,9 @@ backend_access( } } freeit: if ( e != target ) { + op->o_private = e_priv; be_entry_release_r( op, e ); + op->o_private = o_priv; } if ( freeattr ) { attr_free( a ); @@ -1633,15 +1719,14 @@ fe_aux_operational( ap = &(*ap)->a_next; } - if ( op->o_bd != NULL && op->o_bd != frontendDB ) + if ( op->o_bd != NULL ) { /* Let the overlays have a chance at this */ be_orig = op->o_bd; - if ( SLAP_ISOVERLAY( be_orig ) ) - op->o_bd = select_backend( be_orig->be_nsuffix, 0, 0 ); - - if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || rs->sr_attrs ) && - op->o_bd && op->o_bd->be_operational != NULL ) + op->o_bd = select_backend( &op->o_req_ndn, 0, 0 ); + if ( !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 ) { rc = op->o_bd->be_operational( op, rs ); }