/* log.c - deal with log subsystem */
-/*
- * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2001-2009 The OpenLDAP Foundation.
+ * Portions Copyright 2001-2003 Pierangelo Masarati.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
*/
-/*
- * 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.
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by Pierangelo Masarati for inclusion
+ * in OpenLDAP Software.
*/
#include "portable.h"
#include <ac/string.h>
#include "slap.h"
+#include <lber_pvt.h>
#include "lutil.h"
#include "ldif.h"
#include "back-monitor.h"
+static int
+monitor_subsys_log_open(
+ BackendDB *be,
+ monitor_subsys_t *ms );
+
+static int
+monitor_subsys_log_modify(
+ Operation *op,
+ SlapReply *rs,
+ Entry *e );
+
/*
* 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 );
+static int add_values( Operation *op, Entry *e, Modification *mod, int *newlevel );
+static int delete_values( Operation *op, Entry *e, Modification *mod, int *newlevel );
+static int replace_values( Operation *op, Entry *e, Modification *mod, int *newlevel );
/*
* initializes log subentry
*/
int
monitor_subsys_log_init(
- BackendDB *be
-)
+ BackendDB *be,
+ monitor_subsys_t *ms )
{
- struct monitorinfo *mi;
- Entry *e;
- int i;
- struct monitorentrypriv *mp;
- struct berval val, *bv[2] = { &val, NULL };
+ ms->mss_open = monitor_subsys_log_open;
+ ms->mss_modify = monitor_subsys_log_modify;
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 );
- }
+ return( 0 );
+}
- /* 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 );
+/*
+ * opens log subentry
+ */
+int
+monitor_subsys_log_open(
+ BackendDB *be,
+ monitor_subsys_t *ms )
+{
+ BerVarray bva = NULL;
- attr_merge( e, monitor_ad_desc, bv );
+ if ( loglevel2bvarray( ldap_syslog, &bva ) == 0 && bva != NULL ) {
+ monitor_info_t *mi;
+ Entry *e;
+
+ mi = ( monitor_info_t * )be->be_private;
+
+ if ( monitor_cache_get( mi, &ms->mss_ndn, &e ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "monitor_subsys_log_init: "
+ "unable to get entry \"%s\"\n",
+ ms->mss_ndn.bv_val, 0, 0 );
+ ber_bvarray_free( bva );
+ return( -1 );
}
- }
- monitor_cache_release( mi, e );
+ attr_merge_normalize( e, mi->mi_ad_managedInfo, bva, NULL );
+ ber_bvarray_free( bva );
+
+ monitor_cache_release( mi, e );
+ }
return( 0 );
}
-int
+static int
monitor_subsys_log_modify(
- struct monitorinfo *mi,
- Entry *e,
- Modifications *modlist
-)
+ Operation *op,
+ SlapReply *rs,
+ Entry *e )
{
+ monitor_info_t *mi = ( monitor_info_t * )op->o_bd->be_private;
int rc = LDAP_OTHER;
int newlevel = ldap_syslog;
Attribute *save_attrs;
+ Modifications *modlist = op->orm_modlist;
Modifications *ml;
ldap_pvt_thread_mutex_lock( &monitor_log_mutex );
Modification *mod = &ml->sml_mod;
/*
- * Operational attributes
+ * accept all operational attributes;
+ * this includes modifersName and modifyTimestamp
+ * if lastmod is "on"
*/
-#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;
+ rc = rs->sr_err = attr_merge( e, mod->sm_desc,
+ mod->sm_values, mod->sm_nvalues );
+ if ( rc != LDAP_SUCCESS ) {
break;
}
continue;
-#endif
/*
- * only the monitor description attribute can be modified
+ * only the "managedInfo" attribute can be modified
*/
- } else if ( mod->sm_desc != monitor_ad_desc ) {
- rc = LDAP_UNWILLING_TO_PERFORM;
+ } else if ( mod->sm_desc != mi->mi_ad_managedInfo ) {
+ rc = rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
break;
}
switch ( mod->sm_op ) {
case LDAP_MOD_ADD:
- rc = add_values( e, mod, &newlevel );
+ rc = add_values( op, e, mod, &newlevel );
break;
case LDAP_MOD_DELETE:
- rc = delete_values( e, mod, &newlevel );
+ rc = delete_values( op, e, mod, &newlevel );
break;
case LDAP_MOD_REPLACE:
- rc = replace_values( e, mod, &newlevel );
+ rc = replace_values( op, e, mod, &newlevel );
break;
default:
- rc = LDAP_OPERATIONS_ERROR;
+ rc = LDAP_OTHER;
break;
}
if ( rc != LDAP_SUCCESS ) {
+ rs->sr_err = rc;
break;
}
}
/* set the new debug level */
if ( rc == LDAP_SUCCESS ) {
- const char *text;
- static char textbuf[1024];
+ const char *text;
+ static char textbuf[ BACKMONITOR_BUFSIZE ];
-#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;
+ rc = rs->sr_err = SLAPD_ABANDON;
goto cleanup;
}
-#endif
/* check that the entry still obeys the schema */
- rc = entry_schema_check( e, save_attrs, &text, textbuf,
- sizeof( textbuf ) );
+ rc = entry_schema_check( op, e, save_attrs, 0, 0, NULL,
+ &text, textbuf, sizeof( textbuf ) );
if ( rc != LDAP_SUCCESS ) {
+ rs->sr_err = rc;
goto cleanup;
}
+ /*
+ * Do we need to protect this with a mutex?
+ */
ldap_syslog = newlevel;
-#if 0
+#if 0 /* debug rather than log */
slap_debug = newlevel;
lutil_set_debug_level( "slapd", slap_debug );
ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug);
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;
- }
+ if ( rc == LDAP_SUCCESS ) {
+ rc = SLAP_CB_CONTINUE;
}
- return NULL;
+ return rc;
}
static int
{
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 ) {
+ if ( mod->sm_nvalues != NULL ) {
+ ber_bvarray_free( mod->sm_nvalues );
+ mod->sm_nvalues = NULL;
+ }
+
+ for ( i = 0; !BER_BVISNULL( &mod->sm_values[ i ] ); i++ ) {
+ int l;
+ struct berval bv;
+
+ if ( str2loglevel( mod->sm_values[ i ].bv_val, &l ) ) {
return LDAP_CONSTRAINT_VIOLATION;
}
- s = int2loglevel( l );
- len = strlen( s );
- assert( len == mod->sm_bvalues[i]->bv_len );
+ if ( loglevel2bv( l, &bv ) ) {
+ return LDAP_CONSTRAINT_VIOLATION;
+ }
- AC_MEMCPY( mod->sm_bvalues[i]->bv_val, s, len );
+ assert( bv.bv_len == mod->sm_values[ i ].bv_len );
+
+ AC_MEMCPY( mod->sm_values[ i ].bv_val,
+ bv.bv_val, bv.bv_len );
*newlevel |= l;
}
}
static int
-add_values( Entry *e, Modification *mod, int *newlevel )
+add_values( Operation *op, Entry *e, Modification *mod, int *newlevel )
{
Attribute *a;
int i, rc;
MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
+ assert( mod->sm_values != NULL );
+
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 ... */
+ /* "managedInfo" SHOULD have appropriate rules ... */
if ( mr == NULL || !mr->smr_match ) {
return LDAP_INAPPROPRIATE_MATCHING;
}
- for ( i = 0; mod->sm_bvalues[i] != NULL; i++ ) {
+ for ( i = 0; !BER_BVISNULL( &mod->sm_values[ i ] ); i++ ) {
int rc;
int j;
const char *text = NULL;
- struct berval *asserted = NULL;
+ struct berval asserted;
- rc = value_normalize( mod->sm_desc,
- SLAP_MR_EQUALITY,
- mod->sm_bvalues[i],
- &asserted,
- &text );
+ rc = asserted_value_validate_normalize(
+ mod->sm_desc, mr, SLAP_MR_EQUALITY,
+ &mod->sm_values[ i ], &asserted, &text,
+ op->o_tmpmemctx );
if ( rc != LDAP_SUCCESS ) {
return rc;
}
- for ( j = 0; a->a_vals[j] != NULL; j++ ) {
+ for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ ) {
int match;
int rc = value_match( &match, mod->sm_desc, mr,
- SLAP_MR_VALUE_SYNTAX_MATCH,
- a->a_vals[j], asserted, &text );
+ 0, &a->a_nvals[ j ], &asserted, &text );
if ( rc == LDAP_SUCCESS && match == 0 ) {
- ber_bvfree( asserted );
+ free( asserted.bv_val );
return LDAP_TYPE_OR_VALUE_EXISTS;
}
}
- ber_bvfree( asserted );
+ free( asserted.bv_val );
}
}
/* 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;
+ rc = attr_merge_normalize( e, mod->sm_desc, mod->sm_values,
+ op->o_tmpmemctx );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
}
return LDAP_SUCCESS;
}
static int
-delete_values( Entry *e, Modification *mod, int *newlevel )
+delete_values( Operation *op, 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;
+ MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
/* delete the entire attribute */
- if ( mod->sm_bvalues == NULL ) {
+ if ( mod->sm_values == 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;
}
+ rc = check_constraints( mod, &nl );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ *newlevel &= ~nl;
+
if ( mr == NULL || !mr->smr_match ) {
/* disallow specific attributes from being deleted if
* no equality rule */
}
/* find each value to delete */
- for ( i = 0; mod->sm_bvalues[i] != NULL; i++ ) {
+ for ( i = 0; !BER_BVISNULL( &mod->sm_values[ i ] ); i++ ) {
int rc;
const char *text = NULL;
- struct berval *asserted = NULL;
+ struct berval asserted;
- rc = value_normalize( mod->sm_desc,
- SLAP_MR_EQUALITY,
- mod->sm_bvalues[i],
- &asserted,
- &text );
+ rc = asserted_value_validate_normalize(
+ mod->sm_desc, mr, SLAP_MR_EQUALITY,
+ &mod->sm_values[ i ], &asserted, &text,
+ op->o_tmpmemctx );
if( rc != LDAP_SUCCESS ) return rc;
found = 0;
- for ( j = 0; a->a_vals[j] != NULL; j++ ) {
+ for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ ) {
int match;
int rc = value_match( &match, mod->sm_desc, mr,
- SLAP_MR_VALUE_SYNTAX_MATCH,
- a->a_vals[j], asserted, &text );
+ 0, &a->a_nvals[ j ], &asserted, &text );
if( rc == LDAP_SUCCESS && match != 0 ) {
continue;
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];
+ if ( a->a_nvals != a->a_vals ) {
+ free( a->a_nvals[ j ].bv_val );
+ for ( k = j + 1; !BER_BVISNULL( &a->a_nvals[ k ] ); k++ ) {
+ a->a_nvals[ k - 1 ] = a->a_nvals[ k ];
+ }
+ BER_BVZERO( &a->a_nvals[ k - 1 ] );
}
- a->a_vals[k - 1] = NULL;
+
+ free( a->a_vals[ j ].bv_val );
+ for ( k = j + 1; !BER_BVISNULL( &a->a_vals[ k ] ); k++ ) {
+ a->a_vals[ k - 1 ] = a->a_vals[ k ];
+ }
+ BER_BVZERO( &a->a_vals[ k - 1 ] );
+ a->a_numvals--;
break;
}
- ber_bvfree( asserted );
+ free( asserted.bv_val );
/* looked through them all w/o finding it */
if ( ! found ) {
}
/* if no values remain, delete the entire attribute */
- if ( a->a_vals[0] == NULL ) {
+ if ( BER_BVISNULL( &a->a_vals[ 0 ] ) ) {
+ assert( a->a_numvals == 0 );
+
/* should already be zero */
*newlevel = 0;
}
static int
-replace_values( Entry *e, Modification *mod, int *newlevel )
+replace_values( Operation *op, Entry *e, Modification *mod, int *newlevel )
{
- int i, rc;
+ int rc;
- *newlevel = 0;
- rc = check_constraints( mod, newlevel );
- if ( rc != LDAP_SUCCESS ) {
- return rc;
+ if ( mod->sm_values != NULL ) {
+ *newlevel = 0;
+ rc = check_constraints( mod, newlevel );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
}
rc = attr_delete( &e->e_attrs, mod->sm_desc );
return rc;
}
- if ( mod->sm_bvalues != NULL &&
- attr_merge( e, mod->sm_desc, mod->sm_bvalues ) != 0 ) {
- return LDAP_OTHER;
+ if ( mod->sm_values != NULL ) {
+ rc = attr_merge_normalize( e, mod->sm_desc, mod->sm_values,
+ op->o_tmpmemctx );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
}
return LDAP_SUCCESS;