X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fbackend.c;h=7e0dbce7d99f9a6648ecc5c486afdb40fd6ea947;hb=e841247c9086053d774d66e4fbb058d0ead706b2;hp=3eb2a679d4bfeefa6dc3a3371d9dcef9968b8be1;hpb=d2179d885ff588df4f73ee27ae363df9a493b9f3;p=openldap diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index 3eb2a679d4..7e0dbce7d9 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-2007 The OpenLDAP Foundation. + * Copyright 1998-2009 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -261,15 +261,13 @@ 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, &cr ); } /* open frontend, if required */ if ( frontendDB->bd_info->bi_db_open ) { - rc = frontendDB->bd_info->bi_db_open( frontendDB, NULL ); + rc = frontendDB->bd_info->bi_db_open( frontendDB, &cr ); if ( rc != 0 ) { Debug( LDAP_DEBUG_ANY, "backend_startup: bi_db_open(frontend) failed! (%d)\n", @@ -310,8 +308,6 @@ int backend_startup(Backend *be) "has no suffix\n", i, be->bd_info->bi_type, 0 ); } - /* append global access controls */ - acl_append( &be->be_acl, frontendDB->be_acl, -1 ); rc = backend_startup_one( be, &cr ); @@ -349,11 +345,13 @@ int backend_shutdown( Backend *be ) } if ( be->bd_info->bi_db_close ) { - be->bd_info->bi_db_close( be, NULL ); + rc = be->bd_info->bi_db_close( be, NULL ); + if ( rc ) return rc; } if( be->bd_info->bi_close ) { - be->bd_info->bi_close( be->bd_info ); + rc = be->bd_info->bi_close( be->bd_info ); + if ( rc ) return rc; } return 0; @@ -451,7 +449,7 @@ void backend_destroy_one( BackendDB *bd, int dynamic ) if ( !BER_BVISNULL( &bd->be_rootpw ) ) { free( bd->be_rootpw.bv_val ); } - acl_destroy( bd->be_acl, frontendDB->be_acl ); + acl_destroy( bd->be_acl ); limits_destroy( bd->be_limits ); if ( !BER_BVISNULL( &bd->be_update_ndn ) ) { ch_free( bd->be_update_ndn.bv_val ); @@ -502,7 +500,8 @@ int backend_destroy(void) if ( !BER_BVISNULL( &bd->be_rootpw ) ) { free( bd->be_rootpw.bv_val ); } - acl_destroy( bd->be_acl, frontendDB->be_acl ); + acl_destroy( bd->be_acl ); + frontendDB = NULL; } return 0; @@ -585,6 +584,7 @@ backend_db_init( } be->bd_info = bi; + be->bd_self = be; be->be_def_limit = frontendDB->be_def_limit; be->be_dfltaccess = frontendDB->be_dfltaccess; @@ -593,8 +593,7 @@ backend_db_init( be->be_requires = frontendDB->be_requires; be->be_ssf_set = frontendDB->be_ssf_set; - be->be_pcl_mutexp = &be->be_pcl_mutex; - ldap_pvt_thread_mutex_init( be->be_pcl_mutexp ); + ldap_pvt_thread_mutex_init( &be->be_pcl_mutex ); /* assign a default depth limit for alias deref */ be->be_max_deref_depth = SLAPD_DEFAULT_MAXDEREFDEPTH; @@ -613,6 +612,9 @@ backend_db_init( nbackends--; } } else { + if ( !bi->bi_nDB ) { + backend_init_controls( bi ); + } bi->bi_nDB++; } return( be ); @@ -783,7 +785,7 @@ be_isroot_pw( Operation *op ) * checks if binding as rootdn * * return value: - * SLAP_CB_CONTINUE if not the rootdn + * SLAP_CB_CONTINUE if not the rootdn, or if rootpw is null * LDAP_SUCCESS if rootdn & rootpw * LDAP_INVALID_CREDENTIALS if rootdn & !rootpw * @@ -795,6 +797,9 @@ int be_rootdn_bind( Operation *op, SlapReply *rs ) { int rc; +#ifdef SLAPD_SPASSWD + void *old_authctx = NULL; +#endif assert( op->o_tag == LDAP_REQ_BIND ); assert( op->orb_method == LDAP_AUTH_SIMPLE ); @@ -819,14 +824,15 @@ be_rootdn_bind( Operation *op, SlapReply *rs ) } #ifdef SLAPD_SPASSWD - ldap_pvt_thread_pool_setkey( op->o_threadctx, slap_sasl_bind, - op->o_conn->c_sasl_authctx, NULL ); + ldap_pvt_thread_pool_setkey( op->o_threadctx, (void *)slap_sasl_bind, + op->o_conn->c_sasl_authctx, 0, &old_authctx, NULL ); #endif rc = lutil_passwd( &op->o_bd->be_rootpw, &op->orb_cred, NULL, NULL ); #ifdef SLAPD_SPASSWD - ldap_pvt_thread_pool_setkey( op->o_threadctx, slap_sasl_bind, NULL, NULL ); + ldap_pvt_thread_pool_setkey( op->o_threadctx, (void *)slap_sasl_bind, + old_authctx, 0, NULL, NULL ); #endif rc = ( rc == 0 ? LDAP_SUCCESS : LDAP_INVALID_CREDENTIALS ); @@ -941,6 +947,14 @@ backend_check_controls( case LDAP_COMPARE_FALSE: if ( !op->o_bd->be_ctrls[cid] && (*ctrls)->ldctl_iscritical ) { +#ifdef SLAP_CONTROL_X_WHATFAILED + if ( get_whatFailed( op ) ) { + char *oids[ 2 ]; + oids[ 0 ] = (*ctrls)->ldctl_oid; + oids[ 1 ] = NULL; + slap_ctrl_whatFailed_add( op, rs, oids ); + } +#endif /* RFC 4511 allows unavailableCriticalExtension to be * returned when the server is unwilling to perform * an operation extended by a recognized critical @@ -991,13 +1005,19 @@ backend_check_restrictions( slap_mask_t requires; slap_mask_t opflag; slap_mask_t exopflag = 0; - slap_ssf_set_t *ssf; + slap_ssf_set_t ssfs, *ssf; int updateop = 0; int starttls = 0; int session = 0; + restrictops = frontendDB->be_restrictops; + requires = frontendDB->be_requires; + ssfs = frontendDB->be_ssf_set; + ssf = &ssfs; + if ( op->o_bd ) { - int rc = SLAP_CB_CONTINUE; + slap_ssf_t *fssf, *bssf; + int rc = SLAP_CB_CONTINUE, i; if ( op->o_bd->be_chk_controls ) { rc = ( *op->o_bd->be_chk_controls )( op, rs ); @@ -1011,14 +1031,13 @@ backend_check_restrictions( return rs->sr_err; } - restrictops = op->o_bd->be_restrictops; - requires = op->o_bd->be_requires; - ssf = &op->o_bd->be_ssf_set; - - } else { - restrictops = frontendDB->be_restrictops; - requires = frontendDB->be_requires; - ssf = &frontendDB->be_ssf_set; + restrictops |= op->o_bd->be_restrictops; + requires |= op->o_bd->be_requires; + bssf = &op->o_bd->be_ssf_set.sss_ssf; + fssf = &ssfs.sss_ssf; + for ( i=0; io_tag ) { @@ -1345,8 +1364,18 @@ fe_acl_group( int rc; GroupAssertion *g; Backend *be = op->o_bd; + OpExtra *oex; + + LDAP_SLIST_FOREACH(oex, &op->o_extra, oe_next) { + if ( oex->oe_key == (void *)backend_group ) + break; + } + + if ( oex && ((OpExtraDB *)oex)->oe_db ) + op->o_bd = ((OpExtraDB *)oex)->oe_db; - op->o_bd = select_backend( gr_ndn, 0 ); + if ( !op->o_bd || !SLAP_DBHIDDEN( op->o_bd )) + op->o_bd = select_backend( gr_ndn, 0 ); for ( g = op->o_groups; g; g = g->ga_next ) { if ( g->ga_be != op->o_bd || g->ga_oc != group_oc || @@ -1481,7 +1510,7 @@ fe_acl_group( { rc = 0; } - filter_free_x( op, filter ); + filter_free_x( op, filter, 1 ); } loopit: ldap_free_urldesc( ludp ); @@ -1552,17 +1581,23 @@ backend_group( AttributeDescription *group_at ) { int rc; - BackendDB *be_orig; + BackendDB *be_orig; + OpExtraDB oex; if ( op->o_abandon ) { return SLAPD_ABANDON; } + oex.oe_db = op->o_bd; + oex.oe.oe_key = (void *)backend_group; + LDAP_SLIST_INSERT_HEAD(&op->o_extra, &oex.oe, oe_next); + be_orig = op->o_bd; op->o_bd = frontendDB; rc = frontendDB->be_group( op, target, gr_ndn, op_ndn, group_oc, group_at ); op->o_bd = be_orig; + LDAP_SLIST_REMOVE(&op->o_extra, &oex.oe, OpExtra, oe_next); return rc; } @@ -1582,8 +1617,18 @@ fe_acl_attribute( int freeattr = 0, i, j, rc = LDAP_SUCCESS; AccessControlState acl_state = ACL_STATE_INIT; Backend *be = op->o_bd; + OpExtra *oex; - op->o_bd = select_backend( edn, 0 ); + LDAP_SLIST_FOREACH(oex, &op->o_extra, oe_next) { + if ( oex->oe_key == (void *)backend_attribute ) + break; + } + + if ( oex && ((OpExtraDB *)oex)->oe_db ) + op->o_bd = ((OpExtraDB *)oex)->oe_db; + + if ( !op->o_bd || !SLAP_DBHIDDEN( op->o_bd )) + op->o_bd = select_backend( edn, 0 ); if ( target && dn_match( &target->e_nname, edn ) ) { e = target; @@ -1702,13 +1747,19 @@ backend_attribute( slap_access_t access ) { int rc; - BackendDB *be_orig; + BackendDB *be_orig; + OpExtraDB oex; + + oex.oe_db = op->o_bd; + oex.oe.oe_key = (void *)backend_attribute; + LDAP_SLIST_INSERT_HEAD(&op->o_extra, &oex.oe, oe_next); be_orig = op->o_bd; op->o_bd = frontendDB; rc = frontendDB->be_attribute( op, target, edn, entry_at, vals, access ); op->o_bd = be_orig; + LDAP_SLIST_REMOVE(&op->o_extra, &oex.oe, OpExtra, oe_next); return rc; } @@ -1734,7 +1785,9 @@ backend_access( assert( edn != NULL ); assert( access > ACL_NONE ); - op->o_bd = select_backend( edn, 0 ); + if ( !op->o_bd ) { + op->o_bd = select_backend( edn, 0 ); + } if ( target && dn_match( &target->e_nname, edn ) ) { e = target; @@ -1826,7 +1879,14 @@ fe_aux_operational( SlapReply *rs ) { Attribute **ap; - int rc = 0; + int rc = LDAP_SUCCESS; + BackendDB *be_orig = op->o_bd; + OpExtra *oex; + + LDAP_SLIST_FOREACH(oex, &op->o_extra, oe_next) { + if ( oex->oe_key == (void *)backend_operational ) + break; + } for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) /* just count them */ ; @@ -1852,19 +1912,20 @@ fe_aux_operational( ap = &(*ap)->a_next; } - if ( op->o_bd != NULL ) { - BackendDB *be_orig = op->o_bd; + /* Let the overlays have a chance at this */ + if ( oex && ((OpExtraDB *)oex)->oe_db ) + op->o_bd = ((OpExtraDB *)oex)->oe_db; - /* Let the overlays have a chance at this */ + if ( !op->o_bd || !SLAP_DBHIDDEN( op->o_bd )) op->o_bd = select_backend( &op->o_req_ndn, 0 ); - if ( op->o_bd != NULL && !be_match( op->o_bd, frontendDB ) && - ( SLAP_OPATTRS( rs->sr_attr_flags ) || rs->sr_attrs ) && - op->o_bd->be_operational != NULL ) - { - rc = op->o_bd->be_operational( op, rs ); - } - op->o_bd = be_orig; + + if ( op->o_bd != NULL && !be_match( op->o_bd, frontendDB ) && + ( SLAP_OPATTRS( rs->sr_attr_flags ) || rs->sr_attrs ) && + op->o_bd->be_operational != NULL ) + { + rc = op->o_bd->be_operational( op, rs ); } + op->o_bd = be_orig; return rc; } @@ -1873,6 +1934,11 @@ int backend_operational( Operation *op, SlapReply *rs ) { int rc; BackendDB *be_orig; + OpExtraDB oex; + + oex.oe_db = op->o_bd; + oex.oe.oe_key = (void *)backend_operational; + LDAP_SLIST_INSERT_HEAD(&op->o_extra, &oex.oe, oe_next); /* Moved this into the frontend so global overlays are called */ @@ -1880,6 +1946,7 @@ int backend_operational( Operation *op, SlapReply *rs ) op->o_bd = frontendDB; rc = frontendDB->be_operational( op, rs ); op->o_bd = be_orig; + LDAP_SLIST_REMOVE(&op->o_extra, &oex.oe, OpExtra, oe_next); return rc; }