1 /* log.c - deal with log subsystem */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/log.c,v 1.56.2.4 2008/02/11 23:26:47 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2001-2008 The OpenLDAP Foundation.
6 * Portions Copyright 2001-2003 Pierangelo Masarati.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
18 * This work was initially developed by Pierangelo Masarati for inclusion
19 * in OpenLDAP Software.
26 #include <ac/string.h>
32 #include "back-monitor.h"
35 monitor_subsys_log_open(
37 monitor_subsys_t
*ms
);
40 monitor_subsys_log_modify(
48 ldap_pvt_thread_mutex_t monitor_log_mutex
;
50 static int add_values( Operation
*op
, Entry
*e
, Modification
*mod
, int *newlevel
);
51 static int delete_values( Operation
*op
, Entry
*e
, Modification
*mod
, int *newlevel
);
52 static int replace_values( Operation
*op
, Entry
*e
, Modification
*mod
, int *newlevel
);
55 * initializes log subentry
58 monitor_subsys_log_init(
60 monitor_subsys_t
*ms
)
62 ms
->mss_open
= monitor_subsys_log_open
;
63 ms
->mss_modify
= monitor_subsys_log_modify
;
65 ldap_pvt_thread_mutex_init( &monitor_log_mutex
);
74 monitor_subsys_log_open(
76 monitor_subsys_t
*ms
)
80 if ( loglevel2bvarray( ldap_syslog
, &bva
) == 0 && bva
!= NULL
) {
84 mi
= ( monitor_info_t
* )be
->be_private
;
86 if ( monitor_cache_get( mi
, &ms
->mss_ndn
, &e
) ) {
87 Debug( LDAP_DEBUG_ANY
,
88 "monitor_subsys_log_init: "
89 "unable to get entry \"%s\"\n",
90 ms
->mss_ndn
.bv_val
, 0, 0 );
91 ber_bvarray_free( bva
);
95 attr_merge_normalize( e
, mi
->mi_ad_managedInfo
, bva
, NULL
);
96 ber_bvarray_free( bva
);
98 monitor_cache_release( mi
, e
);
105 monitor_subsys_log_modify(
110 monitor_info_t
*mi
= ( monitor_info_t
* )op
->o_bd
->be_private
;
112 int newlevel
= ldap_syslog
;
113 Attribute
*save_attrs
;
114 Modifications
*modlist
= op
->orm_modlist
;
117 ldap_pvt_thread_mutex_lock( &monitor_log_mutex
);
119 save_attrs
= e
->e_attrs
;
120 e
->e_attrs
= attrs_dup( e
->e_attrs
);
122 for ( ml
= modlist
; ml
!= NULL
; ml
= ml
->sml_next
) {
123 Modification
*mod
= &ml
->sml_mod
;
126 * accept all operational attributes;
127 * this includes modifersName and modifyTimestamp
130 if ( is_at_operational( mod
->sm_desc
->ad_type
) ) {
131 ( void ) attr_delete( &e
->e_attrs
, mod
->sm_desc
);
132 rc
= rs
->sr_err
= attr_merge( e
, mod
->sm_desc
,
133 mod
->sm_values
, mod
->sm_nvalues
);
134 if ( rc
!= LDAP_SUCCESS
) {
140 * only the "managedInfo" attribute can be modified
142 } else if ( mod
->sm_desc
!= mi
->mi_ad_managedInfo
) {
143 rc
= rs
->sr_err
= LDAP_UNWILLING_TO_PERFORM
;
147 switch ( mod
->sm_op
) {
149 rc
= add_values( op
, e
, mod
, &newlevel
);
152 case LDAP_MOD_DELETE
:
153 rc
= delete_values( op
, e
, mod
, &newlevel
);
156 case LDAP_MOD_REPLACE
:
157 rc
= replace_values( op
, e
, mod
, &newlevel
);
165 if ( rc
!= LDAP_SUCCESS
) {
171 /* set the new debug level */
172 if ( rc
== LDAP_SUCCESS
) {
174 static char textbuf
[ BACKMONITOR_BUFSIZE
];
176 /* check for abandon */
177 if ( op
->o_abandon
) {
178 rc
= rs
->sr_err
= SLAPD_ABANDON
;
183 /* check that the entry still obeys the schema */
184 rc
= entry_schema_check( op
, e
, save_attrs
, 0, 0,
185 &text
, textbuf
, sizeof( textbuf
) );
186 if ( rc
!= LDAP_SUCCESS
) {
192 * Do we need to protect this with a mutex?
194 ldap_syslog
= newlevel
;
196 #if 0 /* debug rather than log */
197 slap_debug
= newlevel
;
198 lutil_set_debug_level( "slapd", slap_debug
);
199 ber_set_option(NULL
, LBER_OPT_DEBUG_LEVEL
, &slap_debug
);
200 ldap_set_option(NULL
, LDAP_OPT_DEBUG_LEVEL
, &slap_debug
);
201 ldif_debug
= slap_debug
;
206 if ( rc
== LDAP_SUCCESS
) {
207 attrs_free( save_attrs
);
210 attrs_free( e
->e_attrs
);
211 e
->e_attrs
= save_attrs
;
214 ldap_pvt_thread_mutex_unlock( &monitor_log_mutex
);
216 if ( rc
== LDAP_SUCCESS
) {
217 rc
= SLAP_CB_CONTINUE
;
224 check_constraints( Modification
*mod
, int *newlevel
)
228 if ( mod
->sm_nvalues
!= NULL
) {
229 ber_bvarray_free( mod
->sm_nvalues
);
230 mod
->sm_nvalues
= NULL
;
233 for ( i
= 0; !BER_BVISNULL( &mod
->sm_values
[ i
] ); i
++ ) {
237 if ( str2loglevel( mod
->sm_values
[ i
].bv_val
, &l
) ) {
238 return LDAP_CONSTRAINT_VIOLATION
;
241 if ( loglevel2bv( l
, &bv
) ) {
242 return LDAP_CONSTRAINT_VIOLATION
;
245 assert( bv
.bv_len
== mod
->sm_values
[ i
].bv_len
);
247 AC_MEMCPY( mod
->sm_values
[ i
].bv_val
,
248 bv
.bv_val
, bv
.bv_len
);
257 add_values( Operation
*op
, Entry
*e
, Modification
*mod
, int *newlevel
)
261 MatchingRule
*mr
= mod
->sm_desc
->ad_type
->sat_equality
;
263 assert( mod
->sm_values
!= NULL
);
265 rc
= check_constraints( mod
, newlevel
);
266 if ( rc
!= LDAP_SUCCESS
) {
270 a
= attr_find( e
->e_attrs
, mod
->sm_desc
);
273 /* "managedInfo" SHOULD have appropriate rules ... */
274 if ( mr
== NULL
|| !mr
->smr_match
) {
275 return LDAP_INAPPROPRIATE_MATCHING
;
278 for ( i
= 0; !BER_BVISNULL( &mod
->sm_values
[ i
] ); i
++ ) {
281 const char *text
= NULL
;
282 struct berval asserted
;
284 rc
= asserted_value_validate_normalize(
285 mod
->sm_desc
, mr
, SLAP_MR_EQUALITY
,
286 &mod
->sm_values
[ i
], &asserted
, &text
,
289 if ( rc
!= LDAP_SUCCESS
) {
293 for ( j
= 0; !BER_BVISNULL( &a
->a_vals
[ j
] ); j
++ ) {
295 int rc
= value_match( &match
, mod
->sm_desc
, mr
,
296 0, &a
->a_nvals
[ j
], &asserted
, &text
);
298 if ( rc
== LDAP_SUCCESS
&& match
== 0 ) {
299 free( asserted
.bv_val
);
300 return LDAP_TYPE_OR_VALUE_EXISTS
;
304 free( asserted
.bv_val
);
309 rc
= attr_merge_normalize( e
, mod
->sm_desc
, mod
->sm_values
,
311 if ( rc
!= LDAP_SUCCESS
) {
319 delete_values( Operation
*op
, Entry
*e
, Modification
*mod
, int *newlevel
)
321 int i
, j
, k
, found
, rc
, nl
= 0;
323 MatchingRule
*mr
= mod
->sm_desc
->ad_type
->sat_equality
;
325 /* delete the entire attribute */
326 if ( mod
->sm_values
== NULL
) {
327 int rc
= attr_delete( &e
->e_attrs
, mod
->sm_desc
);
330 rc
= LDAP_NO_SUCH_ATTRIBUTE
;
339 rc
= check_constraints( mod
, &nl
);
340 if ( rc
!= LDAP_SUCCESS
) {
346 if ( mr
== NULL
|| !mr
->smr_match
) {
347 /* disallow specific attributes from being deleted if
348 * no equality rule */
349 return LDAP_INAPPROPRIATE_MATCHING
;
352 /* delete specific values - find the attribute first */
353 if ( (a
= attr_find( e
->e_attrs
, mod
->sm_desc
)) == NULL
) {
354 return( LDAP_NO_SUCH_ATTRIBUTE
);
357 /* find each value to delete */
358 for ( i
= 0; !BER_BVISNULL( &mod
->sm_values
[ i
] ); i
++ ) {
360 const char *text
= NULL
;
362 struct berval asserted
;
364 rc
= asserted_value_validate_normalize(
365 mod
->sm_desc
, mr
, SLAP_MR_EQUALITY
,
366 &mod
->sm_values
[ i
], &asserted
, &text
,
369 if( rc
!= LDAP_SUCCESS
) return rc
;
372 for ( j
= 0; !BER_BVISNULL( &a
->a_vals
[ j
] ); j
++ ) {
374 int rc
= value_match( &match
, mod
->sm_desc
, mr
,
375 0, &a
->a_nvals
[ j
], &asserted
, &text
);
377 if( rc
== LDAP_SUCCESS
&& match
!= 0 ) {
381 /* found a matching value */
385 if ( a
->a_nvals
!= a
->a_vals
) {
386 free( a
->a_nvals
[ j
].bv_val
);
387 for ( k
= j
+ 1; !BER_BVISNULL( &a
->a_nvals
[ k
] ); k
++ ) {
388 a
->a_nvals
[ k
- 1 ] = a
->a_nvals
[ k
];
390 BER_BVZERO( &a
->a_nvals
[ k
- 1 ] );
393 free( a
->a_vals
[ j
].bv_val
);
394 for ( k
= j
+ 1; !BER_BVISNULL( &a
->a_vals
[ k
] ); k
++ ) {
395 a
->a_vals
[ k
- 1 ] = a
->a_vals
[ k
];
397 BER_BVZERO( &a
->a_vals
[ k
- 1 ] );
403 free( asserted
.bv_val
);
405 /* looked through them all w/o finding it */
407 return LDAP_NO_SUCH_ATTRIBUTE
;
411 /* if no values remain, delete the entire attribute */
412 if ( BER_BVISNULL( &a
->a_vals
[ 0 ] ) ) {
413 assert( a
->a_numvals
== 0 );
415 /* should already be zero */
418 if ( attr_delete( &e
->e_attrs
, mod
->sm_desc
) ) {
419 return LDAP_NO_SUCH_ATTRIBUTE
;
427 replace_values( Operation
*op
, Entry
*e
, Modification
*mod
, int *newlevel
)
431 if ( mod
->sm_values
!= NULL
) {
433 rc
= check_constraints( mod
, newlevel
);
434 if ( rc
!= LDAP_SUCCESS
) {
439 rc
= attr_delete( &e
->e_attrs
, mod
->sm_desc
);
441 if ( rc
!= LDAP_SUCCESS
&& rc
!= LDAP_NO_SUCH_ATTRIBUTE
) {
445 if ( mod
->sm_values
!= NULL
) {
446 rc
= attr_merge_normalize( e
, mod
->sm_desc
, mod
->sm_values
,
448 if ( rc
!= LDAP_SUCCESS
) {