1 /* log.c - deal with log subsystem */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2003 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
17 * This work was initially developed by Pierangelo Masarati for inclusion
18 * in OpenLDAP Software.
20 /* This is an altered version */
22 * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
24 * This work has beed deveolped for the OpenLDAP Foundation
25 * in the hope that it may be useful to the Open Source community,
26 * but WITHOUT ANY WARRANTY.
28 * Permission is granted to anyone to use this software for any purpose
29 * on any computer system, and to alter it and redistribute it, subject
30 * to the following restrictions:
32 * 1. The author and SysNet s.n.c. are not responsible for the consequences
33 * of use of this software, no matter how awful, even if they arise from
36 * 2. The origin of this software must not be misrepresented, either by
37 * explicit claim or by omission. Since few users ever read sources,
38 * credits should appear in the documentation.
40 * 3. Altered versions must be plainly marked as such, and must not be
41 * misrepresented as being the original software. Since few users
42 * ever read sources, credits should appear in the documentation.
43 * SysNet s.n.c. cannot be responsible for the consequences of the
46 * 4. This notice may not be removed or altered.
53 #include <ac/string.h>
59 #include "back-monitor.h"
64 ldap_pvt_thread_mutex_t monitor_log_mutex;
71 { LDAP_DEBUG_TRACE, BER_BVC("Trace"), { 0, NULL } },
72 { LDAP_DEBUG_PACKETS, BER_BVC("Packets"), { 0, NULL } },
73 { LDAP_DEBUG_ARGS, BER_BVC("Args"), { 0, NULL } },
74 { LDAP_DEBUG_CONNS, BER_BVC("Conns"), { 0, NULL } },
75 { LDAP_DEBUG_BER, BER_BVC("BER"), { 0, NULL } },
76 { LDAP_DEBUG_FILTER, BER_BVC("Filter"), { 0, NULL } },
77 { LDAP_DEBUG_CONFIG, BER_BVC("Config"), { 0, NULL } }, /* useless */
78 { LDAP_DEBUG_ACL, BER_BVC("ACL"), { 0, NULL } },
79 { LDAP_DEBUG_STATS, BER_BVC("Stats"), { 0, NULL } },
80 { LDAP_DEBUG_STATS2, BER_BVC("Stats2"), { 0, NULL } },
81 { LDAP_DEBUG_SHELL, BER_BVC("Shell"), { 0, NULL } },
82 { LDAP_DEBUG_PARSE, BER_BVC("Parse"), { 0, NULL } },
83 { LDAP_DEBUG_CACHE, BER_BVC("Cache"), { 0, NULL } },
84 { LDAP_DEBUG_INDEX, BER_BVC("Index"), { 0, NULL } },
85 { 0, { 0, NULL }, { 0, NULL } }
88 static int loglevel2int( struct berval *l );
89 static int int2loglevel( int n );
91 static int add_values( Entry *e, Modification *mod, int *newlevel );
92 static int delete_values( Entry *e, Modification *mod, int *newlevel );
93 static int replace_values( Entry *e, Modification *mod, int *newlevel );
96 * initializes log subentry
99 monitor_subsys_log_init(
103 struct monitorinfo *mi;
106 struct berval desc[] = {
107 BER_BVC("This entry allows to set the log level runtime."),
108 BER_BVC("Set the attribute 'managedInfo' to the desired log levels."),
112 ldap_pvt_thread_mutex_init( &monitor_log_mutex );
114 mi = ( struct monitorinfo * )be->be_private;
116 if ( monitor_cache_get( mi, &monitor_subsys[SLAPD_MONITOR_LOG].mss_ndn,
119 LDAP_LOG( OPERATION, CRIT,
120 "monitor_subsys_log_init: "
121 "unable to get entry '%s'\n",
122 monitor_subsys[SLAPD_MONITOR_LOG].mss_ndn.bv_val, 0, 0 );
124 Debug( LDAP_DEBUG_ANY,
125 "monitor_subsys_log_init: "
126 "unable to get entry '%s'\n%s%s",
127 monitor_subsys[SLAPD_MONITOR_LOG].mss_ndn.bv_val,
133 /* initialize the debug level(s) */
134 for ( i = 0; int_2_level[ i ].i != 0; i++ ) {
136 if ( mi->mi_ad_managedInfo->ad_type->sat_equality->smr_normalize ) {
139 rc = (*mi->mi_ad_managedInfo->ad_type->sat_equality->smr_normalize)(
140 SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
141 mi->mi_ad_managedInfo->ad_type->sat_syntax,
142 mi->mi_ad_managedInfo->ad_type->sat_equality,
144 &int_2_level[ i ].n, NULL );
150 if ( int_2_level[ i ].i & ldap_syslog ) {
151 attr_merge_one( e, mi->mi_ad_managedInfo,
153 &int_2_level[ i ].n );
157 attr_merge( e, mi->mi_ad_description, desc, NULL );
159 monitor_cache_release( mi, e );
165 monitor_subsys_log_modify(
170 struct monitorinfo *mi = (struct monitorinfo *)op->o_bd->be_private;
172 int newlevel = ldap_syslog;
173 Attribute *save_attrs;
174 Modifications *modlist = op->oq_modify.rs_modlist;
177 ldap_pvt_thread_mutex_lock( &monitor_log_mutex );
179 save_attrs = e->e_attrs;
180 e->e_attrs = attrs_dup( e->e_attrs );
182 for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
183 Modification *mod = &ml->sml_mod;
186 * accept all operational attributes
188 if ( is_at_operational( mod->sm_desc->ad_type ) ) {
189 ( void ) attr_delete( &e->e_attrs, mod->sm_desc );
190 rc = attr_merge( e, mod->sm_desc, mod->sm_bvalues,
199 * only the monitor description attribute can be modified
201 } else if ( mod->sm_desc != mi->mi_ad_managedInfo) {
202 rc = LDAP_UNWILLING_TO_PERFORM;
206 switch ( mod->sm_op ) {
208 rc = add_values( e, mod, &newlevel );
211 case LDAP_MOD_DELETE:
212 rc = delete_values( e, mod, &newlevel );
215 case LDAP_MOD_REPLACE:
216 rc = replace_values( e, mod, &newlevel );
224 if ( rc != LDAP_SUCCESS ) {
229 /* set the new debug level */
230 if ( rc == LDAP_SUCCESS ) {
232 static char textbuf[ BACKMONITOR_BUFSIZE ];
234 /* check for abandon */
235 if ( op->o_abandon ) {
241 /* check that the entry still obeys the schema */
242 rc = entry_schema_check( be_monitor, e, save_attrs,
243 &text, textbuf, sizeof( textbuf ) );
244 if ( rc != LDAP_SUCCESS ) {
249 * Do we need to protect this with a mutex?
251 ldap_syslog = newlevel;
253 #if 0 /* debug rather than log */
254 slap_debug = newlevel;
255 lutil_set_debug_level( "slapd", slap_debug );
256 ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug);
257 ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &slap_debug);
258 ldif_debug = slap_debug;
263 if ( rc == LDAP_SUCCESS ) {
264 attrs_free( save_attrs );
267 attrs_free( e->e_attrs );
268 e->e_attrs = save_attrs;
271 ldap_pvt_thread_mutex_unlock( &monitor_log_mutex );
277 loglevel2int( struct berval *l )
281 for ( i = 0; int_2_level[ i ].i != 0; i++ ) {
282 if ( l->bv_len != int_2_level[ i ].s.bv_len ) {
286 if ( strcasecmp( l->bv_val, int_2_level[ i ].s.bv_val ) == 0 ) {
287 return int_2_level[ i ].i;
295 int2loglevel( int n )
299 for ( i = 0; int_2_level[ i ].i != 0; i++ ) {
300 if ( int_2_level[ i ].i == n ) {
309 check_constraints( Modification *mod, int *newlevel )
313 for ( i = 0; mod->sm_bvalues && mod->sm_bvalues[i].bv_val != NULL; i++ ) {
316 l = loglevel2int( &mod->sm_bvalues[i] );
318 return LDAP_CONSTRAINT_VIOLATION;
321 if ( ( l = int2loglevel( l ) ) == -1 ) {
325 assert( int_2_level[ l ].s.bv_len
326 == mod->sm_bvalues[i].bv_len );
328 AC_MEMCPY( mod->sm_bvalues[i].bv_val,
329 int_2_level[ l ].s.bv_val,
330 int_2_level[ l ].s.bv_len );
332 AC_MEMCPY( mod->sm_nvalues[i].bv_val,
333 int_2_level[ l ].n.bv_val,
334 int_2_level[ l ].n.bv_len );
343 add_values( Entry *e, Modification *mod, int *newlevel )
347 MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
349 rc = check_constraints( mod, newlevel );
350 if ( rc != LDAP_SUCCESS ) {
354 a = attr_find( e->e_attrs, mod->sm_desc );
357 /* "description" SHOULD have appropriate rules ... */
358 if ( mr == NULL || !mr->smr_match ) {
359 return LDAP_INAPPROPRIATE_MATCHING;
362 for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) {
365 const char *text = NULL;
366 struct berval asserted;
368 rc = asserted_value_validate_normalize(
369 mod->sm_desc, mr, SLAP_MR_EQUALITY,
370 &mod->sm_bvalues[i], &asserted, &text, NULL );
372 if ( rc != LDAP_SUCCESS ) {
376 for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) {
378 int rc = value_match( &match, mod->sm_desc, mr,
380 &a->a_vals[j], &asserted, &text );
382 if ( rc == LDAP_SUCCESS && match == 0 ) {
383 free( asserted.bv_val );
384 return LDAP_TYPE_OR_VALUE_EXISTS;
388 free( asserted.bv_val );
393 rc = attr_merge( e, mod->sm_desc, mod->sm_bvalues, mod->sm_nvalues );
394 if ( rc != LDAP_SUCCESS ) {
395 /* this should return result of attr_mergeit */
403 delete_values( Entry *e, Modification *mod, int *newlevel )
405 int i, j, k, found, rc, nl = 0;
407 MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
409 rc = check_constraints( mod, &nl );
410 if ( rc != LDAP_SUCCESS ) {
416 /* delete the entire attribute */
417 if ( mod->sm_bvalues == NULL ) {
418 int rc = attr_delete( &e->e_attrs, mod->sm_desc );
421 rc = LDAP_NO_SUCH_ATTRIBUTE;
429 if ( mr == NULL || !mr->smr_match ) {
430 /* disallow specific attributes from being deleted if
431 * no equality rule */
432 return LDAP_INAPPROPRIATE_MATCHING;
435 /* delete specific values - find the attribute first */
436 if ( (a = attr_find( e->e_attrs, mod->sm_desc )) == NULL ) {
437 return( LDAP_NO_SUCH_ATTRIBUTE );
440 /* find each value to delete */
441 for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) {
443 const char *text = NULL;
445 struct berval asserted;
447 rc = asserted_value_validate_normalize(
448 mod->sm_desc, mr, SLAP_MR_EQUALITY,
449 &mod->sm_bvalues[i], &asserted, &text, NULL );
451 if( rc != LDAP_SUCCESS ) return rc;
454 for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) {
456 int rc = value_match( &match, mod->sm_desc, mr,
458 &a->a_vals[j], &asserted, &text );
460 if( rc == LDAP_SUCCESS && match != 0 ) {
464 /* found a matching value */
468 free( a->a_vals[j].bv_val );
469 for ( k = j + 1; a->a_vals[k].bv_val != NULL; k++ ) {
470 a->a_vals[k - 1] = a->a_vals[k];
472 a->a_vals[k - 1].bv_val = NULL;
477 free( asserted.bv_val );
479 /* looked through them all w/o finding it */
481 return LDAP_NO_SUCH_ATTRIBUTE;
485 /* if no values remain, delete the entire attribute */
486 if ( a->a_vals[0].bv_val == NULL ) {
487 /* should already be zero */
490 if ( attr_delete( &e->e_attrs, mod->sm_desc ) ) {
491 return LDAP_NO_SUCH_ATTRIBUTE;
499 replace_values( Entry *e, Modification *mod, int *newlevel )
504 rc = check_constraints( mod, newlevel );
505 if ( rc != LDAP_SUCCESS ) {
509 rc = attr_delete( &e->e_attrs, mod->sm_desc );
511 if ( rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_ATTRIBUTE ) {
515 if ( mod->sm_bvalues != NULL ) {
516 rc = attr_merge( e, mod->sm_desc, mod->sm_bvalues,
518 if ( rc != LDAP_SUCCESS ) {