X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fbackend.c;h=f64e661ea75ba9fcd7ff92e61a44acbb2121ac16;hb=ac3ad635ef0883d96b5424f96b2c43e13b0ad659;hp=a9b07536edab6e2ee39cee8d326858222ecdbbad;hpb=5f6996c8bfe15e2df0f07f4dca2665f04cb99a0b;p=openldap diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index a9b07536ed..f64e661ea7 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-2004 The OpenLDAP Foundation. + * Copyright 1998-2005 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -56,155 +56,69 @@ static void call_group_postop_plugins( Operation *op ); * imported into slapd without appropriate __declspec(dllimport) directives. */ -#if SLAPD_BDB == SLAPD_MOD_STATIC -#include "back-bdb/external.h" -#endif -#if SLAPD_DNSSRV == SLAPD_MOD_STATIC -#include "back-dnssrv/external.h" -#endif -#if SLAPD_HDB == SLAPD_MOD_STATIC -#include "back-hdb/external.h" -#endif -#if SLAPD_LDAP == SLAPD_MOD_STATIC -#include "back-ldap/external.h" -#endif -#if SLAPD_LDBM == SLAPD_MOD_STATIC -#include "back-ldbm/external.h" -#endif -#if SLAPD_META == SLAPD_MOD_STATIC -#include "back-meta/external.h" -#endif -#if SLAPD_MONITOR == SLAPD_MOD_STATIC -#include "back-monitor/external.h" -#endif -#if SLAPD_NULL == SLAPD_MOD_STATIC -#include "back-null/external.h" -#endif -#if SLAPD_PASSWD == SLAPD_MOD_STATIC -#include "back-passwd/external.h" -#endif -#if SLAPD_PERL == SLAPD_MOD_STATIC -#include "back-perl/external.h" -#endif -#if SLAPD_RELAY == SLAPD_MOD_STATIC -#include "back-relay/external.h" -#endif -#if SLAPD_SHELL == SLAPD_MOD_STATIC -#include "back-shell/external.h" -#endif -#if SLAPD_TCL == SLAPD_MOD_STATIC -#include "back-tcl/external.h" -#endif -#if SLAPD_SQL == SLAPD_MOD_STATIC -#include "back-sql/external.h" -#endif -#if SLAPD_PRIVATE == SLAPD_MOD_STATIC -#include "private/external.h" -#endif - -static BackendInfo binfo[] = { -#if SLAPD_BDB == SLAPD_MOD_STATIC - {"bdb", bdb_initialize}, -#endif -#if SLAPD_DNSSRV == SLAPD_MOD_STATIC - {"dnssrv", dnssrv_back_initialize}, -#endif -#if SLAPD_HDB == SLAPD_MOD_STATIC - {"hdb", hdb_initialize}, -#endif -#if SLAPD_LDAP == SLAPD_MOD_STATIC - {"ldap", ldap_back_initialize}, -#endif -#if SLAPD_LDBM == SLAPD_MOD_STATIC - {"ldbm", ldbm_back_initialize}, -#endif -#if SLAPD_META == SLAPD_MOD_STATIC - {"meta", meta_back_initialize}, -#endif -#if SLAPD_MONITOR == SLAPD_MOD_STATIC - {"monitor", monitor_back_initialize}, -#endif -#if SLAPD_NULL == SLAPD_MOD_STATIC - {"null", null_back_initialize}, -#endif -#if SLAPD_PASSWD == SLAPD_MOD_STATIC - {"passwd", passwd_back_initialize}, -#endif -#if SLAPD_PERL == SLAPD_MOD_STATIC - {"perl", perl_back_initialize}, -#endif -#if SLAPD_RELAY == SLAPD_MOD_STATIC - {"relay", relay_back_initialize}, -#endif -#if SLAPD_SHELL == SLAPD_MOD_STATIC - {"shell", shell_back_initialize}, -#endif -#if SLAPD_TCL == SLAPD_MOD_STATIC - {"tcl", tcl_back_initialize}, -#endif -#if SLAPD_SQL == SLAPD_MOD_STATIC - {"sql", sql_back_initialize}, -#endif - /* for any private backend */ -#if SLAPD_PRIVATE == SLAPD_MOD_STATIC - {"private", private_back_initialize}, -#endif - {NULL} -}; - int nBackendInfo = 0; -BackendInfo *backendInfo = NULL; +BackendInfo *backendInfo = NULL; int nBackendDB = 0; -BackendDB *backendDB = NULL; +BackendDB *backendDB = NULL; + +static int +backend_init_controls( BackendInfo *bi ) +{ + if ( bi->bi_controls ) { + int i; + + for ( i = 0; bi->bi_controls[ i ]; i++ ) { + int cid; + + if ( slap_find_control_id( bi->bi_controls[ i ], &cid ) + == LDAP_CONTROL_NOT_FOUND ) + { + if ( !( slapMode & SLAP_TOOL_MODE ) ) { + assert( 0 ); + } + + return -1; + } -ldap_pvt_thread_pool_t syncrepl_pool; -int syncrepl_pool_max = SLAP_MAX_SYNCREPL_THREADS; + bi->bi_ctrls[ cid ] = 1; + } + } + + return 0; +} int backend_init(void) { int rc = -1; - ldap_pvt_thread_pool_init( &syncrepl_pool, syncrepl_pool_max, 0 ); - if((nBackendInfo != 0) || (backendInfo != NULL)) { /* already initialized */ -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, ERR, - "backend_init: backend already initialized\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, - "backend_init: already initialized.\n", 0, 0, 0 ); -#endif + "backend_init: already initialized\n", 0, 0, 0 ); return -1; } for( ; - binfo[nBackendInfo].bi_type != NULL; + slap_binfo[nBackendInfo].bi_type != NULL; nBackendInfo++ ) { - assert( binfo[nBackendInfo].bi_init ); + assert( slap_binfo[nBackendInfo].bi_init ); - rc = binfo[nBackendInfo].bi_init( &binfo[nBackendInfo] ); + rc = slap_binfo[nBackendInfo].bi_init( &slap_binfo[nBackendInfo] ); if(rc != 0) { -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, INFO, - "backend_init: initialized for type \"%s\"\n", - binfo[nBackendInfo].bi_type, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "backend_init: initialized for type \"%s\"\n", - binfo[nBackendInfo].bi_type, 0, 0 ); -#endif + slap_binfo[nBackendInfo].bi_type, 0, 0 ); /* destroy those we've already inited */ for( nBackendInfo--; nBackendInfo >= 0 ; nBackendInfo-- ) { - if ( binfo[nBackendInfo].bi_destroy ) { - binfo[nBackendInfo].bi_destroy( - &binfo[nBackendInfo] ); + if ( slap_binfo[nBackendInfo].bi_destroy ) { + slap_binfo[nBackendInfo].bi_destroy( + &slap_binfo[nBackendInfo] ); } } return rc; @@ -212,7 +126,7 @@ int backend_init(void) } if ( nBackendInfo > 0) { - backendInfo = binfo; + backendInfo = slap_binfo; return 0; } @@ -220,13 +134,9 @@ int backend_init(void) return 0; #else -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, ERR, "backend_init: failed\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "backend_init: failed\n", 0, 0, 0 ); -#endif return rc; #endif /* SLAPD_MODULES */ @@ -237,37 +147,28 @@ int backend_add(BackendInfo *aBackendInfo) int rc = 0; if ( aBackendInfo->bi_init == NULL ) { -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, ERR, "backend_add: " - "backend type \"%s\" does not have the (mandatory)init function\n", - aBackendInfo->bi_type, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "backend_add: " "backend type \"%s\" does not have the (mandatory)init function\n", aBackendInfo->bi_type, 0, 0 ); -#endif return -1; } - if ((rc = aBackendInfo->bi_init(aBackendInfo)) != 0) { -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, ERR, - "backend_add: initialization for type \"%s\" failed\n", - aBackendInfo->bi_type, 0, 0 ); -#else + rc = aBackendInfo->bi_init(aBackendInfo); + if ( rc != 0) { Debug( LDAP_DEBUG_ANY, "backend_add: initialization for type \"%s\" failed\n", aBackendInfo->bi_type, 0, 0 ); -#endif return rc; - } + } + + (void)backend_init_controls( aBackendInfo ); /* now add the backend type to the Backend Info List */ { BackendInfo *newBackendInfo = 0; - /* if backendInfo == binfo no deallocation of old backendInfo */ - if (backendInfo == binfo) { + /* if backendInfo == slap_binfo no deallocation of old backendInfo */ + if (backendInfo == slap_binfo) { newBackendInfo = ch_calloc(nBackendInfo + 1, sizeof(BackendInfo)); AC_MEMCPY(newBackendInfo, backendInfo, sizeof(BackendInfo) * nBackendInfo); @@ -284,43 +185,69 @@ int backend_add(BackendInfo *aBackendInfo) } } +static int +backend_set_controls( BackendDB *be ) +{ + BackendInfo *bi = be->bd_info; + + /* back-relay takes care of itself; so may do other */ + if ( overlay_is_over( be ) ) { + bi = ((slap_overinfo *)be->bd_info->bi_private)->oi_orig; + } + + if ( bi->bi_controls ) { + if ( be->be_ctrls[ SLAP_MAX_CIDS ] == 0 ) { + AC_MEMCPY( be->be_ctrls, bi->bi_ctrls, + sizeof( be->be_ctrls ) ); + be->be_ctrls[ SLAP_MAX_CIDS ] = 1; + + } else { + int i; + + for ( i = 0; i < SLAP_MAX_CIDS; i++ ) { + if ( bi->bi_ctrls[ i ] ) { + be->be_ctrls[ i ] = bi->bi_ctrls[ i ]; + } + } + } + + } + + return 0; +} + /* startup a specific backend database */ int backend_startup_one(Backend *be) { - int rc = 0; + int rc = 0; - assert(be); + assert( be ); be->be_pending_csn_list = (struct be_pcl *) ch_calloc( 1, sizeof( struct be_pcl )); - build_new_dn( &be->be_context_csn, be->be_nsuffix, - (struct berval *)&slap_ldapsync_cn_bv, NULL ); LDAP_TAILQ_INIT( be->be_pending_csn_list ); -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, DETAIL1, "backend_startup: starting \"%s\"\n", - be->be_suffix ? be->be_suffix[0].bv_val : "(unknown)", - 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, - "backend_startup: starting \"%s\"\n", + "backend_startup_one: starting \"%s\"\n", be->be_suffix ? be->be_suffix[0].bv_val : "(unknown)", 0, 0 ); -#endif + + /* set database controls */ + (void)backend_set_controls( be ); + if ( be->bd_info->bi_db_open ) { rc = be->bd_info->bi_db_open( be ); - if ( rc != 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, CRIT, - "backend_startup: bi_db_open failed! (%d)\n", rc, 0, 0 ); -#else + if ( rc == 0 ) { + (void)backend_set_controls( be ); + + } else { Debug( LDAP_DEBUG_ANY, - "backend_startup: bi_db_open failed! (%d)\n", + "backend_startup_one: bi_db_open failed! (%d)\n", rc, 0, 0 ); -#endif } } + return rc; } @@ -331,14 +258,9 @@ int backend_startup(Backend *be) if( ! ( nBackendDB > 0 ) ) { /* no databases */ -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, INFO, - "backend_startup: %d databases to startup. \n", nBackendDB, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "backend_startup: %d databases to startup.\n", nBackendDB, 0, 0 ); -#endif return 1; } @@ -346,14 +268,9 @@ int backend_startup(Backend *be) if ( be->bd_info->bi_open ) { rc = be->bd_info->bi_open( be->bd_info ); if ( rc != 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, CRIT, - "backend_startup: bi_open failed!\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "backend_startup: bi_open failed!\n", 0, 0, 0 ); -#endif return rc; } @@ -366,15 +283,9 @@ int backend_startup(Backend *be) if ( frontendDB->bd_info->bi_db_open ) { rc = frontendDB->bd_info->bi_db_open( frontendDB ); if ( rc != 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, CRIT, - "backend_startup: bi_db_open(frontend) failed! (%d)\n", - rc, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "backend_startup: bi_db_open(frontend) failed! (%d)\n", rc, 0, 0 ); -#endif return rc; } } @@ -387,40 +298,29 @@ int backend_startup(Backend *be) } if( backendInfo[i].bi_open ) { - rc = backendInfo[i].bi_open( - &backendInfo[i] ); + rc = backendInfo[i].bi_open( &backendInfo[i] ); if ( rc != 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, CRIT, - "backend_startup: bi_open %d failed!\n", i, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "backend_startup: bi_open %d failed!\n", i, 0, 0 ); -#endif return rc; } } + + (void)backend_init_controls( &backendInfo[i] ); } - ldap_pvt_thread_mutex_init( &syncrepl_rq.rq_mutex ); - LDAP_STAILQ_INIT( &syncrepl_rq.task_list ); - LDAP_STAILQ_INIT( &syncrepl_rq.run_list ); + ldap_pvt_thread_mutex_init( &slapd_rq.rq_mutex ); + LDAP_STAILQ_INIT( &slapd_rq.task_list ); + LDAP_STAILQ_INIT( &slapd_rq.run_list ); /* open each backend database */ for( i = 0; i < nBackendDB; i++ ) { if ( backendDB[i].be_suffix == NULL ) { -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, CRIT, - "backend_startup: warning, database %d (%s) " - "has no suffix\n", - i, backendDB[i].bd_info->bi_type, 0 ); -#else Debug( LDAP_DEBUG_ANY, "backend_startup: warning, database %d (%s) " "has no suffix\n", i, backendDB[i].bd_info->bi_type, 0 ); -#endif } /* append global access controls */ acl_append( &backendDB[i].be_acl, frontendDB->be_acl ); @@ -430,30 +330,25 @@ int backend_startup(Backend *be) if ( rc ) return rc; - if ( !LDAP_STAILQ_EMPTY( &backendDB[i].be_syncinfo )) { + if ( backendDB[i].be_syncinfo ) { syncinfo_t *si; if ( !( backendDB[i].be_search && backendDB[i].be_add && backendDB[i].be_modify && backendDB[i].be_delete )) { -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, CRIT, - "backend_startup: database(%d) does not support " - "operations required for syncrepl", i, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "backend_startup: database(%d) does not support " "operations required for syncrepl", i, 0, 0 ); -#endif continue; } - LDAP_STAILQ_FOREACH( si, &backendDB[i].be_syncinfo, si_next ) { + { + si = backendDB[i].be_syncinfo; si->si_be = &backendDB[i]; init_syncrepl( si ); - ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex ); - ldap_pvt_runqueue_insert( &syncrepl_rq, + ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); + ldap_pvt_runqueue_insert( &slapd_rq, si->si_interval, do_syncrepl, (void *) si ); - ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex ); + ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } } } @@ -505,15 +400,9 @@ int backend_shutdown( Backend *be ) } if(rc != 0) { -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, NOTICE, - "backend_shutdown: bi_db_close %s failed!\n", - backendDB[i].be_type, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "backend_close: bi_db_close %s failed!\n", backendDB[i].be_type, 0, 0 ); -#endif } } @@ -534,15 +423,9 @@ int backend_shutdown( Backend *be ) if ( frontendDB->bd_info->bi_db_close ) { rc = frontendDB->bd_info->bi_db_close ( frontendDB ); if ( rc != 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG( BACKEND, CRIT, - "backend_startup: bi_db_close(frontend) failed! (%d)\n", - rc, 0, 0 ); -#else Debug( LDAP_DEBUG_ANY, "backend_startup: bi_db_close(frontend) failed! (%d)\n", rc, 0, 0 ); -#endif } } @@ -553,20 +436,41 @@ int backend_destroy(void) { int i; BackendDB *bd; - - ldap_pvt_thread_pool_destroy( &syncrepl_pool, 1 ); + struct slap_csn_entry *csne; /* destroy each backend database */ for( i = 0, bd = backendDB; i < nBackendDB; i++, bd++ ) { + + if ( bd->be_syncinfo ) { + syncinfo_free( bd->be_syncinfo ); + } + + if ( bd->be_pending_csn_list ) { + csne = LDAP_TAILQ_FIRST( bd->be_pending_csn_list ); + while ( csne ) { + struct slap_csn_entry *tmp_csne = csne; + + LDAP_TAILQ_REMOVE( bd->be_pending_csn_list, csne, ce_csn_link ); + ch_free( csne->ce_csn.bv_val ); + csne = LDAP_TAILQ_NEXT( csne, ce_csn_link ); + ch_free( tmp_csne ); + } + } + if ( bd->bd_info->bi_db_destroy ) { bd->bd_info->bi_db_destroy( bd ); } ber_bvarray_free( bd->be_suffix ); ber_bvarray_free( bd->be_nsuffix ); - if ( bd->be_rootdn.bv_val ) free( bd->be_rootdn.bv_val ); - if ( bd->be_rootndn.bv_val ) free( bd->be_rootndn.bv_val ); - if ( bd->be_rootpw.bv_val ) free( bd->be_rootpw.bv_val ); - if ( bd->be_context_csn.bv_val ) free( bd->be_context_csn.bv_val ); + if ( !BER_BVISNULL( &bd->be_rootdn ) ) { + free( bd->be_rootdn.bv_val ); + } + if ( !BER_BVISNULL( &bd->be_rootndn ) ) { + free( bd->be_rootndn.bv_val ); + } + if ( !BER_BVISNULL( &bd->be_rootpw ) ) { + free( bd->be_rootpw.bv_val ); + } acl_destroy( bd->be_acl, frontendDB->be_acl ); } free( backendDB ); @@ -580,7 +484,7 @@ int backend_destroy(void) } #ifdef SLAPD_MODULES - if (backendInfo != binfo) { + if (backendInfo != slap_binfo) { free(backendInfo); } #endif /* SLAPD_MODULES */ @@ -590,15 +494,23 @@ int backend_destroy(void) /* destroy frontend database */ bd = frontendDB; - if ( bd->bd_info->bi_db_destroy ) { - bd->bd_info->bi_db_destroy( bd ); + if ( bd ) { + if ( bd->bd_info->bi_db_destroy ) { + bd->bd_info->bi_db_destroy( bd ); + } + ber_bvarray_free( bd->be_suffix ); + ber_bvarray_free( bd->be_nsuffix ); + if ( !BER_BVISNULL( &bd->be_rootdn ) ) { + free( bd->be_rootdn.bv_val ); + } + if ( !BER_BVISNULL( &bd->be_rootndn ) ) { + free( bd->be_rootndn.bv_val ); + } + if ( !BER_BVISNULL( &bd->be_rootpw ) ) { + free( bd->be_rootpw.bv_val ); + } + acl_destroy( bd->be_acl, frontendDB->be_acl ); } - ber_bvarray_free( bd->be_suffix ); - ber_bvarray_free( bd->be_nsuffix ); - if ( bd->be_rootdn.bv_val ) free( bd->be_rootdn.bv_val ); - if ( bd->be_rootndn.bv_val ) free( bd->be_rootndn.bv_val ); - if ( bd->be_rootpw.bv_val ) free( bd->be_rootpw.bv_val ); - acl_destroy( bd->be_acl, frontendDB->be_acl ); return 0; } @@ -650,6 +562,7 @@ backend_db_init( be = &backends[nbackends++]; be->bd_info = bi; + be->be_def_limit = frontendDB->be_def_limit; be->be_dfltaccess = frontendDB->be_dfltaccess; @@ -657,21 +570,17 @@ backend_db_init( be->be_requires = frontendDB->be_requires; be->be_ssf_set = frontendDB->be_ssf_set; - be->be_context_csn.bv_len = 0; - be->be_context_csn.bv_val = NULL; be->be_pcl_mutexp = &be->be_pcl_mutex; ldap_pvt_thread_mutex_init( be->be_pcl_mutexp ); - LDAP_STAILQ_INIT( &be->be_syncinfo ); - /* assign a default depth limit for alias deref */ be->be_max_deref_depth = SLAPD_DEFAULT_MAXDEREFDEPTH; - if(bi->bi_db_init) { + if ( bi->bi_db_init ) { rc = bi->bi_db_init( be ); } - if(rc != 0) { + if ( rc != 0 ) { fprintf( stderr, "database init failed (%s)\n", type ); nbackends--; return NULL; @@ -695,6 +604,7 @@ be_db_close( void ) if ( frontendDB->bd_info->bi_db_close ) { (*frontendDB->bd_info->bi_db_close)( frontendDB ); } + } Backend * @@ -703,13 +613,16 @@ select_backend( int manageDSAit, int noSubs ) { - int i, j; - ber_len_t len, dnlen = dn->bv_len; - Backend *be = NULL; + int i, j; + ber_len_t len, dnlen = dn->bv_len; + Backend *be = NULL; for ( i = 0; i < nbackends; i++ ) { - for ( j = 0; backends[i].be_nsuffix != NULL && - backends[i].be_nsuffix[j].bv_val != NULL; j++ ) + if ( backends[i].be_nsuffix == NULL ) { + continue; + } + + for ( j = 0; !BER_BVISNULL( &backends[i].be_nsuffix[j] ); j++ ) { if ( ( SLAP_GLUE_SUBORDINATE( &backends[i] ) ) && noSubs ) @@ -762,58 +675,49 @@ be_issuffix( { int i; - for ( i = 0; - be->be_nsuffix != NULL && be->be_nsuffix[i].bv_val != NULL; - i++ ) - { + if ( be->be_nsuffix == NULL ) { + return 0; + } + + for ( i = 0; !BER_BVISNULL( &be->be_nsuffix[i] ); i++ ) { if ( bvmatch( &be->be_nsuffix[i], bvsuffix ) ) { - return( 1 ); + return 1; } } - return( 0 ); + return 0; } int be_isroot_dn( Backend *be, struct berval *ndn ) { - if ( !ndn->bv_len ) { - return( 0 ); - } - - if ( !be->be_rootndn.bv_len ) { - return( 0 ); + if ( BER_BVISEMPTY( ndn ) || BER_BVISEMPTY( &be->be_rootndn ) ) { + return 0; } return dn_match( &be->be_rootndn, ndn ); } -int -be_sync_update( Operation *op ) -{ - return ( SLAP_SYNC_SHADOW( op->o_bd ) && syncrepl_isupdate( op ) ); -} - int be_slurp_update( Operation *op ) { return ( SLAP_SLURP_SHADOW( op->o_bd ) && - be_isupdate_dn( op->o_bd, &op->o_ndn )); + be_isupdate_dn( op->o_bd, &op->o_ndn ) ); } int be_shadow_update( Operation *op ) { - return ( SLAP_SHADOW( op->o_bd ) && - ( syncrepl_isupdate( op ) || be_isupdate_dn( op->o_bd, &op->o_ndn ))); + return ( SLAP_SYNC_SHADOW( op->o_bd ) || + ( SLAP_SHADOW( op->o_bd ) && be_isupdate_dn( op->o_bd, &op->o_ndn ) ) ); } int be_isupdate_dn( Backend *be, struct berval *ndn ) { - if ( !ndn->bv_len ) return( 0 ); - - if ( !be->be_update_ndn.bv_len ) return( 0 ); + if ( BER_BVISEMPTY( ndn ) || BER_BVISEMPTY( &be->be_update_ndn ) ) { + return 0; + } return dn_match( &be->be_update_ndn, ndn ); } @@ -839,7 +743,7 @@ be_isroot_pw( Operation *op ) return 0; } - if( op->o_bd->be_rootpw.bv_len == 0 ) { + if ( BER_BVISEMPTY( &op->o_bd->be_rootpw ) ) { return 0; } @@ -896,15 +800,9 @@ backend_unbind( Operation *op, SlapReply *rs ) * 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); -#else Debug(LDAP_DEBUG_TRACE, "do_bind: Unbind preoperation plugin failed\n", 0, 0, 0); -#endif return 0; } } @@ -919,15 +817,9 @@ backend_unbind( Operation *op, SlapReply *rs ) if ( op->o_pb != NULL && slapi_int_call_plugins( &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); -#else Debug(LDAP_DEBUG_TRACE, "do_unbind: Unbind postoperation plugins failed\n", 0, 0, 0); -#endif } #endif /* defined( LDAP_SLAPI ) */ } @@ -965,7 +857,7 @@ backend_connection_destroy( return 0; } -static int +int backend_check_controls( Operation *op, SlapReply *rs ) @@ -975,16 +867,51 @@ backend_check_controls( if( ctrls ) { for( ; *ctrls != NULL ; ctrls++ ) { - 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; + int cid; + + switch ( slap_global_control( op, (*ctrls)->ldctl_oid, &cid ) ) { + case LDAP_CONTROL_NOT_FOUND: + /* unrecognized control */ + if ( (*ctrls)->ldctl_iscritical ) { + /* should not be reachable */ + Debug( LDAP_DEBUG_ANY, + "backend_check_controls: unrecognized control: %s\n", + (*ctrls)->ldctl_oid, 0, 0 ); + assert( 0 ); + } + break; + + case LDAP_COMPARE_FALSE: + if ( !op->o_bd->be_ctrls[ cid ] ) + { + /* 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 not unavailable in a particular context, hence the + * return of unwillingToPerform. + */ + rs->sr_text = "control unavailable in context"; + rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + goto done; + } + break; + + case LDAP_COMPARE_TRUE: break; + + default: + /* unreachable */ + rs->sr_text = "unable to check control"; + rs->sr_err = LDAP_OTHER; + goto done; } } } +done:; return rs->sr_err; } @@ -1003,8 +930,18 @@ backend_check_restrictions( int starttls = 0; int session = 0; - if( op->o_bd ) { - if ( backend_check_controls( op, rs ) != LDAP_SUCCESS ) { + if ( op->o_bd ) { + int rc = SLAP_CB_CONTINUE; + + if ( op->o_bd->be_chk_controls ) { + rc = ( *op->o_bd->be_chk_controls )( op, rs ); + } + + if ( rc == SLAP_CB_CONTINUE ) { + rc = backend_check_controls( op, rs ); + } + + if ( rc != LDAP_SUCCESS ) { return rs->sr_err; } @@ -1170,7 +1107,7 @@ backend_check_restrictions( } if( !( global_allows & SLAP_ALLOW_UPDATE_ANON ) && - op->o_ndn.bv_len == 0 ) + BER_BVISEMPTY( &op->o_ndn ) ) { rs->sr_text = "modifications require authentication"; rs->sr_err = LDAP_STRONG_AUTH_REQUIRED; @@ -1178,7 +1115,7 @@ backend_check_restrictions( } #ifdef SLAP_X_LISTENER_MOD - if ( op->o_conn->c_listener && ! ( op->o_conn->c_listener->sl_perms & ( op->o_ndn.bv_len > 0 ? S_IWUSR : S_IWOTH ) ) ) { + if ( op->o_conn->c_listener && ! ( op->o_conn->c_listener->sl_perms & ( !BER_BVISEMPTY( &op->o_ndn ) ? S_IWUSR : S_IWOTH ) ) ) { /* no "w" mode means readonly */ rs->sr_text = "modifications not allowed on this listener"; rs->sr_err = LDAP_UNWILLING_TO_PERFORM; @@ -1195,7 +1132,7 @@ backend_check_restrictions( /* should check mechanism */ if( ( op->o_transport_ssf < ssf->sss_transport && op->o_authtype == LDAP_AUTH_SIMPLE ) - || op->o_dn.bv_len == 0 ) + || BER_BVISEMPTY( &op->o_dn ) ) { rs->sr_text = "strong(er) authentication required"; rs->sr_err = LDAP_STRONG_AUTH_REQUIRED; @@ -1204,7 +1141,7 @@ backend_check_restrictions( } if( requires & SLAP_REQUIRE_SASL ) { - if( op->o_authtype != LDAP_AUTH_SASL || op->o_dn.bv_len == 0 ) { + if( op->o_authtype != LDAP_AUTH_SASL || BER_BVISEMPTY( &op->o_dn ) ) { rs->sr_text = "SASL authentication required"; rs->sr_err = LDAP_STRONG_AUTH_REQUIRED; return rs->sr_err; @@ -1212,7 +1149,7 @@ backend_check_restrictions( } if( requires & SLAP_REQUIRE_AUTHC ) { - if( op->o_dn.bv_len == 0 ) { + if( BER_BVISEMPTY( &op->o_dn ) ) { rs->sr_text = "authentication required"; rs->sr_err = LDAP_UNWILLING_TO_PERFORM; return rs->sr_err; @@ -1243,7 +1180,7 @@ backend_check_restrictions( } #ifdef SLAP_X_LISTENER_MOD - if ( !starttls && op->o_dn.bv_len == 0 ) { + if ( !starttls && BER_BVISEMPTY( &op->o_dn ) ) { if ( op->o_conn->c_listener && !( op->o_conn->c_listener->sl_perms & S_IXOTH )) { @@ -1257,7 +1194,7 @@ backend_check_restrictions( if ( !starttls && !updateop ) { if ( op->o_conn->c_listener && !( op->o_conn->c_listener->sl_perms & - ( op->o_dn.bv_len > 0 ? S_IRUSR : S_IROTH ))) + ( !BER_BVISEMPTY( &op->o_dn ) ? S_IRUSR : S_IROTH ))) { /* no "r" mode means no read */ rs->sr_text = "read not allowed on this listener"; @@ -1344,15 +1281,18 @@ backend_group( op->o_bd = select_backend( gr_ndn, 0, 0 ); - 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) + 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; - if (strcmp( g->ga_ndn, gr_ndn->bv_val ) == 0) + } + if ( strcmp( g->ga_ndn, gr_ndn->bv_val ) == 0 ) { break; + } } - if (g) { + if ( g ) { rc = g->ga_res; goto done; } @@ -1361,7 +1301,7 @@ backend_group( e = target; rc = 0; } else { - rc = be_entry_get_rw(op, gr_ndn, group_oc, group_at, 0, &e ); + rc = be_entry_get_rw( op, gr_ndn, group_oc, group_at, 0, &e ); } if ( e ) { #ifdef LDAP_SLAPI @@ -1399,16 +1339,16 @@ backend_group( if ( rc == 0 ) { rc = 1; - for (i=0; a->a_vals[i].bv_val; i++) { + for ( i = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ ) { if ( ldap_url_parse( a->a_vals[i].bv_val, &ludp ) != - LDAP_SUCCESS ) + LDAP_URL_SUCCESS ) { continue; } - nbase.bv_val = NULL; + BER_BVZERO( &nbase ); /* host part must be empty */ /* attrs and extensions parts must be empty */ - if (( ludp->lud_host && *ludp->lud_host ) || + if ( ( ludp->lud_host && *ludp->lud_host ) || ludp->lud_attrs || ludp->lud_exts ) { goto loopit; @@ -1419,21 +1359,27 @@ backend_group( { goto loopit; } - switch(ludp->lud_scope) { + switch ( ludp->lud_scope ) { case LDAP_SCOPE_BASE: - if ( !dn_match( &nbase, op_ndn )) goto loopit; + if ( !dn_match( &nbase, op_ndn ) ) { + goto loopit; + } break; case LDAP_SCOPE_ONELEVEL: - dnParent(op_ndn, &bv ); - if ( !dn_match( &nbase, &bv )) goto loopit; + dnParent( op_ndn, &bv ); + if ( !dn_match( &nbase, &bv ) ) { + goto loopit; + } break; case LDAP_SCOPE_SUBTREE: - if ( !dnIsSuffix( op_ndn, &nbase )) goto loopit; + if ( !dnIsSuffix( op_ndn, &nbase ) ) { + goto loopit; + } break; #ifdef LDAP_SCOPE_SUBORDINATE case LDAP_SCOPE_SUBORDINATE: - if ( dn_match( &nbase, op_ndn ) && - !dnIsSuffix(op_ndn, &nbase )) + if ( dn_match( &nbase, op_ndn ) || + !dnIsSuffix( op_ndn, &nbase ) ) { goto loopit; } @@ -1450,7 +1396,7 @@ backend_group( } loopit: ldap_free_urldesc( ludp ); - if ( nbase.bv_val ) { + if ( !BER_BVISNULL( &nbase ) ) { op->o_tmpfree( nbase.bv_val, op->o_tmpmemctx ); } if ( rc == 0 ) break; @@ -1481,14 +1427,14 @@ loopit: #endif /* LDAP_SLAPI */ if ( op->o_tag != LDAP_REQ_BIND && !op->o_do_not_cache ) { - g = op->o_tmpalloc(sizeof(GroupAssertion) + gr_ndn->bv_len, - op->o_tmpmemctx); + g = op->o_tmpalloc( 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); + strcpy( g->ga_ndn, gr_ndn->bv_val ); g->ga_next = op->o_groups; op->o_groups = g; } @@ -1497,6 +1443,58 @@ done: return rc; } +#ifdef LDAP_SLAPI +static int backend_compute_output_attr(computed_attr_context *c, Slapi_Attr *a, Slapi_Entry *e) +{ + BerVarray v; + int rc; + BerVarray *vals = (BerVarray *)c->cac_private; + Operation *op = NULL; + int i, j; + + slapi_pblock_get( c->cac_pb, SLAPI_OPERATION, &op ); + if ( op == NULL ) { + return 1; + } + + if ( op->o_conn && access_allowed( op, + e, a->a_desc, NULL, ACL_AUTH, + &c->cac_acl_state ) == 0 ) { + return 1; + } + + for ( i = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ ) ; + + v = op->o_tmpalloc( sizeof(struct berval) * (i+1), + op->o_tmpmemctx ); + for ( i = 0, j = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ ) { + if ( op->o_conn && access_allowed( op, + e, a->a_desc, + &a->a_nvals[i], + ACL_AUTH, &c->cac_acl_state ) == 0 ) { + continue; + } + ber_dupbv_x( &v[j], + &a->a_nvals[i], op->o_tmpmemctx ); + if ( !BER_BVISNULL( &v[j] ) ) { + j++; + } + } + + if ( j == 0 ) { + op->o_tmpfree( v, op->o_tmpmemctx ); + *vals = NULL; + rc = 1; + } else { + BER_BVZERO( &v[j] ); + *vals = v; + rc = 0; + } + + return rc; +} +#endif /* LDAP_SLAPI */ + int backend_attribute( Operation *op, @@ -1506,22 +1504,50 @@ backend_attribute( BerVarray *vals, slap_access_t access ) { - Entry *e; - Attribute *a; - int i, j, rc = LDAP_SUCCESS; - AccessControlState acl_state = ACL_STATE_INIT; - Backend *be = op->o_bd; + Entry *e = NULL; + Attribute *a = NULL; + int freeattr = 0, 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 ); + rc = be_entry_get_rw( op, edn, NULL, entry_at, 0, &e ); } if ( e ) { a = attr_find( e->e_attrs, entry_at ); + if ( a == NULL ) { + SlapReply rs = { 0 }; + AttributeName anlist[ 2 ]; + + anlist[ 0 ].an_name = entry_at->ad_cname; + anlist[ 0 ].an_desc = entry_at; + BER_BVZERO( &anlist[ 1 ].an_name ); + rs.sr_attrs = anlist; + + /* NOTE: backend_operational() is also called + * when returning results, so it's supposed + * to do no harm to entries */ + rs.sr_entry = e; + rc = backend_operational( op, &rs ); + rs.sr_entry = NULL; + + if ( rc == LDAP_SUCCESS ) { + if ( rs.sr_operational_attrs ) { + freeattr = 1; + a = rs.sr_operational_attrs; + + } else { + rc = LDAP_NO_SUCH_ATTRIBUTE; + } + } + } + if ( a ) { BerVarray v; @@ -1532,35 +1558,206 @@ backend_attribute( goto freeit; } - for ( i=0; a->a_vals[i].bv_val; i++ ) ; + for ( i = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ ) + ; - v = op->o_tmpalloc( sizeof(struct berval) * (i+1), + v = op->o_tmpalloc( sizeof(struct berval) * ( i + 1 ), op->o_tmpmemctx ); - for ( i=0,j=0; a->a_vals[i].bv_val; i++ ) { - if ( op->o_conn && access > ACL_NONE && access_allowed( op, - e, entry_at, - &a->a_nvals[i], - access, &acl_state ) == 0 ) { + for ( i = 0,j = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ ) + { + if ( op->o_conn && access > ACL_NONE && + access_allowed( op, e, + entry_at, + &a->a_nvals[i], + access, + &acl_state ) == 0 ) + { continue; } - ber_dupbv_x( &v[j], - &a->a_nvals[i], op->o_tmpmemctx ); - if (v[j].bv_val ) j++; + ber_dupbv_x( &v[j], &a->a_nvals[i], + op->o_tmpmemctx ); + if ( !BER_BVISNULL( &v[j] ) ) { + j++; + } } - if (j == 0) { + if ( j == 0 ) { op->o_tmpfree( v, op->o_tmpmemctx ); *vals = NULL; rc = LDAP_INSUFFICIENT_ACCESS; + } else { - v[j].bv_val = NULL; - v[j].bv_len = 0; + BER_BVZERO( &v[j] ); *vals = v; rc = LDAP_SUCCESS; } } -freeit: if (e != target ) { +#ifdef LDAP_SLAPI + else if ( op->o_pb ) { + /* try any computed attributes */ + computed_attr_context ctx; + + slapi_int_pblock_set_operation( op->o_pb, op ); + + ctx.cac_pb = op->o_pb; + ctx.cac_attrs = NULL; + ctx.cac_userattrs = 0; + ctx.cac_opattrs = 0; + ctx.cac_acl_state = acl_state; + ctx.cac_private = (void *)vals; + + rc = compute_evaluator( &ctx, entry_at->ad_cname.bv_val, e, backend_compute_output_attr ); + if ( rc == 1 ) { + rc = LDAP_INSUFFICIENT_ACCESS; + + } else { + rc = LDAP_SUCCESS; + } + } +#endif /* LDAP_SLAPI */ +freeit: if ( e != target ) { + be_entry_release_r( op, e ); + } + if ( freeattr ) { + attr_free( a ); + } + } + + op->o_bd = be; + return rc; +} + +#ifdef LDAP_SLAPI +static int backend_compute_output_attr_access(computed_attr_context *c, Slapi_Attr *a, Slapi_Entry *e) +{ + struct berval *nval = (struct berval *)c->cac_private; + Operation *op = NULL; + + slapi_pblock_get( c->cac_pb, SLAPI_OPERATION, &op ); + if ( op == NULL ) { + return 1; + } + + return access_allowed( op, e, a->a_desc, nval, ACL_AUTH, NULL ) == 0; +} +#endif /* LDAP_SLAPI */ + +int +backend_access( + Operation *op, + Entry *target, + struct berval *edn, + AttributeDescription *entry_at, + struct berval *nval, + slap_access_t access, + slap_mask_t *mask ) +{ + Entry *e = NULL; + int rc = LDAP_INSUFFICIENT_ACCESS; + Backend *be = op->o_bd; + + /* pedantic */ + assert( op ); + assert( op->o_conn ); + assert( edn ); + assert( access > ACL_NONE ); + + 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 ( e ) { + Attribute *a = NULL; + int freeattr = 0; + + if ( entry_at == NULL ) { + entry_at = slap_schema.si_ad_entry; + } + + if ( entry_at == slap_schema.si_ad_entry || entry_at == slap_schema.si_ad_children ) + { + if ( access_allowed_mask( op, e, entry_at, + NULL, access, NULL, mask ) == 0 ) + { + rc = LDAP_INSUFFICIENT_ACCESS; + + } else { + rc = LDAP_SUCCESS; + } + + } else { + a = attr_find( e->e_attrs, entry_at ); + if ( a == NULL ) { + SlapReply rs = { 0 }; + AttributeName anlist[ 2 ]; + + anlist[ 0 ].an_name = entry_at->ad_cname; + anlist[ 0 ].an_desc = entry_at; + BER_BVZERO( &anlist[ 1 ].an_name ); + rs.sr_attrs = anlist; + + rs.sr_attr_flags = slap_attr_flags( rs.sr_attrs ); + + /* NOTE: backend_operational() is also called + * when returning results, so it's supposed + * to do no harm to entries */ + rs.sr_entry = e; + rc = backend_operational( op, &rs ); + rs.sr_entry = NULL; + + if ( rc == LDAP_SUCCESS ) { + if ( rs.sr_operational_attrs ) { + freeattr = 1; + a = rs.sr_operational_attrs; + + } else { + rc = LDAP_NO_SUCH_OBJECT; + } + } + } + + if ( a ) { + if ( access_allowed_mask( op, e, entry_at, + nval, access, NULL, mask ) == 0 ) + { + rc = LDAP_INSUFFICIENT_ACCESS; + goto freeit; + } + rc = LDAP_SUCCESS; + } +#ifdef LDAP_SLAPI + else if ( op->o_pb ) { + /* try any computed attributes */ + computed_attr_context ctx; + + slapi_int_pblock_set_operation( op->o_pb, op ); + + ctx.cac_pb = op->o_pb; + ctx.cac_attrs = NULL; + ctx.cac_userattrs = 0; + ctx.cac_opattrs = 0; + ctx.cac_private = (void *)nval; + + rc = compute_evaluator( &ctx, entry_at->ad_cname.bv_val, e, backend_compute_output_attr_access ); + if ( rc == 1 ) { + rc = LDAP_INSUFFICIENT_ACCESS; + + } else { + rc = LDAP_SUCCESS; + } + } +#endif /* LDAP_SLAPI */ + } +freeit: if ( e != target ) { be_entry_release_r( op, e ); } + if ( freeattr ) { + attr_free( a ); + } } op->o_bd = be; @@ -1573,6 +1770,7 @@ int backend_operational( { Attribute **ap; int rc = 0; + BackendDB *be_orig; for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) /* just count them */ ; @@ -1582,29 +1780,31 @@ int backend_operational( * and the backend supports specific operational attributes, * add them to the attribute list */ - if ( SLAP_OPATTRS( rs->sr_attr_flags ) || ( op->ors_attrs && - ad_inlist( slap_schema.si_ad_subschemaSubentry, op->ors_attrs )) ) { - *ap = slap_operational_subschemaSubentry( op->o_bd ); + if ( 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 ))) + { + *ap = slap_operational_subschemaSubentry( op->o_bd ); ap = &(*ap)->a_next; } - if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || op->ors_attrs ) && op->o_bd && - op->o_bd->be_operational != 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 ) { - Attribute *a; - - a = rs->sr_operational_attrs; - rs->sr_operational_attrs = NULL; rc = op->o_bd->be_operational( op, rs ); - *ap = rs->sr_operational_attrs; - if ( a != NULL ) { - rs->sr_operational_attrs = a; - } - - for ( ; *ap; ap = &(*ap)->a_next ) - /* just count them */ ; } + op->o_bd = be_orig; return rc; } @@ -1614,18 +1814,23 @@ static void init_group_pblock( Operation *op, Entry *target, Entry *e, struct berval *op_ndn, AttributeDescription *group_at ) { slapi_int_pblock_set_operation( op->o_pb, op ); - slapi_pblock_set( op->o_pb, SLAPI_TARGET_DN, (void *)target->e_nname.bv_val ); - slapi_pblock_set( op->o_pb, SLAPI_X_GROUP_ENTRY, (void *)e ); - slapi_pblock_set( op->o_pb, SLAPI_X_GROUP_OPERATION_DN, (void *)op_ndn->bv_val ); - slapi_pblock_set( op->o_pb, SLAPI_X_GROUP_ATTRIBUTE, (void *)group_at->ad_cname.bv_val ); - slapi_pblock_set( op->o_pb, SLAPI_X_GROUP_TARGET_ENTRY, (void *)target ); + + slapi_pblock_set( op->o_pb, + SLAPI_X_GROUP_ENTRY, (void *)e ); + slapi_pblock_set( op->o_pb, + SLAPI_X_GROUP_OPERATION_DN, (void *)op_ndn->bv_val ); + slapi_pblock_set( op->o_pb, + SLAPI_X_GROUP_ATTRIBUTE, (void *)group_at->ad_cname.bv_val ); + slapi_pblock_set( op->o_pb, + SLAPI_X_GROUP_TARGET_ENTRY, (void *)target ); } static int call_group_preop_plugins( Operation *op ) { int rc; - rc = slapi_int_call_plugins( op->o_bd, SLAPI_X_PLUGIN_PRE_GROUP_FN, op->o_pb ); + rc = slapi_int_call_plugins( op->o_bd, + SLAPI_X_PLUGIN_PRE_GROUP_FN, op->o_pb ); if ( rc < 0 ) { if (( slapi_pblock_get( op->o_pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0 ) || rc == LDAP_SUCCESS )