#define SLAPD_SCHEMA_DN "cn=Subschema"
/* dn of the default "monitor" subentry */
#define SLAPD_MONITOR_DN "cn=Monitor"
-#define SLAPD_MONITOR_NDN "CN=MONITOR"
#if 0
/* dn of the default "config" subentry */
#define SLAPD_CONFIG_DN "cn=Config"
# $OpenLDAP$
-SRCS = init.c search.c compare.c abandon.c \
+SRCS = init.c search.c compare.c abandon.c modify.c bind.c \
cache.c entry.c \
- backend.c database.c thread.c conn.c rww.c \
+ backend.c database.c thread.c conn.c rww.c log.c \
dummy.c
-OBJS = init.o search.o compare.o abandon.o \
+OBJS = init.o search.o compare.o abandon.o modify.o bind.o \
cache.o entry.o \
- backend.o database.o thread.o conn.o rww.o \
+ backend.o database.o thread.o conn.o rww.o log.o \
dummy.o
LDAP_INCDIR= ../../../include
#define SLAPD_MONITOR_WRITEW_DN \
SLAPD_MONITOR_WRITEW_RDN "," SLAPD_MONITOR_DN
+#define SLAPD_MONITOR_LOG 9
+#define SLAPD_MONITOR_LOG_NAME "Log"
+#define SLAPD_MONITOR_LOG_RDN \
+ "cn=" SLAPD_MONITOR_LOG_NAME
+#define SLAPD_MONITOR_LOG_DN \
+ SLAPD_MONITOR_LOG_RDN "," SLAPD_MONITOR_DN
+
struct monitorsubsys {
int mss_type;
char *mss_name;
#define MONITOR_HAS_VOLATILE_CH( mp ) \
( ( mp )->mp_flags & MONITOR_F_VOLATILE_CH )
+ /* initialize entry and subentries */
int ( *mss_init )( BackendDB * );
+ /* update existing dynamic entry and subentries */
int ( *mss_update )( struct monitorinfo *, Entry * );
- int ( *mss_create )( struct monitorinfo *, const char *ndn, Entry *, Entry ** );
+ /* create new dynamic subentries */
+ int ( *mss_create )( struct monitorinfo *, const char *ndn,
+ Entry *, Entry ** );
+ /* modify entry and subentries */
+ int ( *mss_modify )( struct monitorinfo *, Entry *,
+ Modifications *modlist );
};
extern struct monitorsubsys monitor_subsys[];
extern int monitor_cache_dup LDAP_P(( void *c1, void *c2 ));
extern int monitor_cache_add LDAP_P(( struct monitorinfo *mi, Entry *e ));
extern int monitor_cache_get LDAP_P(( struct monitorinfo *mi, const char *ndn, Entry **ep ));
-extern int monitor_cache_dn2entry LDAP_P(( struct monitorinfo *mi, const char *ndn, Entry **ep ));
+extern int monitor_cache_dn2entry LDAP_P(( struct monitorinfo *mi, const char *ndn, Entry **ep, Entry **matched ));
extern int monitor_cache_lock LDAP_P(( Entry *e ));
extern int monitor_cache_release LDAP_P(( struct monitorinfo *mi, Entry *e ));
extern int monitor_entry_update LDAP_P(( struct monitorinfo *mi, Entry *e ));
extern int monitor_entry_create LDAP_P(( struct monitorinfo *mi, const char *ndn, Entry *e_parent, Entry **ep ));
+extern int monitor_entry_modify LDAP_P(( struct monitorinfo *mi, Entry *e, Modifications *modlist ));
LDAP_END_DECL
monitor_cache_dn2entry(
struct monitorinfo *mi,
const char *ndn,
- Entry **ep
+ Entry **ep,
+ Entry **matched
)
{
int rc;
assert( mi != NULL );
assert( ndn != NULL );
assert( ep != NULL );
+ assert( matched != NULL );
+
+ *matched = NULL;
rc = monitor_cache_get( mi, ndn, ep );
if ( !rc && *ep != NULL ) {
/* try with parent/ancestors */
p_ndn = dn_parent( NULL, ndn );
- rc = monitor_cache_dn2entry( mi, p_ndn, &e_parent );
+ rc = monitor_cache_dn2entry( mi, p_ndn, &e_parent, matched );
if ( rc || e_parent == NULL) {
return( -1 );
}
/* parent entry generates volatile children */
rc = monitor_entry_create( mi, ndn, e_parent, ep );
}
- monitor_cache_release( mi, e_parent );
+
+ if ( !rc ) {
+ monitor_cache_release( mi, e_parent );
+ } else {
+ *matched = e_parent;
+ }
return( rc );
}
AttributeAssertion *ava
)
{
- return( 0 );
+ struct monitorinfo *mi = (struct monitorinfo *) be->be_private; int rc;
+ Entry *e, *matched = NULL;
+ Attribute *a;
+
+ /* get entry with reader lock */
+ monitor_cache_dn2entry( mi, ndn, &e, &matched );
+ if ( e == NULL ) {
+ send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
+ matched ? matched->e_dn : NULL,
+ NULL, NULL, NULL );
+ if ( matched ) {
+ monitor_cache_release( mi, matched );
+ }
+
+ return( 0 );
+ }
+
+ rc = access_allowed( be, conn, op, e, ava->aa_desc,
+ ava->aa_value, ACL_COMPARE );
+ if ( !rc ) {
+ send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
+ NULL, NULL, NULL, NULL );
+ rc = 1;
+ goto return_results;
+ }
+
+ rc = LDAP_NO_SUCH_ATTRIBUTE;
+
+ for ( a = attrs_find( e->e_attrs, ava->aa_desc );
+ a != NULL;
+ a = attrs_find( a->a_next, ava->aa_desc )) {
+ rc = LDAP_COMPARE_FALSE;
+
+ if ( value_find( ava->aa_desc, a->a_vals, ava->aa_value ) == 0 ) {
+
+ rc = LDAP_COMPARE_TRUE;
+ break;
+ }
+ }
+
+ send_ldap_result( conn, op, rc, NULL, NULL, NULL, NULL );
+
+ if( rc != LDAP_NO_SUCH_ATTRIBUTE ) {
+ rc = 0;
+ }
+
+return_results:;
+ monitor_cache_release( mi, e );
+
+ return( rc );
}
return( 0 );
}
+int
+monitor_entry_modify(
+ struct monitorinfo *mi,
+ Entry *e,
+ Modifications *modlist
+)
+{
+ struct monitorentrypriv *mp;
+
+ assert( mi != NULL );
+ assert( e != NULL );
+ assert( e->e_private != NULL );
+
+ mp = ( struct monitorentrypriv * )e->e_private;
+
+ if ( mp->mp_info && mp->mp_info->mss_modify ) {
+ return ( *mp->mp_info->mss_modify )( mi, e, modlist );
+ }
+
+ return( 0 );
+}
+
int
monitor_entry_test_flags(
struct monitorentrypriv *mp,
extern int monitor_back_abandon LDAP_P(( BackendDB *bd,
Connection *conn, Operation *op, ber_int_t msgid ));
+extern int monitor_back_modify LDAP_P(( BackendDB *bd,
+ Connection *conn, Operation *op,
+ const char *dn, const char *ndn, Modifications *ml ));
+
+extern int monitor_back_bind LDAP_P(( BackendDB *bd,
+ Connection *conn, Operation *op,
+ const char *dn, const char *ndn, int method,
+ struct berval *cred, char** edn ));
+
LDAP_END_DECL
#endif /* _MONITOR_EXTERNAL_H */
MONITOR_F_NONE,
NULL, /* init */
NULL, /* update */
- NULL /* create */
+ NULL, /* create */
+ NULL /* modify */
}, {
SLAPD_MONITOR_DATABASE, SLAPD_MONITOR_DATABASE_NAME,
NULL, NULL, NULL,
MONITOR_F_PERSISTENT_CH,
monitor_subsys_database_init,
NULL, /* update */
- NULL /* create */
+ NULL, /* create */
+ NULL /* modify */
}, {
SLAPD_MONITOR_BACKEND, SLAPD_MONITOR_BACKEND_NAME,
NULL, NULL, NULL,
MONITOR_F_PERSISTENT_CH,
monitor_subsys_backend_init,
NULL, /* update */
- NULL /* create */
+ NULL, /* create */
+ NULL /* modify */
}, {
SLAPD_MONITOR_THREAD, SLAPD_MONITOR_THREAD_NAME,
NULL, NULL, NULL,
MONITOR_F_NONE,
- NULL, /* init */
+ monitor_subsys_thread_init,
monitor_subsys_thread_update,
- NULL /* create */
+ NULL, /* create */
+ NULL /* modify */
}, {
SLAPD_MONITOR_SASL, SLAPD_MONITOR_SASL_NAME,
NULL, NULL, NULL,
MONITOR_F_NONE,
NULL, /* init */
NULL, /* update */
- NULL /* create */
+ NULL, /* create */
+ NULL /* modify */
}, {
SLAPD_MONITOR_TLS, SLAPD_MONITOR_TLS_NAME,
NULL, NULL, NULL,
MONITOR_F_NONE,
NULL, /* init */
NULL, /* update */
- NULL /* create */
+ NULL, /* create */
+ NULL /* modify */
}, {
SLAPD_MONITOR_CONN, SLAPD_MONITOR_CONN_NAME,
NULL, NULL, NULL,
MONITOR_F_VOLATILE_CH,
monitor_subsys_conn_init,
monitor_subsys_conn_update,
- monitor_subsys_conn_create
+ monitor_subsys_conn_create,
+ NULL /* modify */
}, {
SLAPD_MONITOR_READW, SLAPD_MONITOR_READW_NAME,
NULL, NULL, NULL,
MONITOR_F_NONE,
NULL, /* init */
monitor_subsys_readw_update,
- NULL /* create */
+ NULL, /* create */
+ NULL /* modify */
}, {
SLAPD_MONITOR_WRITEW, SLAPD_MONITOR_WRITEW_NAME,
NULL, NULL, NULL,
MONITOR_F_NONE,
NULL, /* init */
monitor_subsys_writew_update,
- NULL /* create */
+ NULL, /* create */
+ NULL /* modify */
+ }, {
+ SLAPD_MONITOR_LOG, SLAPD_MONITOR_LOG_NAME,
+ NULL, NULL, NULL,
+ MONITOR_F_NONE,
+ monitor_subsys_log_init,
+ NULL, /* update */
+ NULL, /* create */
+ monitor_subsys_log_modify
}, { -1, NULL }
};
bi->bi_db_close = NULL;
bi->bi_db_destroy = monitor_back_db_destroy;
- bi->bi_op_bind = NULL;
+ bi->bi_op_bind = monitor_back_bind;
bi->bi_op_unbind = NULL;
bi->bi_op_search = monitor_back_search;
bi->bi_op_compare = monitor_back_compare;
- bi->bi_op_modify = NULL;
+ bi->bi_op_modify = monitor_back_modify;
bi->bi_op_modrdn = NULL;
bi->bi_op_add = NULL;
bi->bi_op_delete = NULL;
Entry *e, *e_tmp;
struct monitorentrypriv *mp;
int i;
- char buf[1024];
+ char buf[1024], *ndn;
const char *text;
if ( monitor_defined ) {
}
monitor_defined++;
- charray_add( &be->be_suffix, SLAPD_MONITOR_DN );
- ber_bvecadd( &be->be_nsuffix, ber_bvstr( SLAPD_MONITOR_NDN ));
+ ndn = ch_strdup( SLAPD_MONITOR_DN );
+ charray_add( &be->be_suffix, ndn );
+ dn_normalize( ndn );
+ ber_bvecadd( &be->be_nsuffix, ber_bvstr( ndn ) );
+ ch_free( ndn );
mi = ( struct monitorinfo * )ch_calloc( sizeof( struct monitorinfo ), 1 );
ldap_pvt_thread_mutex_init( &mi->mi_cache_mutex );
{
BackendDB *be;
struct monitorsubsys *ms;
+ char *ndn;
/*
* adds the monitor backend
*/
- be = select_backend( SLAPD_MONITOR_NDN, 0 );
+ ndn = ch_strdup( SLAPD_MONITOR_DN );
+ dn_normalize( ndn );
+ be = select_backend( ndn , 0 );
+ ch_free( ndn );
if ( be == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
--- /dev/null
+/* log.c - deal with log subsystem */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * Copyright 2001 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ *
+ * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
+ *
+ * This work has beed deveolped for the OpenLDAP Foundation
+ * in the hope that it may be useful to the Open Source community,
+ * but WITHOUT ANY WARRANTY.
+ *
+ * Permission is granted to anyone to use this software for any purpose
+ * on any computer system, and to alter it and redistribute it, subject
+ * to the following restrictions:
+ *
+ * 1. The author and SysNet s.n.c. are not responsible for the consequences
+ * of use of this software, no matter how awful, even if they arise from
+ * flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission. Since few users ever read sources,
+ * credits should appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software. Since few users
+ * ever read sources, credits should appear in the documentation.
+ * SysNet s.n.c. cannot be responsible for the consequences of the
+ * alterations.
+ *
+ * 4. This notice may not be removed or altered.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+
+#include "slap.h"
+#include "lutil.h"
+#include "ldif.h"
+#include "back-monitor.h"
+
+/*
+ * log mutex
+ */
+ldap_pvt_thread_mutex_t monitor_log_mutex;
+
+static struct {
+ int i;
+ const char *s;
+} int_2_level[] = {
+ { LDAP_DEBUG_TRACE, "Trace" },
+ { LDAP_DEBUG_PACKETS, "Packets" },
+ { LDAP_DEBUG_ARGS, "Args" },
+ { LDAP_DEBUG_CONNS, "Conns" },
+ { LDAP_DEBUG_BER, "BER" },
+ { LDAP_DEBUG_FILTER, "Filter" },
+ { LDAP_DEBUG_CONFIG, "Config" }, /* useless */
+ { LDAP_DEBUG_ACL, "ACL" },
+ { LDAP_DEBUG_STATS, "Stats" },
+ { LDAP_DEBUG_STATS2, "Stats2" },
+ { LDAP_DEBUG_SHELL, "Shell" },
+ { LDAP_DEBUG_PARSE, "Parse" },
+ { LDAP_DEBUG_CACHE, "Cache" },
+ { LDAP_DEBUG_INDEX, "Index" },
+ { 0, NULL }
+};
+
+static int loglevel2int( const char *str );
+static const char * int2loglevel( int n );
+
+static int add_values( Entry *e, Modification *mod, int *newlevel );
+static int delete_values( Entry *e, Modification *mod, int *newlevel );
+static int replace_values( Entry *e, Modification *mod, int *newlevel );
+
+/*
+ * initializes log subentry
+ */
+int
+monitor_subsys_log_init(
+ BackendDB *be
+)
+{
+ struct monitorinfo *mi;
+ Entry *e;
+ int i;
+ struct monitorentrypriv *mp;
+ struct berval val, *bv[2] = { &val, NULL };
+
+ ldap_pvt_thread_mutex_init( &monitor_log_mutex );
+
+ mi = ( struct monitorinfo * )be->be_private;
+
+ if ( monitor_cache_get( mi, monitor_subsys[SLAPD_MONITOR_LOG].mss_ndn,
+ &e ) ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
+ "monitor_subsys_log_init: "
+ "unable to get entry '%s'\n",
+ monitor_subsys[SLAPD_MONITOR_LOG].mss_ndn ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "monitor_subsys_log_init: "
+ "unable to get entry '%s'\n%s%s",
+ monitor_subsys[SLAPD_MONITOR_LOG].mss_ndn,
+ "", "" );
+#endif
+ return( -1 );
+ }
+
+ /* initialize the debug level */
+ for ( i = 0; int_2_level[ i ].i != 0; i++ ) {
+ if ( int_2_level[ i ].i & ldap_syslog ) {
+ val.bv_val = ( char * )int_2_level[ i ].s;
+ val.bv_len = strlen( val.bv_val );
+
+ attr_merge( e, monitor_ad_desc, bv );
+ }
+ }
+
+ monitor_cache_release( mi, e );
+
+ return( 0 );
+}
+
+int
+monitor_subsys_log_modify(
+ struct monitorinfo *mi,
+ Entry *e,
+ Modifications *modlist
+)
+{
+ int rc = LDAP_OTHER;
+ int newlevel = ldap_syslog;
+ Attribute *save_attrs;
+ Modifications *ml;
+
+ ldap_pvt_thread_mutex_lock( &monitor_log_mutex );
+
+ save_attrs = e->e_attrs;
+ e->e_attrs = attrs_dup( e->e_attrs );
+
+ for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
+ Modification *mod = &ml->sml_mod;
+
+ /*
+ * Operational attributes
+ */
+#if 0
+ if ( mod->sm_desc == slap_schema.si_ad_modifyTimestamp
+ || mod->sm_desc == slap_schema.si_ad_modifiersName ) {
+ ( void ) attr_delete( &e->e_attrs, mod->sm_desc );
+ rc = attr_merge( e, mod->sm_desc, mod->sm_bvalues );
+ if ( rc != 0 ) {
+ rc = LDAP_OTHER;
+ break;
+ }
+ continue;
+
+ /*
+ * unhandled operational attributes
+ */
+ } else if ( is_at_operational( mod->sm_desc->ad_type ) ) {
+ continue;
+
+#else
+ if ( is_at_operational( mod->sm_desc->ad_type ) ) {
+ ( void ) attr_delete( &e->e_attrs, mod->sm_desc );
+ rc = attr_merge( e, mod->sm_desc, mod->sm_bvalues );
+ if ( rc != 0 ) {
+ rc = LDAP_OTHER;
+ break;
+ }
+ continue;
+
+#endif
+ /*
+ * only the monitor description attribute can be modified
+ */
+ } else if ( mod->sm_desc != monitor_ad_desc ) {
+ rc = LDAP_UNWILLING_TO_PERFORM;
+ break;
+ }
+
+ switch ( mod->sm_op ) {
+ case LDAP_MOD_ADD:
+ rc = add_values( e, mod, &newlevel );
+ break;
+
+ case LDAP_MOD_DELETE:
+ rc = delete_values( e, mod, &newlevel );
+ break;
+
+ case LDAP_MOD_REPLACE:
+ rc = replace_values( e, mod, &newlevel );
+ break;
+
+ default:
+ rc = LDAP_OPERATIONS_ERROR;
+ break;
+ }
+
+ if ( rc != LDAP_SUCCESS ) {
+ break;
+ }
+ }
+
+ /* set the new debug level */
+ if ( rc == LDAP_SUCCESS ) {
+ const char *text;
+ static char textbuf[1024];
+
+#if 0 /* need op */
+ /* check for abandon */
+ ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
+ if ( op->o_abandon ) {
+ ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
+ rc = SLAPD_ABANDON;
+
+ goto cleanup;
+ }
+#endif
+
+ /* check that the entry still obeys the schema */
+ rc = entry_schema_check( e, save_attrs, &text, textbuf,
+ sizeof( textbuf ) );
+ if ( rc != LDAP_SUCCESS ) {
+ goto cleanup;
+ }
+
+ ldap_syslog = newlevel;
+
+#if 0
+ slap_debug = newlevel;
+ lutil_set_debug_level( "slapd", slap_debug );
+ ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug);
+ ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &slap_debug);
+ ldif_debug = slap_debug;
+#endif
+ }
+
+cleanup:;
+ if ( rc == LDAP_SUCCESS ) {
+ attrs_free( save_attrs );
+
+ } else {
+ attrs_free( e->e_attrs );
+ e->e_attrs = save_attrs;
+ }
+
+ ldap_pvt_thread_mutex_unlock( &monitor_log_mutex );
+
+ return( rc );
+}
+
+static int
+loglevel2int( const char *str )
+{
+ int i;
+
+ for ( i = 0; int_2_level[ i ].i != 0; i++ ) {
+ if ( strcasecmp( str, int_2_level[ i ].s ) == 0 ) {
+ return int_2_level[ i ].i;
+ }
+ }
+
+ return 0;
+}
+
+static const char *
+int2loglevel( int n )
+{
+ int i;
+
+ for ( i = 0; int_2_level[ i ].i != 0; i++ ) {
+ if ( int_2_level[ i ].i == n ) {
+ return int_2_level[ i ].s;
+ }
+ }
+
+ return NULL;
+}
+
+static int
+check_constraints( Modification *mod, int *newlevel )
+{
+ int i;
+
+ for ( i = 0; mod->sm_bvalues && mod->sm_bvalues[i] != NULL; i++ ) {
+ int len, l;
+ const char *s;
+
+ l = loglevel2int( mod->sm_bvalues[i]->bv_val );
+ if ( !l ) {
+ return LDAP_CONSTRAINT_VIOLATION;
+ }
+
+ s = int2loglevel( l );
+ len = strlen( s );
+ assert( len == mod->sm_bvalues[i]->bv_len );
+
+ AC_MEMCPY( mod->sm_bvalues[i]->bv_val, s, len );
+
+ *newlevel |= l;
+ }
+
+ return LDAP_SUCCESS;
+}
+
+static int
+add_values( Entry *e, Modification *mod, int *newlevel )
+{
+ Attribute *a;
+ int i, rc;
+ MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
+
+ rc = check_constraints( mod, newlevel );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ a = attr_find( e->e_attrs, mod->sm_desc );
+
+ if ( a != NULL ) {
+
+ /* "description" SHOULD have appropriate rules ... */
+ if ( mr == NULL || !mr->smr_match ) {
+ return LDAP_INAPPROPRIATE_MATCHING;
+ }
+
+ for ( i = 0; mod->sm_bvalues[i] != NULL; i++ ) {
+ int rc;
+ int j;
+ const char *text = NULL;
+ struct berval *asserted;
+
+ rc = value_normalize( mod->sm_desc,
+ SLAP_MR_EQUALITY,
+ mod->sm_bvalues[i],
+ &asserted,
+ &text );
+
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ for ( j = 0; a->a_vals[j] != NULL; j++ ) {
+ int match;
+ int rc = value_match( &match, mod->sm_desc, mr,
+ SLAP_MR_VALUE_SYNTAX_MATCH,
+ a->a_vals[j], asserted, &text );
+
+ if ( rc == LDAP_SUCCESS && match == 0 ) {
+ ber_bvfree( asserted );
+ return LDAP_TYPE_OR_VALUE_EXISTS;
+ }
+ }
+
+ ber_bvfree( asserted );
+ }
+ }
+
+ /* no - add them */
+ if ( attr_merge( e, mod->sm_desc, mod->sm_bvalues ) != 0 ) {
+ /* this should return result return of attr_merge */
+ return LDAP_OTHER;
+ }
+
+ return LDAP_SUCCESS;
+}
+
+static int
+delete_values( Entry *e, Modification *mod, int *newlevel )
+{
+ int i, j, k, found, rc, nl = 0;
+ Attribute *a;
+ char *desc = mod->sm_desc->ad_cname.bv_val;
+ MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
+
+ rc = check_constraints( mod, &nl );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ *newlevel &= ~nl;
+
+ /* delete the entire attribute */
+ if ( mod->sm_bvalues == NULL ) {
+ int rc = attr_delete( &e->e_attrs, mod->sm_desc );
+
+ if ( rc ) {
+ rc = LDAP_NO_SUCH_ATTRIBUTE;
+ } else {
+ *newlevel = 0;
+ rc = LDAP_SUCCESS;
+ }
+ return rc;
+ }
+
+ if ( mr == NULL || !mr->smr_match ) {
+ /* disallow specific attributes from being deleted if
+ * no equality rule */
+ return LDAP_INAPPROPRIATE_MATCHING;
+ }
+
+ /* delete specific values - find the attribute first */
+ if ( (a = attr_find( e->e_attrs, mod->sm_desc )) == NULL ) {
+ return( LDAP_NO_SUCH_ATTRIBUTE );
+ }
+
+ /* find each value to delete */
+ for ( i = 0; mod->sm_bvalues[i] != NULL; i++ ) {
+ int rc;
+ const char *text = NULL;
+
+ struct berval *asserted;
+
+ rc = value_normalize( mod->sm_desc,
+ SLAP_MR_EQUALITY,
+ mod->sm_bvalues[i],
+ &asserted,
+ &text );
+
+ if( rc != LDAP_SUCCESS ) return rc;
+
+ found = 0;
+ for ( j = 0; a->a_vals[j] != NULL; j++ ) {
+ int match;
+ int rc = value_match( &match, mod->sm_desc, mr,
+ SLAP_MR_VALUE_SYNTAX_MATCH,
+ a->a_vals[j], asserted, &text );
+
+ if( rc == LDAP_SUCCESS && match != 0 ) {
+ continue;
+ }
+
+ /* found a matching value */
+ found = 1;
+
+ /* delete it */
+ ber_bvfree( a->a_vals[j] );
+ for ( k = j + 1; a->a_vals[k] != NULL; k++ ) {
+ a->a_vals[k - 1] = a->a_vals[k];
+ }
+ a->a_vals[k - 1] = NULL;
+
+ break;
+ }
+
+ ber_bvfree( asserted );
+
+ /* looked through them all w/o finding it */
+ if ( ! found ) {
+ return LDAP_NO_SUCH_ATTRIBUTE;
+ }
+ }
+
+ /* if no values remain, delete the entire attribute */
+ if ( a->a_vals[0] == NULL ) {
+ /* should already be zero */
+ *newlevel = 0;
+
+ if ( attr_delete( &e->e_attrs, mod->sm_desc ) ) {
+ return LDAP_NO_SUCH_ATTRIBUTE;
+ }
+ }
+
+ return LDAP_SUCCESS;
+}
+
+static int
+replace_values( Entry *e, Modification *mod, int *newlevel )
+{
+ int i, rc;
+
+ *newlevel = 0;
+ rc = check_constraints( mod, newlevel );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ rc = attr_delete( &e->e_attrs, mod->sm_desc );
+
+ if ( rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_ATTRIBUTE ) {
+ return rc;
+ }
+
+ if ( mod->sm_bvalues != NULL &&
+ attr_merge( e, mod->sm_desc, mod->sm_bvalues ) != 0 ) {
+ return LDAP_OTHER;
+ }
+
+ return LDAP_SUCCESS;
+}
+
/*
* threads
*/
+int monitor_subsys_thread_init LDAP_P(( BackendDB *be ));
int monitor_subsys_thread_update LDAP_P(( struct monitorinfo *mi, Entry *e ));
/*
*/
int monitor_subsys_writew_update LDAP_P(( struct monitorinfo *mi, Entry *e ));
+/*
+ * log
+ */
+int monitor_subsys_log_init LDAP_P(( BackendDB *be ));
+int monitor_subsys_log_modify LDAP_P(( struct monitorinfo *mi, Entry *e, Modifications *modlist ));
+
LDAP_END_DECL
#endif
{
struct monitorinfo *mi = (struct monitorinfo *) be->be_private;
int rc;
- Entry *e;
+ Entry *e, *matched = NULL;
int nentries = 0;
#ifdef NEW_LOGGING
/* get entry with reader lock */
- monitor_cache_dn2entry( mi, nbase, &e );
+ monitor_cache_dn2entry( mi, nbase, &e, &matched );
if ( e == NULL ) {
send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
- NULL, NULL, NULL, NULL );
+ matched ? matched->e_dn : NULL,
+ NULL, NULL, NULL );
+ if ( matched ) {
+ monitor_cache_release( mi, matched );
+ }
return( 0 );
}
#include "slap.h"
#include "back-monitor.h"
+/*
+* * initializes log subentry
+* */
+int
+monitor_subsys_thread_init(
+ BackendDB *be
+)
+{
+ struct monitorinfo *mi;
+ Entry *e;
+ struct monitorentrypriv *mp;
+ struct berval val, *bv[2] = { &val, NULL };
+ static char buf[1024];
+
+ mi = ( struct monitorinfo * )be->be_private;
+
+ if ( monitor_cache_get( mi,
+ monitor_subsys[SLAPD_MONITOR_THREAD].mss_ndn,
+ &e ) ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
+ "monitor_subsys_thread_init: "
+ "unable to get entry '%s'\n",
+ monitor_subsys[SLAPD_MONITOR_THREAD].mss_ndn ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "monitor_subsys_thread_init: "
+ "unable to get entry '%s'\n%s%s",
+ monitor_subsys[SLAPD_MONITOR_THREAD].mss_ndn,
+ "", "" );
+#endif
+ return( -1 );
+ }
+
+ /* initialize the thread number */
+ snprintf( buf, sizeof( buf ), "max=%d", connection_pool_max );
+
+ val.bv_val = buf;
+ val.bv_len = strlen( val.bv_val );
+
+ attr_merge( e, monitor_ad_desc, bv );
+
+ monitor_cache_release( mi, e );
+
+ return( 0 );
+}
int
monitor_subsys_thread_update(
bv[0] = &val;
bv[1] = NULL;
- snprintf( buf, sizeof( buf ), "threads=%d",
+ snprintf( buf, sizeof( buf ), "backload=%d",
ldap_pvt_thread_pool_backload( &connection_pool ) );
if ( ( a = attr_find( e->e_attrs, monitor_ad_desc ) ) != NULL ) {
for ( b = a->a_vals; b[0] != NULL; b++ ) {
- if ( strncmp( b[0]->bv_val, "threads=",
- sizeof( "threads=" ) - 1 ) == 0 ) {
- free( b[0]->bv_val );
+ if ( strncmp( b[0]->bv_val, "backload=",
+ sizeof( "backload=" ) - 1 ) == 0 ) {
+ ber_bvfree( b[0] );
b[0] = ber_bvstrdup( buf );
break;
}
ldap_pvt_thread_pool_maxthreads( &connection_pool, c );
+ /* save for later use */
+ connection_pool_max = c;
+
/* get pid file name */
} else if ( strcasecmp( cargv[0], "pidfile" ) == 0 ) {
if ( cargc < 2 ) {
* global variables that need mutex protection
*/
ldap_pvt_thread_pool_t connection_pool;
+int connection_pool_max = SLAP_MAX_WORKER_THREADS;
ldap_pvt_thread_mutex_t gmtime_mutex;
#if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
ldap_pvt_thread_mutex_t passwd_mutex;
(void) ldap_pvt_thread_initialize();
- ldap_pvt_thread_pool_init(&connection_pool, SLAP_MAX_WORKER_THREADS, 0);
+ ldap_pvt_thread_pool_init(&connection_pool, connection_pool_max, 0);
ldap_pvt_thread_mutex_init( &entry2str_mutex );
ldap_pvt_thread_mutex_init( &replog_mutex );
#define slap_get_time() time( NULL )
LDAP_SLAPD_V (ldap_pvt_thread_pool_t) connection_pool;
+LDAP_SLAPD_V (int) connection_pool_max;
LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) entry2str_mutex;
LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) replog_mutex;