1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 *
4 * Copyright 2021 The OpenLDAP Foundation.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
9 * Public License.
10 *
11 * A copy of this license is available in the file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
14 */
15
16 #include "portable.h"
17
18 #include <stdio.h>
19
20 #include <ac/errno.h>
21 #include <ac/param.h>
22 #include <ac/string.h>
23 #include <ac/time.h>
24 #include <ac/unistd.h>
25 #include <ac/ctype.h>
26
27 #include <sys/stat.h>
28 #include <sys/uio.h>
29 #include <fcntl.h>
30
31 #include "slap.h"
32 #include "ldif.h"
33
34 #include "slap-config.h"
35 #include "slap-cfglog.h"
36
37 static int config_syslog, active_syslog;
38
39 static char logfile_suffix[sizeof(".xx.gz")];
40 static char logfile_path[MAXPATHLEN - sizeof(logfile_suffix) -1];
41 static long logfile_fslimit;
42 static int logfile_age, logfile_only, logfile_max;
43
44 int slap_debug_orig;
45
46 ldap_pvt_thread_mutex_t logfile_mutex;
47
48 static off_t logfile_fsize;
49 static time_t logfile_fcreated;
50 static int logfile_fd = -1;
51 static char logpaths[2][MAXPATHLEN];
52 static int logpathlen;
53
54 void
slap_debug_print(const char * data)55 slap_debug_print( const char *data )
56 {
57 char prefix[sizeof("ssssssssssssssss.ffffffff 0xtttttttttttttttt ")];
58 struct iovec iov[2];
59 int rotate = 0;
60 #ifdef HAVE_CLOCK_GETTIME
61 struct timespec tv;
62 #define TS "%08x"
63 #define Tfrac tv.tv_nsec
64 #define gettime(tv) clock_gettime( CLOCK_REALTIME, tv )
65 #else
66 struct timeval tv;
67 #define TS "%05x"
68 #define Tfrac tv.tv_usec
69 #define gettime(tv) gettimeofday( tv, NULL )
70 #endif
71
72 gettime( &tv );
73 iov[0].iov_base = prefix;
74 iov[0].iov_len = sprintf( prefix, "%lx." TS " %p ",
75 (long)tv.tv_sec, (unsigned int)Tfrac, (void *)ldap_pvt_thread_self() );
76 iov[1].iov_base = (void *)data;
77 iov[1].iov_len = strlen( data );
78 if ( !logfile_only )
79 (void)!writev( 2, iov, 2 );
80 if ( logfile_fd >= 0 ) {
81 int len = iov[0].iov_len + iov[1].iov_len;
82 if ( logfile_fslimit || logfile_age ) {
83 ldap_pvt_thread_mutex_lock( &logfile_mutex );
84 if ( logfile_fslimit && logfile_fsize + len > logfile_fslimit )
85 rotate = 1;
86 if ( logfile_age && tv.tv_sec - logfile_fcreated >= logfile_age )
87 rotate |= 2;
88 if ( rotate ) {
89 close( logfile_fd );
90 logfile_fd = -1;
91 strcpy( logpaths[0]+logpathlen, ".tmp" );
92 rename( logfile_path, logpaths[0] );
93 logfile_open( logfile_path );
94 }
95 }
96 len = writev( logfile_fd, iov, 2 );
97 if ( len > 0 )
98 logfile_fsize += len;
99 if ( logfile_fslimit || logfile_age )
100 ldap_pvt_thread_mutex_unlock( &logfile_mutex );
101 }
102 if ( rotate ) {
103 int i;
104 for (i=logfile_max; i > 1; i--) {
105 sprintf( logpaths[0]+logpathlen, ".%02d", i );
106 sprintf( logpaths[1]+logpathlen, ".%02d", i-1 );
107 rename( logpaths[1], logpaths[0] );
108 }
109 sprintf( logpaths[0]+logpathlen, ".tmp" );
110 rename( logpaths[0], logpaths[1] );
111 }
112 }
113
114 void
logfile_close()115 logfile_close()
116 {
117 if ( logfile_fd >= 0 ) {
118 close( logfile_fd );
119 logfile_fd = -1;
120 }
121 logfile_path[0] = '\0';
122 }
123
124 int
logfile_open(const char * path)125 logfile_open( const char *path )
126 {
127 struct stat st;
128 int fd, saved_errno;
129
130 fd = open( path, O_CREAT|O_WRONLY, 0640 );
131 if ( fd < 0 ) {
132 saved_errno = errno;
133 fail:
134 logfile_only = 0; /* make sure something gets output */
135 return saved_errno;
136 }
137
138 if ( fstat( fd, &st ) ) {
139 saved_errno = errno;
140 close( fd );
141 goto fail;
142 }
143
144 if ( !logfile_path[0] ) {
145 logpathlen = strlen( path );
146 if ( logpathlen >= sizeof(logfile_path) ) {
147 saved_errno = ENAMETOOLONG;
148 goto fail;
149 }
150 strcpy( logfile_path, path );
151 strcpy( logpaths[0], path );
152 strcpy( logpaths[1], path );
153 }
154
155 logfile_fsize = st.st_size;
156 logfile_fcreated = st.st_ctime; /* not strictly true but close enough */
157 logfile_fd = fd;
158 lseek( fd, 0, SEEK_END );
159
160 return 0;
161 }
162
163 const char *
logfile_name()164 logfile_name()
165 {
166 return logfile_path[0] ? logfile_path : NULL;
167 }
168
169 #if defined(LDAP_DEBUG) && defined(LDAP_SYSLOG)
170 #ifdef LOG_LOCAL4
171 int
slap_parse_syslog_user(const char * arg,int * syslogUser)172 slap_parse_syslog_user( const char *arg, int *syslogUser )
173 {
174 static slap_verbmasks syslogUsers[] = {
175 { BER_BVC( "LOCAL0" ), LOG_LOCAL0 },
176 { BER_BVC( "LOCAL1" ), LOG_LOCAL1 },
177 { BER_BVC( "LOCAL2" ), LOG_LOCAL2 },
178 { BER_BVC( "LOCAL3" ), LOG_LOCAL3 },
179 { BER_BVC( "LOCAL4" ), LOG_LOCAL4 },
180 { BER_BVC( "LOCAL5" ), LOG_LOCAL5 },
181 { BER_BVC( "LOCAL6" ), LOG_LOCAL6 },
182 { BER_BVC( "LOCAL7" ), LOG_LOCAL7 },
183 #ifdef LOG_USER
184 { BER_BVC( "USER" ), LOG_USER },
185 #endif /* LOG_USER */
186 #ifdef LOG_DAEMON
187 { BER_BVC( "DAEMON" ), LOG_DAEMON },
188 #endif /* LOG_DAEMON */
189 { BER_BVNULL, 0 }
190 };
191 int i = verb_to_mask( arg, syslogUsers );
192
193 if ( BER_BVISNULL( &syslogUsers[ i ].word ) ) {
194 Debug( LDAP_DEBUG_ANY,
195 "unrecognized syslog user \"%s\".\n",
196 arg );
197 return 1;
198 }
199
200 *syslogUser = syslogUsers[ i ].mask;
201
202 return 0;
203 }
204 #endif /* LOG_LOCAL4 */
205
206 int
slap_parse_syslog_level(const char * arg,int * levelp)207 slap_parse_syslog_level( const char *arg, int *levelp )
208 {
209 static slap_verbmasks str2syslog_level[] = {
210 { BER_BVC( "EMERG" ), LOG_EMERG },
211 { BER_BVC( "ALERT" ), LOG_ALERT },
212 { BER_BVC( "CRIT" ), LOG_CRIT },
213 { BER_BVC( "ERR" ), LOG_ERR },
214 { BER_BVC( "WARNING" ), LOG_WARNING },
215 { BER_BVC( "NOTICE" ), LOG_NOTICE },
216 { BER_BVC( "INFO" ), LOG_INFO },
217 { BER_BVC( "DEBUG" ), LOG_DEBUG },
218 { BER_BVNULL, 0 }
219 };
220 int i = verb_to_mask( arg, str2syslog_level );
221 if ( BER_BVISNULL( &str2syslog_level[ i ].word ) ) {
222 Debug( LDAP_DEBUG_ANY,
223 "unknown syslog level \"%s\".\n",
224 arg );
225 return 1;
226 }
227
228 *levelp = str2syslog_level[ i ].mask;
229
230 return 0;
231 }
232 #endif /* LDAP_DEBUG && LDAP_SYSLOG */
233
234 static char **debug_unknowns;
235 static char **syslog_unknowns;
236
237 static int
parse_debug_unknowns(char ** unknowns,int * levelp)238 parse_debug_unknowns( char **unknowns, int *levelp )
239 {
240 int i, level, rc = 0;
241
242 for ( i = 0; unknowns[ i ] != NULL; i++ ) {
243 level = 0;
244 if ( str2loglevel( unknowns[ i ], &level )) {
245 fprintf( stderr,
246 "unrecognized log level \"%s\"\n", unknowns[ i ] );
247 rc = 1;
248 } else {
249 *levelp |= level;
250 }
251 }
252 return rc;
253 }
254
255 int
slap_parse_debug_level(const char * arg,int * levelp,int which)256 slap_parse_debug_level( const char *arg, int *levelp, int which )
257 {
258 int level;
259
260 if ( arg && arg[ 0 ] != '-' && !isdigit( (unsigned char) arg[ 0 ] ) )
261 {
262 int i;
263 char **levels;
264 char ***unknowns = which ? &syslog_unknowns : &debug_unknowns;
265
266 levels = ldap_str2charray( arg, "," );
267
268 for ( i = 0; levels[ i ] != NULL; i++ ) {
269 level = 0;
270
271 if ( str2loglevel( levels[ i ], &level ) ) {
272 /* remember this for later */
273 ldap_charray_add( unknowns, levels[ i ] );
274 fprintf( stderr,
275 "unrecognized log level \"%s\" (deferred)\n",
276 levels[ i ] );
277 } else {
278 *levelp |= level;
279 }
280 }
281
282 ldap_charray_free( levels );
283
284 } else {
285 int rc;
286
287 if ( arg[0] == '-' ) {
288 rc = lutil_atoix( &level, arg, 0 );
289 } else {
290 unsigned ulevel;
291
292 rc = lutil_atoux( &ulevel, arg, 0 );
293 level = (int)ulevel;
294 }
295
296 if ( rc ) {
297 fprintf( stderr,
298 "unrecognized log level "
299 "\"%s\"\n", arg );
300 return 1;
301 }
302
303 if ( level == 0 ) {
304 *levelp = 0;
305
306 } else {
307 *levelp |= level;
308 }
309 }
310
311 return 0;
312 }
313
314 int
slap_parse_debug_unknowns()315 slap_parse_debug_unknowns() {
316 int rc = 0;
317 if ( debug_unknowns ) {
318 rc = parse_debug_unknowns( debug_unknowns, &slap_debug );
319 ldap_charray_free( debug_unknowns );
320 debug_unknowns = NULL;
321 if ( rc )
322 goto leave;
323 ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug );
324 ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &slap_debug );
325 }
326 if ( syslog_unknowns ) {
327 rc = parse_debug_unknowns( syslog_unknowns, &ldap_syslog );
328 ldap_charray_free( syslog_unknowns );
329 syslog_unknowns = NULL;
330 }
331 leave:
332 return rc;
333 }
334
slap_check_unknown_level(char * levelstr,int level)335 void slap_check_unknown_level( char *levelstr, int level )
336 {
337 int i;
338
339 if ( debug_unknowns ) {
340 for ( i = 0; debug_unknowns[ i ]; i++ ) {
341 if ( !strcasecmp( debug_unknowns[ i ], levelstr )) {
342 slap_debug |= level;
343 break;
344 }
345 }
346 }
347
348 if ( syslog_unknowns ) {
349 for ( i = 0; syslog_unknowns[ i ]; i++ ) {
350 if ( !strcasecmp( syslog_unknowns[ i ], levelstr )) {
351 ldap_syslog |= level;
352 break;
353 }
354 }
355 }
356 }
357
358 static slap_verbmasks *loglevel_ops;
359
360 static int
loglevel_init(void)361 loglevel_init( void )
362 {
363 slap_verbmasks lo[] = {
364 { BER_BVC("Any"), (slap_mask_t) LDAP_DEBUG_ANY },
365 { BER_BVC("Trace"), LDAP_DEBUG_TRACE },
366 { BER_BVC("Packets"), LDAP_DEBUG_PACKETS },
367 { BER_BVC("Args"), LDAP_DEBUG_ARGS },
368 { BER_BVC("Conns"), LDAP_DEBUG_CONNS },
369 { BER_BVC("BER"), LDAP_DEBUG_BER },
370 { BER_BVC("Filter"), LDAP_DEBUG_FILTER },
371 { BER_BVC("Config"), LDAP_DEBUG_CONFIG },
372 { BER_BVC("ACL"), LDAP_DEBUG_ACL },
373 { BER_BVC("Stats"), LDAP_DEBUG_STATS },
374 { BER_BVC("Stats2"), LDAP_DEBUG_STATS2 },
375 { BER_BVC("Shell"), LDAP_DEBUG_SHELL },
376 { BER_BVC("Parse"), LDAP_DEBUG_PARSE },
377 #if 0 /* no longer used (nor supported) */
378 { BER_BVC("Cache"), LDAP_DEBUG_CACHE },
379 { BER_BVC("Index"), LDAP_DEBUG_INDEX },
380 #endif
381 { BER_BVC("Sync"), LDAP_DEBUG_SYNC },
382 { BER_BVC("None"), LDAP_DEBUG_NONE },
383 { BER_BVNULL, 0 }
384 };
385
386 return slap_verbmasks_init( &loglevel_ops, lo );
387 }
388
389 void
slap_loglevel_destroy(void)390 slap_loglevel_destroy( void )
391 {
392 if ( loglevel_ops ) {
393 (void)slap_verbmasks_destroy( loglevel_ops );
394 }
395 loglevel_ops = NULL;
396 }
397
398 static slap_mask_t loglevel_ignore[] = { -1, 0 };
399
400 int
slap_loglevel_get(struct berval * s,int * l)401 slap_loglevel_get( struct berval *s, int *l )
402 {
403 int rc;
404 slap_mask_t m, i;
405
406 if ( loglevel_ops == NULL ) {
407 loglevel_init();
408 }
409
410 for ( m = 0, i = 1; !BER_BVISNULL( &loglevel_ops[ i ].word ); i++ ) {
411 m |= loglevel_ops[ i ].mask;
412 }
413
414 for ( i = 1; m & i; i <<= 1 )
415 ;
416
417 if ( i == 0 ) {
418 return -1;
419 }
420
421 rc = slap_verbmasks_append( &loglevel_ops, i, s, loglevel_ignore );
422
423 if ( rc != 0 ) {
424 Debug( LDAP_DEBUG_ANY, "slap_loglevel_get(%lu, \"%s\") failed\n",
425 i, s->bv_val );
426
427 } else {
428 *l = i;
429 slap_check_unknown_level( s->bv_val, i );
430 }
431
432 return rc;
433 }
434
435 int
slap_syslog_get()436 slap_syslog_get()
437 {
438 return active_syslog;
439 }
440
441 void
slap_syslog_set(int l)442 slap_syslog_set( int l )
443 {
444 active_syslog = l;
445 if ( logfile_only ) {
446 slap_debug |= active_syslog;
447 ldap_syslog = 0;
448 } else {
449 ldap_syslog = active_syslog;
450 }
451 }
452
453 int
slap_debug_get()454 slap_debug_get()
455 {
456 return slap_debug_orig;
457 }
458
459 void
slap_debug_set(int l)460 slap_debug_set( int l )
461 {
462 slap_debug_orig = l;
463 if ( logfile_only )
464 slap_debug = slap_debug_orig | active_syslog;
465 else
466 slap_debug = slap_debug_orig;
467 ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug);
468 ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &slap_debug);
469 ldif_debug = slap_debug;
470 }
471
472 int
str2loglevel(const char * s,int * l)473 str2loglevel( const char *s, int *l )
474 {
475 int i;
476
477 if ( loglevel_ops == NULL ) {
478 loglevel_init();
479 }
480
481 i = verb_to_mask( s, loglevel_ops );
482
483 if ( BER_BVISNULL( &loglevel_ops[ i ].word ) ) {
484 return -1;
485 }
486
487 *l = loglevel_ops[ i ].mask;
488
489 return 0;
490 }
491
492 const char *
loglevel2str(int l)493 loglevel2str( int l )
494 {
495 struct berval bv = BER_BVNULL;
496
497 loglevel2bv( l, &bv );
498
499 return bv.bv_val;
500 }
501
502 int
loglevel2bv(int l,struct berval * bv)503 loglevel2bv( int l, struct berval *bv )
504 {
505 if ( loglevel_ops == NULL ) {
506 loglevel_init();
507 }
508
509 BER_BVZERO( bv );
510
511 return enum_to_verb( loglevel_ops, l, bv ) == -1;
512 }
513
514 int
loglevel2bvarray(int l,BerVarray * bva)515 loglevel2bvarray( int l, BerVarray *bva )
516 {
517 if ( loglevel_ops == NULL ) {
518 loglevel_init();
519 }
520
521 if ( l == 0 ) {
522 struct berval bv = BER_BVC("0");
523 return value_add_one( bva, &bv );
524 }
525
526 return mask_to_verbs( loglevel_ops, l, bva );
527 }
528
529 int
loglevel_print(FILE * out)530 loglevel_print( FILE *out )
531 {
532 int i;
533
534 if ( loglevel_ops == NULL ) {
535 loglevel_init();
536 }
537
538 fprintf( out, "Installed log subsystems:\n\n" );
539 for ( i = 0; !BER_BVISNULL( &loglevel_ops[ i ].word ); i++ ) {
540 unsigned mask = loglevel_ops[ i ].mask & 0xffffffffUL;
541 fprintf( out,
542 (mask == ((slap_mask_t) -1 & 0xffffffffUL)
543 ? "\t%-30s (-1, 0xffffffff)\n" : "\t%-30s (%u, 0x%x)\n"),
544 loglevel_ops[ i ].word.bv_val, mask, mask );
545 }
546
547 fprintf( out, "\nNOTE: custom log subsystems may be later installed "
548 "by specific code\n\n" );
549
550 return 0;
551 }
552
553 int
config_logging(ConfigArgs * c)554 config_logging(ConfigArgs *c) {
555 int i, rc;
556
557 if ( loglevel_ops == NULL ) {
558 loglevel_init();
559 }
560
561 if (c->op == SLAP_CONFIG_EMIT) {
562 switch(c->type) {
563 case CFG_LOGLEVEL:
564 /* Get default or commandline slapd setting */
565 if ( ldap_syslog && !config_syslog )
566 config_syslog = ldap_syslog;
567 rc = loglevel2bvarray( config_syslog, &c->rvalue_vals );
568 break;
569
570 case CFG_LOGFILE: {
571 const char *logfileName = logfile_name();
572 if ( logfileName && *logfileName )
573 c->value_string = ch_strdup( logfileName );
574 else
575 rc = 1;
576 }
577 break;
578 case CFG_LOGFILE_ONLY:
579 c->value_int = logfile_only;
580 break;
581 case CFG_LOGFILE_ROTATE:
582 rc = 1;
583 if ( logfile_max ) {
584 char buf[64];
585 struct berval bv;
586 bv.bv_len = snprintf( buf, sizeof(buf), "%d %ld %ld", logfile_max,
587 (long) logfile_fslimit / 1048576, (long) logfile_age / 3600 );
588 if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) {
589 bv.bv_val = buf;
590 value_add_one( &c->rvalue_vals, &bv );
591 rc = 0;
592 }
593 }
594 break;
595 default:
596 rc = 1;
597 }
598 return rc;
599 } else if ( c->op == LDAP_MOD_DELETE ) {
600 switch(c->type) {
601 case CFG_LOGLEVEL:
602 if ( !c->line ) {
603 config_syslog = 0;
604 } else {
605 i = verb_to_mask( c->line, loglevel_ops );
606 config_syslog &= ~loglevel_ops[i].mask;
607 }
608 goto reset;
609
610 case CFG_LOGFILE:
611 logfile_close();
612 break;
613
614 case CFG_LOGFILE_ONLY:
615 /* remove loglevel from debuglevel */
616 slap_debug = slap_debug_orig;
617 ldap_syslog = config_syslog;
618 break;
619
620 case CFG_LOGFILE_ROTATE:
621 logfile_max = logfile_fslimit = logfile_age = 0;
622 break;
623 default:
624 rc = 1;
625 }
626 return rc;
627 }
628
629 switch(c->type) {
630 case CFG_LOGLEVEL:
631 for( i=1; i < c->argc; i++ ) {
632 int level;
633
634 if ( isdigit((unsigned char)c->argv[i][0]) || c->argv[i][0] == '-' ) {
635 if( lutil_atoix( &level, c->argv[i], 0 ) != 0 ) {
636 snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse level", c->argv[0] );
637 Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
638 c->log, c->cr_msg, c->argv[i]);
639 return( 1 );
640 }
641 } else {
642 if ( str2loglevel( c->argv[i], &level ) ) {
643 snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown level", c->argv[0] );
644 Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
645 c->log, c->cr_msg, c->argv[i]);
646 return( 1 );
647 }
648 }
649 /* Explicitly setting a zero clears all the levels */
650 if ( level )
651 config_syslog |= level;
652 else
653 config_syslog = 0;
654 }
655
656 reset:
657 slap_debug = slap_debug_orig;
658 active_syslog = config_syslog;
659 if ( logfile_only ) {
660 slap_debug |= config_syslog;
661 ldap_syslog = 0;
662 } else {
663 ldap_syslog = config_syslog;
664 }
665 rc = 0;
666 break;
667
668 case CFG_LOGFILE:
669 rc = logfile_open( c->value_string );
670 ch_free( c->value_string );
671 break;
672
673 case CFG_LOGFILE_ONLY:
674 logfile_only = c->value_int;
675 goto reset;
676
677 case CFG_LOGFILE_ROTATE: {
678 unsigned lf_max, lf_mbyte, lf_hour;
679 if ( lutil_atoux( &lf_max, c->argv[1], 0 ) != 0 ) {
680 snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> "
681 "invalid max value \"%s\"", c->argv[0], c->argv[1] );
682 Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
683 c->log, c->cr_msg );
684 return 1;
685 }
686 if ( !lf_max || lf_max > 99 ) {
687 snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> "
688 "invalid max value \"%s\" must be 1-99", c->argv[0], c->argv[1] );
689 Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
690 c->log, c->cr_msg );
691 return 1;
692 }
693 if ( lutil_atoux( &lf_mbyte, c->argv[2], 0 ) != 0 ) {
694 snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> "
695 "invalid Mbyte value \"%s\"", c->argv[0], c->argv[2] );
696 Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
697 c->log, c->cr_msg );
698 return 1;
699 }
700 if ( lutil_atoux( &lf_hour, c->argv[3], 0 ) != 0 ) {
701 snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> "
702 "invalid hours value \"%s\"", c->argv[0], c->argv[3] );
703 Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
704 c->log, c->cr_msg );
705 return 1;
706 }
707 if ( !lf_mbyte && !lf_hour ) {
708 snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> "
709 "Mbyte and hours cannot both be zero", c->argv[0] );
710 Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
711 c->log, c->cr_msg );
712 return 1;
713 }
714 logfile_max = lf_max;
715 logfile_fslimit = lf_mbyte * 1048576; /* Megabytes to bytes */
716 logfile_age = lf_hour * 3600; /* hours to seconds */
717 }
718 break;
719 default:
720 rc = 1;
721 }
722 return rc;
723 }
724