From 145221472e871c7e37c542ca8c4ac46f95f03a86 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Wed, 27 Apr 2005 02:43:38 +0000 Subject: [PATCH] cleanup entity registration --- servers/slapd/back-monitor/back-monitor.h | 43 ++++ servers/slapd/back-monitor/database.c | 2 +- servers/slapd/back-monitor/entry.c | 18 +- servers/slapd/back-monitor/init.c | 247 ++++++++++++++++++++-- servers/slapd/back-monitor/modify.c | 1 + 5 files changed, 287 insertions(+), 24 deletions(-) diff --git a/servers/slapd/back-monitor/back-monitor.h b/servers/slapd/back-monitor/back-monitor.h index dc7d4cf2fb..c98faa1c55 100644 --- a/servers/slapd/back-monitor/back-monitor.h +++ b/servers/slapd/back-monitor/back-monitor.h @@ -36,6 +36,12 @@ typedef struct monitor_callback_t { int (*mc_update)( Operation *op, Entry *e, void *priv ); /* update callback for user-defined entries */ + int (*mc_modify)( Operation *op, Entry *e, void *priv ); + /* modify callback + for user-defined entries */ + int (*mc_free)( Entry *e, void *priv ); + /* update callback + for user-defined entries */ void *mc_private; /* opaque pointer to private data */ struct monitor_callback_t *mc_next; @@ -250,6 +256,43 @@ extern BackendDB *be_monitor; /* increase this bufsize if entries in string form get too big */ #define BACKMONITOR_BUFSIZE 1024 +extern int +monitor_back_register_entry( + Entry *e, + monitor_callback_t *cb ); + +extern int +monitor_back_register_entry_parent( + Entry *e, + monitor_callback_t *cb, + struct berval *base, + int scope, + struct berval *filter ); + +extern int +monitor_filter2ndn( + struct berval *base, + int scope, + struct berval *filter, + struct berval *ndn ); + +extern int +monitor_back_register_entry_attrs( + struct berval *ndn_in, + Attribute *a, + monitor_callback_t *cb, + struct berval *base, + int scope, + struct berval *filter ); + +extern int +monitor_back_register_entry_callback( + struct berval *ndn, + monitor_callback_t *cb, + struct berval *base, + int scope, + struct berval *filter ); + LDAP_END_DECL #include "proto-back-monitor.h" diff --git a/servers/slapd/back-monitor/database.c b/servers/slapd/back-monitor/database.c index 8d5ee6076b..90ac169550 100644 --- a/servers/slapd/back-monitor/database.c +++ b/servers/slapd/back-monitor/database.c @@ -555,7 +555,7 @@ monitor_subsys_database_modify( i = sscanf( e->e_nname.bv_val, "cn=database %d,", &n ); if ( i != 1 ) - return LDAP_UNWILLING_TO_PERFORM; + return /* LDAP_UNWILLING_TO_PERFORM */ 0; if ( n < 0 || n >= nBackendDB ) return LDAP_NO_SUCH_OBJECT; diff --git a/servers/slapd/back-monitor/entry.c b/servers/slapd/back-monitor/entry.c index 3c2b4ebf1c..193a41369d 100644 --- a/servers/slapd/back-monitor/entry.c +++ b/servers/slapd/back-monitor/entry.c @@ -32,7 +32,7 @@ monitor_entry_update( { monitor_info_t *mi = ( monitor_info_t * )op->o_bd->be_private; monitor_entry_t *mp; - int rc = 0; + int rc = 0; assert( mi != NULL ); assert( e != NULL ); @@ -91,6 +91,7 @@ monitor_entry_modify( { monitor_info_t *mi = ( monitor_info_t * )op->o_bd->be_private; monitor_entry_t *mp; + int rc = 0; assert( mi != NULL ); assert( e != NULL ); @@ -99,10 +100,21 @@ monitor_entry_modify( mp = ( monitor_entry_t * )e->e_private; if ( mp->mp_info && mp->mp_info->mss_modify ) { - return ( *mp->mp_info->mss_modify )( op, e ); + rc = ( *mp->mp_info->mss_modify )( op, e ); } - return( 0 ); + if ( rc == 0 && mp->mp_cb ) { + struct monitor_callback_t *mc; + + for ( mc = mp->mp_cb; mc; mc = mc->mc_next ) { + rc = ( *mc->mc_modify )( op, e, mc->mc_private ); + if ( rc != 0 ) { + break; + } + } + } + + return rc; } int diff --git a/servers/slapd/back-monitor/init.c b/servers/slapd/back-monitor/init.c index 8747e2a891..abbc20457b 100644 --- a/servers/slapd/back-monitor/init.c +++ b/servers/slapd/back-monitor/init.c @@ -201,6 +201,7 @@ monitor_back_register_subsys( monitor_subsys_t *ms ) enum { LIMBO_ENTRY, + LIMBO_ENTRY_PARENT, LIMBO_ATTRS, LIMBO_CB }; @@ -281,7 +282,7 @@ monitor_back_register_entry( } e_new = entry_dup( e ); - if ( e == NULL ) { + if ( e_new == NULL ) { Debug( LDAP_DEBUG_ANY, "monitor_back_register_entry(\"%s\"): " "entry_dup() failed\n", @@ -293,6 +294,7 @@ monitor_back_register_entry( e_new->e_private = ( void * )mp; mp->mp_info = mp_parent->mp_info; mp->mp_flags = mp_parent->mp_flags | MONITOR_F_SUB; + mp->mp_cb = cb; ep = &mp_parent->mp_children; for ( ; *ep; ) { @@ -326,7 +328,7 @@ done:; } } else { - entry_limbo_t *elp, el = { 0 }; + entry_limbo_t **elpp, el = { 0 }; el.el_type = LIMBO_ENTRY; @@ -341,16 +343,209 @@ done:; el.el_cb = cb; - elp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) ); - if ( elp ) { + for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo; + *elpp; + elpp = &(*elpp)->el_next ) + /* go to last */; + + *elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) ); + if ( *elpp == NULL ) { + el.el_e->e_private = NULL; + entry_free( el.el_e ); + return -1; + } + + el.el_next = NULL; + **elpp = el; + } + + return 0; +} + +int +monitor_back_register_entry_parent( + Entry *e, + monitor_callback_t *cb, + struct berval *base, + int scope, + struct berval *filter ) +{ + monitor_info_t *mi = ( monitor_info_t * )be_monitor->be_private; + struct berval ndn = BER_BVNULL; + + assert( mi != NULL ); + assert( e != NULL ); + assert( e->e_private == NULL ); + + if ( BER_BVISNULL( filter ) ) { + /* need a filter */ + Debug( LDAP_DEBUG_ANY, + "monitor_back_register_entry_parent(\"\"): " + "need a valid filter\n", + 0, 0, 0 ); + return -1; + } + + if ( monitor_subsys_opened ) { + Entry *e_parent = NULL, + *e_new = NULL, + **ep = NULL; + struct berval e_name = BER_BVNULL, + e_nname = BER_BVNULL; + monitor_entry_t *mp = NULL, + *mp_parent = NULL; + int rc = 0; + + if ( monitor_filter2ndn( base, scope, filter, &ndn ) ) { + /* entry does not exist */ + Debug( LDAP_DEBUG_ANY, + "monitor_back_register_entry_*(\"\"): " + "base=%s scope=%d filter=%s : " + "unable to find entry\n", + base->bv_val ? base->bv_val : "\"\"", + scope, filter->bv_val ); + return -1; + } + + if ( monitor_cache_get( mi, &ndn, &e_parent ) != 0 ) { + /* entry does not exist */ + Debug( LDAP_DEBUG_ANY, + "monitor_back_register_entry_parent(\"%s\"): " + "parent entry does not exist\n", + ndn.bv_val, 0, 0 ); + rc = -1; + goto done; + } + + assert( e_parent->e_private != NULL ); + mp_parent = ( monitor_entry_t * )e_parent->e_private; + + if ( mp_parent->mp_flags & MONITOR_F_VOLATILE ) { + /* entry is volatile; cannot append callback */ + Debug( LDAP_DEBUG_ANY, + "monitor_back_register_entry_*(\"%s\"): " + "entry is volatile\n", + e_parent->e_name.bv_val, 0, 0 ); + rc = -1; + goto done; + } + + build_new_dn( &e_name, &e_parent->e_name, &e->e_name, NULL ); + build_new_dn( &e_nname, &e_parent->e_nname, &e->e_nname, NULL ); + + if ( monitor_cache_get( mi, &e_nname, &e_new ) == 0 ) { + /* entry already exists */ + Debug( LDAP_DEBUG_ANY, + "monitor_back_register_entry_parent(\"%s\"): " + "entry already exists\n", + e_name.bv_val, 0, 0 ); + monitor_cache_release( mi, e_new ); + rc = -1; + goto done; + } + + mp = monitor_entrypriv_create(); + if ( mp == NULL ) { + Debug( LDAP_DEBUG_ANY, + "monitor_back_register_entry_parent(\"%s\"): " + "monitor_entrypriv_create() failed\n", + e->e_name.bv_val, 0, 0 ); + rc = -1; + goto done; + } + + e_new = entry_dup( e ); + if ( e_new == NULL ) { + Debug( LDAP_DEBUG_ANY, + "monitor_back_register_entry(\"%s\"): " + "entry_dup() failed\n", + e->e_name.bv_val, 0, 0 ); + rc = -1; + goto done; + } + ch_free( e_new->e_name.bv_val ); + ch_free( e_new->e_nname.bv_val ); + e_new->e_name = e_name; + e_new->e_nname = e_nname; + + e_new->e_private = ( void * )mp; + mp->mp_info = mp_parent->mp_info; + mp->mp_flags = mp_parent->mp_flags | MONITOR_F_SUB; + mp->mp_cb = cb; + + ep = &mp_parent->mp_children; + for ( ; *ep; ) { + mp_parent = ( monitor_entry_t * )(*ep)->e_private; + ep = &mp_parent->mp_next; + } + *ep = e_new; + + if ( monitor_cache_add( mi, e_new ) ) { + Debug( LDAP_DEBUG_ANY, + "monitor_back_register_entry(\"%s\"): " + "unable to add entry\n", + e->e_name.bv_val, 0, 0 ); + rc = -1; + goto done; + } + +done:; + if ( !BER_BVISNULL( &ndn ) ) { + ch_free( ndn.bv_val ); + } + + if ( rc ) { + if ( mp ) { + ch_free( mp ); + } + if ( e_new ) { + e_new->e_private = NULL; + entry_free( e_new ); + } + } + + if ( e_parent ) { + monitor_cache_release( mi, e_parent ); + } + + } else { + entry_limbo_t **elpp, el = { 0 }; + + el.el_type = LIMBO_ENTRY_PARENT; + + el.el_e = entry_dup( e ); + if ( el.el_e == NULL ) { + Debug( LDAP_DEBUG_ANY, + "monitor_back_register_entry(\"%s\"): " + "entry_dup() failed\n", + e->e_name.bv_val, 0, 0 ); + return -1; + } + + if ( !BER_BVISNULL( base ) ) { + ber_dupbv( &el.el_base, base ); + } + el.el_scope = scope; + if ( !BER_BVISNULL( filter ) ) { + ber_dupbv( &el.el_filter, filter ); + } + + el.el_cb = cb; + + for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo; + *elpp; + elpp = &(*elpp)->el_next ) + /* go to last */; + + *elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) ); + if ( *elpp == NULL ) { el.el_e->e_private = NULL; entry_free( el.el_e ); return -1; } - el.el_next = (entry_limbo_t *)mi->mi_entry_limbo; - *elp = el; - mi->mi_entry_limbo = (void *)elp; + el.el_next = NULL; + **elpp = el; } return 0; @@ -373,11 +568,10 @@ monitor_filter2ndn( struct berval *base, int scope, struct berval *filter, struct berval *ndn ) { Connection conn = { 0 }; - char opbuf[OPERATION_BUFFER_SIZE]; + char opbuf[OPERATION_BUFFER_SIZE]; Operation *op; SlapReply rs = { 0 }; slap_callback cb = { NULL, monitor_filter2ndn_cb, NULL, NULL }; - AttributeName anlist[ 2 ]; int rc; BER_BVZERO( ndn ); @@ -415,9 +609,7 @@ monitor_filter2ndn( struct berval *base, int scope, struct berval *filter, op->ors_scope = scope; ber_dupbv_x( &op->ors_filterstr, filter, op->o_tmpmemctx ); op->ors_filter = str2filter_x( op, filter->bv_val ); - op->ors_attrs = anlist; - BER_BVSTR( &anlist[ 0 ].an_name, LDAP_NO_ATTRS ); - BER_BVZERO( &anlist[ 1 ].an_name ); + op->ors_attrs = slap_anlist_no_attrs; op->ors_attrsonly = 0; op->ors_tlimit = SLAP_NO_LIMIT; op->ors_slimit = 1; @@ -579,7 +771,7 @@ done:; } } else { - entry_limbo_t *elp, el = { 0 }; + entry_limbo_t **elpp, el = { 0 }; el.el_type = LIMBO_ATTRS; if ( !BER_BVISNULL( &ndn ) ) { @@ -596,15 +788,20 @@ done:; el.el_a = attrs_dup( a ); el.el_cb = cb; - elp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) ); - if ( elp == NULL ) { - attrs_free( a ); + for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo; + *elpp; + elpp = &(*elpp)->el_next ) + /* go to last */; + + *elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) ); + if ( *elpp == NULL ) { + el.el_e->e_private = NULL; + entry_free( el.el_e ); return -1; } - el.el_next = (entry_limbo_t *)mi->mi_entry_limbo; - *elp = el; - mi->mi_entry_limbo = (void *)elp;; + el.el_next = NULL; + **elpp = el; } return 0; @@ -886,7 +1083,7 @@ monitor_back_db_init( offsetof(monitor_info_t, mi_ad_monitorTimestamp) }, { "monitorOverlay", "( 1.3.6.1.4.1.4203.666.1.27 " "NAME 'monitorOverlay' " - "DESC 'name of overlays defined for a give database' " + "DESC 'name of overlays defined for a given database' " "SUP monitoredInfo " "NO-USER-MODIFICATION " "USAGE directoryOperation )", SLAP_AT_HIDE, @@ -1352,6 +1549,16 @@ monitor_back_db_open( el->el_cb ); break; + case LIMBO_ENTRY_PARENT: + monitor_back_register_entry_parent( + el->el_e, + el->el_cb, + &el->el_base, + el->el_scope, + &el->el_filter ); + break; + + case LIMBO_ATTRS: monitor_back_register_entry_attrs( &el->el_ndn, diff --git a/servers/slapd/back-monitor/modify.c b/servers/slapd/back-monitor/modify.c index 0fe61e2b46..d4aee8c990 100644 --- a/servers/slapd/back-monitor/modify.c +++ b/servers/slapd/back-monitor/modify.c @@ -67,6 +67,7 @@ monitor_back_modify( Operation *op, SlapReply *rs ) if ( !acl_check_modlist( op, e, op->oq_modify.rs_modlist )) { rc = LDAP_INSUFFICIENT_ACCESS; + } else { rc = monitor_entry_modify( op, e ); } -- 2.39.5