X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fbackend.c;h=a9462bb7406ce40585d235c69b599e5a92b03d54;hb=b0b3eff457f0e431c4fd094d3d9cfeb6383df91d;hp=03d14efa520008ad44552f5b68e1f00543d94a2d;hpb=86a46c267a5279794c1ac858a53a8033d55b7274;p=openldap diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index 03d14efa52..a9462bb740 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -1,9 +1,28 @@ +/* backend.c - routines for dealing with back-end databases */ /* $OpenLDAP$ */ -/* - * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2003 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* Portions Copyright (c) 1995 Regents of the University of Michigan. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. */ -/* backend.c - routines for dealing with back-end databases */ #include "portable.h" @@ -18,6 +37,8 @@ #include "lutil.h" #include "lber_pvt.h" +#include "ldap_rq.h" + #ifdef LDAP_SLAPI #include "slapi.h" #endif @@ -36,6 +57,9 @@ #if defined(SLAPD_DNSSRV) && !defined(SLAPD_DNSSRV_DYNAMIC) #include "back-dnssrv/external.h" #endif +#if defined(SLAPD_HDB) && !defined(SLAPD_HDB_DYNAMIC) +#include "back-hdb/external.h" +#endif #if defined(SLAPD_LDAP) && !defined(SLAPD_LDAP_DYNAMIC) #include "back-ldap/external.h" #endif @@ -77,6 +101,9 @@ static BackendInfo binfo[] = { #if defined(SLAPD_DNSSRV) && !defined(SLAPD_DNSSRV_DYNAMIC) {"dnssrv", dnssrv_back_initialize}, #endif +#if defined(SLAPD_HDB) && !defined(SLAPD_HDB_DYNAMIC) + {"hdb", hdb_initialize}, +#endif #if defined(SLAPD_LDAP) && !defined(SLAPD_LDAP_DYNAMIC) {"ldap", ldap_back_initialize}, #endif @@ -120,18 +147,14 @@ BackendInfo *backendInfo = NULL; int nBackendDB = 0; BackendDB *backendDB = NULL; -#ifdef LDAP_SYNCREPL ldap_pvt_thread_pool_t syncrepl_pool; int syncrepl_pool_max = SLAP_MAX_SYNCREPL_THREADS; -#endif int backend_init(void) { int rc = -1; -#ifdef LDAP_SYNCREPL - ldap_pvt_thread_pool_init( &syncrepl_pool, syncrepl_pool_max, 0 ); -#endif + ldap_pvt_thread_pool_init( &syncrepl_pool, syncrepl_pool_max, 0 ); if((nBackendInfo != 0) || (backendInfo != NULL)) { /* already initialized */ @@ -240,10 +263,6 @@ int backend_startup(Backend *be) int i; int rc = 0; -#ifdef LDAP_SYNCREPL - init_syncrepl(); -#endif - if( ! ( nBackendDB > 0 ) ) { /* no databases */ #ifdef NEW_LOGGING @@ -259,6 +278,9 @@ int backend_startup(Backend *be) if(be != NULL) { /* startup a specific backend database */ + + LDAP_TAILQ_INIT( &be->be_pending_csn_list ); + #ifdef NEW_LOGGING LDAP_LOG( BACKEND, DETAIL1, "backend_startup: starting \"%s\"\n", be->be_suffix[0].bv_val, 0, 0 ); @@ -325,11 +347,17 @@ int backend_startup(Backend *be) } } + ldap_pvt_thread_mutex_init( &syncrepl_rq.rq_mutex ); + LDAP_STAILQ_INIT( &syncrepl_rq.task_list ); + LDAP_STAILQ_INIT( &syncrepl_rq.run_list ); + /* open each backend database */ for( i = 0; i < nBackendDB; i++ ) { /* append global access controls */ acl_append( &backendDB[i].be_acl, global_acl ); + LDAP_TAILQ_INIT( &backendDB[i].be_pending_csn_list ); + if ( backendDB[i].bd_info->bi_db_open ) { rc = backendDB[i].bd_info->bi_db_open( &backendDB[i] ); @@ -346,24 +374,17 @@ int backend_startup(Backend *be) } } -#ifdef LDAP_SYNCREPL - if ( backendDB[i].syncinfo != NULL ) { - int ret; - ret = ldap_pvt_thread_pool_submit( &syncrepl_pool, - do_syncrepl, (void *) &backendDB[i] ); - if ( ret != 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, CRIT, - "syncrepl thread pool submit failed (%d)\n", - ret, 0, 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "ldap_pvt_thread_pool_submit failed (%d) \n", - ret, 0, 0 ); -#endif + if ( !LDAP_STAILQ_EMPTY( &backendDB[i].be_syncinfo )) { + syncinfo_t *si; + LDAP_STAILQ_FOREACH( si, &backendDB[i].be_syncinfo, si_next ) { + si->si_be = &backendDB[i]; + init_syncrepl( si ); + ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex ); + ldap_pvt_runqueue_insert( &syncrepl_rq, + si->si_interval, do_syncrepl, (void *) si ); + ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex ); } } -#endif } return rc; @@ -446,9 +467,7 @@ int backend_destroy(void) int i; BackendDB *bd; -#ifdef LDAP_SYNCREPL - ldap_pvt_thread_pool_destroy( &syncrepl_pool, 1 ); -#endif + ldap_pvt_thread_pool_destroy( &syncrepl_pool, 1 ); /* destroy each backend database */ for( i = 0, bd = backendDB; i < nBackendDB; i++, bd++ ) { @@ -529,9 +548,12 @@ backend_db_init( be->be_requires = global_requires; be->be_ssf_set = global_ssf_set; -#ifdef LDAP_SYNCREPL - be->syncinfo = NULL; -#endif + be->be_context_csn.bv_len = 0; + be->be_context_csn.bv_val = NULL; + ldap_pvt_thread_mutex_init( &be->be_pcl_mutex ); + ldap_pvt_thread_mutex_init( &be->be_context_csn_mutex ); + + LDAP_STAILQ_INIT( &be->be_syncinfo ); /* assign a default depth limit for alias deref */ be->be_max_deref_depth = SLAPD_DEFAULT_MAXDEREFDEPTH; @@ -605,7 +627,8 @@ select_backend( if( be == NULL ) { be = &backends[i]; - if( manageDSAit && len == dnlen ) { + if( manageDSAit && len == dnlen && + !SLAP_GLUE_SUBORDINATE( be ) ) { continue; } } else { @@ -674,6 +697,7 @@ int be_isroot_pw( Operation *op ) { int result; + char *errmsg; if ( ! be_isroot( op->o_bd, &op->o_req_ndn ) ) { return 0; @@ -686,11 +710,11 @@ be_isroot_pw( Operation *op ) #if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD ) ldap_pvt_thread_mutex_lock( &passwd_mutex ); #ifdef SLAPD_SPASSWD - lutil_passwd_sasl_conn = op->o_conn->c_sasl_context; + lutil_passwd_sasl_conn = op->o_conn->c_sasl_authctx; #endif #endif - result = lutil_passwd( &op->o_bd->be_rootpw, &op->orb_cred, NULL ); + result = lutil_passwd( &op->o_bd->be_rootpw, &op->orb_cred, NULL, NULL ); #if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD ) #ifdef SLAPD_SPASSWD @@ -722,31 +746,29 @@ int backend_unbind( Operation *op, SlapReply *rs ) { int i; -#if defined( LDAP_SLAPI ) - Slapi_PBlock *pb = op->o_pb; - - int rc; - slapi_x_pblock_set_operation( pb, op ); -#endif /* defined( LDAP_SLAPI ) */ for ( i = 0; i < nbackends; i++ ) { #if defined( LDAP_SLAPI ) - slapi_pblock_set( pb, SLAPI_BACKEND, (void *)&backends[i] ); - rc = doPluginFNs( &backends[i], SLAPI_PLUGIN_PRE_UNBIND_FN, - (Slapi_PBlock *)pb ); - if ( rc < 0 ) { - /* - * A preoperation plugin failure will abort the - * entire operation. - */ + if ( op->o_pb ) { + int rc; + if ( i == 0 ) slapi_x_pblock_set_operation( op->o_pb, op ); + slapi_pblock_set( op->o_pb, SLAPI_BACKEND, (void *)&backends[i] ); + rc = doPluginFNs( &backends[i], SLAPI_PLUGIN_PRE_UNBIND_FN, + (Slapi_PBlock *)op->o_pb ); + if ( rc < 0 ) { + /* + * A preoperation plugin failure will abort the + * entire operation. + */ #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, INFO, "do_bind: Unbind preoperation plugin " - "failed\n", 0, 0, 0); + LDAP_LOG( OPERATION, INFO, "do_bind: Unbind preoperation plugin " + "failed\n", 0, 0, 0); #else - Debug(LDAP_DEBUG_TRACE, "do_bind: Unbind preoperation plugin " - "failed.\n", 0, 0, 0); + Debug(LDAP_DEBUG_TRACE, "do_bind: Unbind preoperation plugin " + "failed.\n", 0, 0, 0); #endif - return 0; + return 0; + } } #endif /* defined( LDAP_SLAPI ) */ @@ -756,8 +778,8 @@ backend_unbind( Operation *op, SlapReply *rs ) } #if defined( LDAP_SLAPI ) - if ( doPluginFNs( &backends[i], SLAPI_PLUGIN_POST_UNBIND_FN, - (Slapi_PBlock *)pb ) < 0 ) { + if ( op->o_pb && doPluginFNs( &backends[i], SLAPI_PLUGIN_POST_UNBIND_FN, + (Slapi_PBlock *)op->o_pb ) < 0 ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, INFO, "do_unbind: Unbind postoperation plugins " "failed\n", 0, 0, 0); @@ -814,8 +836,8 @@ backend_check_controls( if( ctrls ) { for( ; *ctrls != NULL ; ctrls++ ) { - if( (*ctrls)->ldctl_iscritical && - !ldap_charray_inlist( op->o_bd->be_controls, (*ctrls)->ldctl_oid ) ) + if( (*ctrls)->ldctl_iscritical && !ldap_charray_inlist( + op->o_bd->be_controls, (*ctrls)->ldctl_oid ) ) { rs->sr_text = "control unavailable in context"; rs->sr_err = LDAP_UNAVAILABLE_CRITICAL_EXTENSION; @@ -1120,13 +1142,10 @@ be_entry_get_rw( int rw, Entry **e ) { - Backend *be = op->o_bd; int rc; *e = NULL; - op->o_bd = select_backend( ndn, 0, 0 ); - if (op->o_bd == NULL) { rc = LDAP_NO_SUCH_OBJECT; } else if ( op->o_bd->be_fetch ) { @@ -1135,7 +1154,6 @@ be_entry_get_rw( } else { rc = LDAP_UNWILLING_TO_PERFORM; } - op->o_bd = be; return rc; } @@ -1153,12 +1171,13 @@ backend_group( Attribute *a; int rc; GroupAssertion *g; + Backend *be = op->o_bd; if ( op->o_abandon ) return SLAPD_ABANDON; - ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); + op->o_bd = select_backend( gr_ndn, 0, 0 ); - for (g = op->o_conn->c_groups; g; g=g->ga_next) { + for (g = op->o_groups; g; g=g->ga_next) { if (g->ga_be != op->o_bd || g->ga_oc != group_oc || g->ga_at != group_at || g->ga_len != gr_ndn->bv_len) continue; @@ -1166,24 +1185,90 @@ backend_group( break; } - ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); - if (g) { - return g->ga_res; + rc = g->ga_res; + goto done; } if ( target && dn_match( &target->e_nname, gr_ndn ) ) { e = target; + rc = 0; } else { rc = be_entry_get_rw(op, gr_ndn, group_oc, group_at, 0, &e ); } if ( e ) { a = attr_find( e->e_attrs, group_at ); if ( a ) { - rc = value_find_ex( group_at, + /* If the attribute is a subtype of labeledURI, treat this as + * a dynamic group ala groupOfURLs + */ + if (is_at_subtype( group_at->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) { + int i; + LDAPURLDesc *ludp; + struct berval bv, nbase; + Filter *filter; + Entry *user; + 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 ); + rc = be_entry_get_rw(op, op_ndn, NULL, NULL, 0, &user ); + } + + if ( rc == 0 ) { + rc = 1; + for (i=0; a->a_vals[i].bv_val; i++) { + if ( ldap_url_parse( a->a_vals[i].bv_val, &ludp ) != LDAP_SUCCESS ) + continue; + nbase.bv_val = NULL; + /* host part must be empty */ + /* attrs and extensions parts must be empty */ + if (( ludp->lud_host && *ludp->lud_host ) + || ludp->lud_attrs || ludp->lud_exts ) + goto loopit; + ber_str2bv( ludp->lud_dn, 0, 0, &bv ); + if ( dnNormalize( 0, NULL, NULL, &bv, &nbase, op->o_tmpmemctx ) != LDAP_SUCCESS ) + goto loopit; + switch(ludp->lud_scope) { + case LDAP_SCOPE_BASE: + if ( !dn_match(&nbase, op_ndn)) goto loopit; + break; + case LDAP_SCOPE_ONELEVEL: + dnParent(op_ndn, &bv ); + if ( !dn_match(&nbase, &bv)) goto loopit; + break; + case LDAP_SCOPE_SUBTREE: + if ( !dnIsSuffix(op_ndn, &nbase)) goto loopit; + break; + } + filter = str2filter_x( op, ludp->lud_filter ); + if ( filter ) { + if ( test_filter( NULL, user, filter ) == LDAP_COMPARE_TRUE ) + { + rc = 0; + } + filter_free_x( op, filter ); + } + loopit: + ldap_free_urldesc( ludp ); + if ( nbase.bv_val ) { + op->o_tmpfree( nbase.bv_val, op->o_tmpmemctx ); + } + if ( rc == 0 ) break; + } + if ( user != target ) { + be_entry_release_r( op, user ); + } + } + op->o_bd = b2; + } else { + rc = value_find_ex( group_at, SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, a->a_nvals, op_ndn, op->o_tmpmemctx ); + } } else { rc = LDAP_NO_SUCH_ATTRIBUTE; } @@ -1195,19 +1280,18 @@ backend_group( } if ( op->o_tag != LDAP_REQ_BIND && !op->o_do_not_cache ) { - g = ch_malloc(sizeof(GroupAssertion) + gr_ndn->bv_len); + g = sl_malloc(sizeof(GroupAssertion) + gr_ndn->bv_len, op->o_tmpmemctx); g->ga_be = op->o_bd; g->ga_oc = group_oc; g->ga_at = group_at; g->ga_res = rc; g->ga_len = gr_ndn->bv_len; strcpy(g->ga_ndn, gr_ndn->bv_val); - ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); - g->ga_next = op->o_conn->c_groups; - op->o_conn->c_groups = g; - ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); + g->ga_next = op->o_groups; + op->o_groups = g; } - +done: + op->o_bd = be; return rc; } @@ -1224,12 +1308,14 @@ backend_attribute( Attribute *a; int i, j, rc = LDAP_SUCCESS; AccessControlState acl_state = ACL_STATE_INIT; + Backend *be = op->o_bd; + + op->o_bd = select_backend( edn, 0, 0 ); if ( target && dn_match( &target->e_nname, edn ) ) { e = target; } else { rc = be_entry_get_rw(op, edn, NULL, entry_at, 0, &e ); - if ( rc != LDAP_SUCCESS ) return rc; } if ( e ) { @@ -1274,6 +1360,7 @@ freeit: if (e != target ) { } } + op->o_bd = be; return rc; }