]> git.sur5r.net Git - openldap/commitdiff
improvements to monitor backend: added a log entry that lists the current log level...
authorPierangelo Masarati <ando@openldap.org>
Mon, 10 Dec 2001 09:50:06 +0000 (09:50 +0000)
committerPierangelo Masarati <ando@openldap.org>
Mon, 10 Dec 2001 09:50:06 +0000 (09:50 +0000)
15 files changed:
include/ldap_defaults.h
servers/slapd/back-monitor/Makefile.in
servers/slapd/back-monitor/back-monitor.h
servers/slapd/back-monitor/cache.c
servers/slapd/back-monitor/compare.c
servers/slapd/back-monitor/entry.c
servers/slapd/back-monitor/external.h
servers/slapd/back-monitor/init.c
servers/slapd/back-monitor/log.c [new file with mode: 0644]
servers/slapd/back-monitor/proto-back-monitor.h
servers/slapd/back-monitor/search.c
servers/slapd/back-monitor/thread.c
servers/slapd/config.c
servers/slapd/init.c
servers/slapd/proto-slap.h

index 9d77e752538daed167f4002390df8ee4cfe2ffbd..c8cbcf2ef29412ef1fd6b75a4f3942e47d540fea 100644 (file)
@@ -220,7 +220,6 @@ Please try again later.\r\n"
 #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"
index 5e3ce20328cb7e36c8136502a2591bf169abb724..cd77e57d4186644809ea0f1a98d0c4e015a37578 100644 (file)
@@ -1,12 +1,12 @@
 # $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       
index 73c360a4092ebea45f3e5ca5105b63cb986502d9..97030eef499691b8ba24689a3de6273cc0e39b80 100644 (file)
@@ -144,6 +144,13 @@ struct monitorinfo {
 #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;
@@ -155,9 +162,16 @@ struct monitorsubsys {
 #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[];
@@ -172,7 +186,7 @@ extern int monitor_cache_cmp LDAP_P(( const void *c1, const void *c2 ));
 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 ));
 
@@ -182,6 +196,7 @@ 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
 
index b794b402334b2ec775c0338812acc444671ffacc..b6fdabe7383fe76b6085ff6a6c11e7e34dcd8078 100644 (file)
@@ -174,7 +174,8 @@ int
 monitor_cache_dn2entry(
                struct monitorinfo      *mi,
                const char              *ndn,
-               Entry                   **ep
+               Entry                   **ep,
+               Entry                   **matched
 )
 {
        int rc;
@@ -186,6 +187,9 @@ monitor_cache_dn2entry(
        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 ) {
@@ -194,7 +198,7 @@ monitor_cache_dn2entry(
 
        /* 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 );
        }
@@ -205,7 +209,12 @@ monitor_cache_dn2entry(
                /* 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 );
 }
index f4318c5e946f796a3726980550f1132d87cbfd71..acaf766bcbb6b2d22bcbd9ad5d4927c19a1beb4e 100644 (file)
@@ -51,6 +51,55 @@ monitor_back_compare(
        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 );
 }
 
index 036a6c511cb9d1a6ca5fed261efb907fd7c7d661..a4cdafd0853c1bad8002dd28856a61c94f2a86c6 100644 (file)
@@ -85,6 +85,28 @@ monitor_entry_create(
        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,
index f644744b939f643e1c1e356b2ba1269b1dfeaa40..6cf06e84c23616dc858503e2726b08b3e829bb51 100644 (file)
@@ -63,6 +63,15 @@ extern int   monitor_back_compare LDAP_P(( BackendDB *bd,
 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 */
index b7b0c51ea6292c556bc76f92834713faabf5ba8f..5b46dca3026eaba9081698b3e2c7b28f2fe80890 100644 (file)
@@ -61,63 +61,80 @@ struct monitorsubsys monitor_subsys[] = {
                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 }
 };
 
@@ -145,11 +162,11 @@ monitor_back_initialize(
        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;
@@ -189,7 +206,7 @@ monitor_back_db_init(
        Entry                   *e, *e_tmp;
        struct monitorentrypriv *mp;
        int                     i;
-       char                    buf[1024];
+       char                    buf[1024], *ndn;
        const char              *text;
 
        if ( monitor_defined ) {
@@ -205,8 +222,11 @@ monitor_back_db_init(
        }
        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 );
@@ -358,11 +378,15 @@ monitor_back_open(
 {
        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,
diff --git a/servers/slapd/back-monitor/log.c b/servers/slapd/back-monitor/log.c
new file mode 100644 (file)
index 0000000..f1e6835
--- /dev/null
@@ -0,0 +1,500 @@
+/* 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;
+}
+
index d0de827fca9d710a99b4e669c3d4e5cec3811f63..ca16fd5a59a3478ac3273339c90667680e22adb6 100644 (file)
@@ -60,6 +60,7 @@ int monitor_subsys_database_init LDAP_P(( BackendDB *be ));
 /*
  * threads
  */
+int monitor_subsys_thread_init LDAP_P(( BackendDB *be ));
 int monitor_subsys_thread_update LDAP_P(( struct monitorinfo *mi, Entry *e ));
 
 /*
@@ -79,5 +80,11 @@ int monitor_subsys_readw_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
index 27b9fb5efc6b1b2d86ff1d8a6a3aae17395b2b61..64f3b95e6d4f59beeb3fcb7a525851d85149ada9 100644 (file)
@@ -127,7 +127,7 @@ monitor_back_search(
 {
        struct monitorinfo      *mi = (struct monitorinfo *) be->be_private;
        int             rc;
-       Entry           *e;
+       Entry           *e, *matched = NULL;
        int             nentries = 0;
 
 #ifdef NEW_LOGGING
@@ -139,10 +139,14 @@ monitor_back_search(
 
 
        /* 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 );
        }
index 04b3fb6b6cd1cd74c0ca6b63760751af801513cc..b1e05f29d6de1dce20d2c9ae0f72bb8bf37b94d0 100644 (file)
 #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( 
@@ -55,15 +101,15 @@ 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;
                        }
index 5bf2a78ec9a7d6b48f13b0c0b0ae51ad25868e9f..20386a9afe577a6a012b0969c5cbc2b1cee65fc2 100644 (file)
@@ -446,6 +446,9 @@ read_config( const char *fname )
 
                        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 ) {
index 508650b36b22251f0b4ac29de40dc962790fdd67..c26fe7b8c0bbfe4deee90b75540562f5453230df 100644 (file)
@@ -39,6 +39,7 @@ char          **g_argv;
  * 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;
@@ -106,7 +107,7 @@ slap_init( int mode, const char *name )
        
                        (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 );
index 7df651706b521cc697b5fe88dbc25bfaf9971944..0b4b737c2e1e52180067478c9a20776309ae6e21 100644 (file)
@@ -921,6 +921,7 @@ LDAP_SLAPD_V (time_t)               starttime;
 #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;