]> git.sur5r.net Git - openldap/blob - servers/slapd/config.c
Add "sasl-external-x509dn-convert" configuration option aimed
[openldap] / servers / slapd / config.c
1 /* config.c - configuration file handling routines */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/string.h>
13 #include <ac/ctype.h>
14 #include <ac/socket.h>
15
16 #include "lutil.h"
17 #include "ldap_pvt.h"
18 #include "slap.h"
19
20 #define MAXARGS 200
21
22 /*
23  * defaults for various global variables
24  */
25 int             defsize = SLAPD_DEFAULT_SIZELIMIT;
26 int             deftime = SLAPD_DEFAULT_TIMELIMIT;
27 AccessControl   *global_acl = NULL;
28 slap_access_t           global_default_access = ACL_READ;
29 slap_mask_t             global_restrictops = 0;
30 slap_mask_t             global_allows = 0;
31 slap_mask_t             global_disallows = 0;
32 slap_mask_t             global_requires = 0;
33 slap_ssf_set_t  global_ssf_set;
34 char            *replogfile;
35 int             global_lastmod = ON;
36 int             global_idletimeout = 0;
37 char    *global_host = NULL;
38 char    *global_realm = NULL;
39 char            *ldap_srvtab = "";
40 char            *default_passwd_hash;
41 char            *default_search_base = NULL;
42 char            *default_search_nbase = NULL;
43
44 char   *slapd_pid_file  = NULL;
45 char   *slapd_args_file = NULL;
46
47 int nSaslRegexp = 0;
48 SaslRegexp_t *SaslRegexp = NULL;
49 int sasl_external_x509dn_convert;
50
51 static char     *fp_getline(FILE *fp, int *lineno);
52 static void     fp_getline_init(int *lineno);
53 static int      fp_parse_line(char *line, int *argcp, char **argv);
54
55 static char     *strtok_quote(char *line, char *sep);
56 static int      load_ucdata(char *path);
57
58 int
59 read_config( const char *fname )
60 {
61         FILE    *fp;
62         char    *line, *savefname, *saveline;
63         int     cargc, savelineno;
64         char    *cargv[MAXARGS+1];
65         int     lineno, i;
66 #ifdef HAVE_TLS
67         int rc;
68 #endif
69         struct berval *vals[2];
70         struct berval val;
71
72         static BackendInfo *bi = NULL;
73         static BackendDB        *be = NULL;
74
75         vals[0] = &val;
76         vals[1] = NULL;
77
78         if ( (fp = fopen( fname, "r" )) == NULL ) {
79                 ldap_syslog = 1;
80                 Debug( LDAP_DEBUG_ANY,
81                     "could not open config file \"%s\" - absolute path?\n",
82                     fname, 0, 0 );
83                 perror( fname );
84                 return 1;
85         }
86
87 #ifdef NEW_LOGGING
88         LDAP_LOG(( "config", LDAP_LEVEL_ENTRY,
89                    "read_config: reading config file %s\n", fname ));
90 #else
91         Debug( LDAP_DEBUG_CONFIG, "reading config file %s\n", fname, 0, 0 );
92 #endif
93
94
95         fp_getline_init( &lineno );
96
97         while ( (line = fp_getline( fp, &lineno )) != NULL ) {
98                 /* skip comments and blank lines */
99                 if ( line[0] == '#' || line[0] == '\0' ) {
100                         continue;
101                 }
102
103 #ifdef NEW_LOGGING
104                 LDAP_LOG(( "config", LDAP_LEVEL_DETAIL1,
105                            "line %d (%s)\n", lineno, line ));
106 #else
107                 Debug( LDAP_DEBUG_CONFIG, "line %d (%s)\n", lineno, line, 0 );
108 #endif
109
110
111                 /* fp_parse_line is destructive, we save a copy */
112                 saveline = ch_strdup( line );
113
114                 if ( fp_parse_line( line, &cargc, cargv ) != 0 ) {
115                         return( 1 );
116                 }
117
118                 if ( cargc < 1 ) {
119 #ifdef NEW_LOGGING
120                         LDAP_LOG(( "config", LDAP_LEVEL_INFO,
121                                    "%s: line %d: bad config line (ignored)\n",
122                                    fname, lineno ));
123 #else
124                         Debug( LDAP_DEBUG_ANY,
125                             "%s: line %d: bad config line (ignored)\n",
126                             fname, lineno, 0 );
127 #endif
128
129                         continue;
130                 }
131
132                 if ( strcasecmp( cargv[0], "backend" ) == 0 ) {
133                         if ( cargc < 2 ) {
134 #ifdef NEW_LOGGING
135                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
136                                            "%s : line %d: missing type in \"backend\" line.\n",
137                                            fname, lineno ));
138 #else
139                                 Debug( LDAP_DEBUG_ANY,
140                 "%s: line %d: missing type in \"backend <type>\" line\n",
141                                     fname, lineno, 0 );
142 #endif
143
144                                 return( 1 );
145                         }
146
147                         if( be != NULL ) {
148 #ifdef NEW_LOGGING
149                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
150                                            "%s: line %d: backend line must appear before any "
151                                            "database definition.\n", fname, lineno ));
152 #else
153                                 Debug( LDAP_DEBUG_ANY,
154 "%s: line %d: backend line must appear before any database definition\n",
155                                     fname, lineno, 0 );
156 #endif
157
158                                 return( 1 );
159                         }
160
161                         bi = backend_info( cargv[1] );
162
163                         if( bi == NULL ) {
164 #ifdef NEW_LOGGING
165                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
166                                            "read_config: backend %s initialization failed.\n",
167                                            cargv[1] ));
168 #else
169                                 Debug( LDAP_DEBUG_ANY,
170                                         "backend %s initialization failed.\n",
171                                     cargv[1], 0, 0 );
172 #endif
173
174                                 return( 1 );
175                         }
176                 } else if ( strcasecmp( cargv[0], "database" ) == 0 ) {
177                         if ( cargc < 2 ) {
178 #ifdef NEW_LOGGING
179                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
180                                            "%s: line %d: missing type in \"database <type>\" line\n",
181                                            fname, lineno ));
182 #else
183                                 Debug( LDAP_DEBUG_ANY,
184                 "%s: line %d: missing type in \"database <type>\" line\n",
185                                     fname, lineno, 0 );
186 #endif
187
188                                 return( 1 );
189                         }
190
191                         bi = NULL;
192                         be = backend_db_init( cargv[1] );
193
194                         if( be == NULL ) {
195 #ifdef NEW_LOGGING
196                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
197                                            "database %s initialization failed.\n",
198                                            cargv[1] ));
199 #else
200                                 Debug( LDAP_DEBUG_ANY,
201                                         "database %s initialization failed.\n",
202                                     cargv[1], 0, 0 );
203 #endif
204
205                                 return( 1 );
206                         }
207
208                 /* set thread concurrency */
209                 } else if ( strcasecmp( cargv[0], "concurrency" ) == 0 ) {
210                         int c;
211                         if ( cargc < 2 ) {
212 #ifdef NEW_LOGGING
213                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
214                                            "%s: line %d: missing level in \"concurrency <level\" line\n",
215                                            fname, lineno ));
216 #else
217                                 Debug( LDAP_DEBUG_ANY,
218             "%s: line %d: missing level in \"concurrency <level>\" line\n",
219                                     fname, lineno, 0 );
220 #endif
221
222                                 return( 1 );
223                         }
224
225                         c = atoi( cargv[1] );
226
227                         if( c < 1 ) {
228 #ifdef NEW_LOGGING
229                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
230                                            "%s: line %d: invalid level (%d) in "
231                                            "\"concurrency <level>\" line.\n",
232                                            fname, lineno, c ));
233 #else
234                                 Debug( LDAP_DEBUG_ANY,
235             "%s: line %d: invalid level (%d) in \"concurrency <level>\" line\n",
236                                     fname, lineno, c );
237 #endif
238
239                                 return( 1 );
240                         }
241
242                         ldap_pvt_thread_set_concurrency( c );
243
244                 /* default search base */
245                 } else if ( strcasecmp( cargv[0], "defaultSearchBase" ) == 0 ) {
246                         if ( cargc < 2 ) {
247 #ifdef NEW_LOGGING
248                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
249                                            "%s: line %d: missing dn in \"defaultSearchBase <dn\" "
250                                            "line\n", fname, lineno ));
251 #else
252                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
253                                         "missing dn in \"defaultSearchBase <dn>\" line\n",
254                                         fname, lineno, 0 );
255 #endif
256
257                                 return 1;
258
259                         } else if ( cargc > 2 ) {
260 #ifdef NEW_LOGGING
261                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
262                                            "%s: line %d: extra cruft after <dn> in "
263                                            "\"defaultSearchBase %s\" line (ignored)\n",
264                                            fname, lineno, cargv[1] ));
265 #else
266                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
267                                         "extra cruft after <dn> in \"defaultSearchBase %s\", "
268                                         "line (ignored)\n",
269                                         fname, lineno, cargv[1] );
270 #endif
271
272                         }
273
274                         if ( bi != NULL || be != NULL ) {
275 #ifdef NEW_LOGGING
276                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
277                                            "%s: line %d: defaultSearchBase line must appear "
278                                            "prior to any backend or database definitions\n",
279                                            fname, lineno ));
280 #else
281                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
282                                         "defaultSearchBaase line must appear prior to "
283                                         "any backend or database definition\n",
284                                     fname, lineno, 0 );
285 #endif
286
287                                 return 1;
288                         }
289
290                         if ( default_search_nbase != NULL ) {
291 #ifdef NEW_LOGGING
292                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
293                                            "%s: line %d: default search base \"%s\" already defined "
294                                            "(discarding old)\n", fname, lineno, default_search_base ));
295 #else
296                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
297                                         "default search base \"%s\" already defined "
298                                         "(discarding old)\n",
299                                         fname, lineno, default_search_base );
300 #endif
301
302                                 free( default_search_base );
303                                 free( default_search_nbase );
304                         }
305
306                         default_search_base = ch_strdup( cargv[1] );
307                         default_search_nbase = ch_strdup( cargv[1] );
308
309                         if ( load_ucdata( NULL ) < 0 ) {
310                                 return( 1 );
311                         }
312                         if( dn_normalize( default_search_nbase ) == NULL ) {
313 #ifdef NEW_LOGGING
314                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
315                                            "%s:  %d: invalid default search base \"%s\"\n",
316                                            fname, lineno, default_search_base ));
317 #else
318                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
319                                         "invalid default search base \"%s\"\n",
320                                         fname, lineno, default_search_base );
321 #endif
322
323                                 return 1;
324                         }
325                
326                 /* set maximum threads in thread pool */
327                 } else if ( strcasecmp( cargv[0], "threads" ) == 0 ) {
328                         int c;
329                         if ( cargc < 2 ) {
330 #ifdef NEW_LOGGING
331                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
332                                            "%s: line %d: missing count in \"threads <count>\" line\n",
333                                            fname, lineno ));
334 #else
335                                 Debug( LDAP_DEBUG_ANY,
336             "%s: line %d: missing count in \"threads <count>\" line\n",
337                                     fname, lineno, 0 );
338 #endif
339
340                                 return( 1 );
341                         }
342
343                         c = atoi( cargv[1] );
344
345                         if( c < 0 ) {
346 #ifdef NEW_LOGGING
347                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
348                                            "%s: line %d: invalid level (%d) in \"threads <count>\""
349                                            "line\n",fname, lineno, c ));
350 #else
351                                 Debug( LDAP_DEBUG_ANY,
352             "%s: line %d: invalid level (%d) in \"threads <count>\" line\n",
353                                     fname, lineno, c );
354 #endif
355
356                                 return( 1 );
357                         }
358
359                         ldap_pvt_thread_pool_maxthreads( &connection_pool, c );
360
361                 /* get pid file name */
362                 } else if ( strcasecmp( cargv[0], "pidfile" ) == 0 ) {
363                         if ( cargc < 2 ) {
364 #ifdef NEW_LOGGING
365                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
366                                            "%s: line %d missing file name in \"pidfile <file>\" line.\n",
367                                            fname, lineno ));
368 #else
369                                 Debug( LDAP_DEBUG_ANY,
370             "%s: line %d: missing file name in \"pidfile <file>\" line\n",
371                                     fname, lineno, 0 );
372 #endif
373
374                                 return( 1 );
375                         }
376
377                         slapd_pid_file = ch_strdup( cargv[1] );
378
379                 /* get args file name */
380                 } else if ( strcasecmp( cargv[0], "argsfile" ) == 0 ) {
381                         if ( cargc < 2 ) {
382 #ifdef NEW_LOGGING
383                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
384                                            "%s: %d: missing file name in "
385                                            "\"argsfile <file>\" line.\n",
386                                            fname, lineno ));
387 #else
388                                 Debug( LDAP_DEBUG_ANY,
389             "%s: line %d: missing file name in \"argsfile <file>\" line\n",
390                                     fname, lineno, 0 );
391 #endif
392
393                                 return( 1 );
394                         }
395
396                         slapd_args_file = ch_strdup( cargv[1] );
397
398                 /* default password hash */
399                 } else if ( strcasecmp( cargv[0], "password-hash" ) == 0 ) {
400                         if ( cargc < 2 ) {
401 #ifdef NEW_LOGGING
402                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
403                                            "%s: line %d: missing hash in "
404                                            "\"password-hash <hash>\" line.\n",
405                                            fname, lineno ));
406 #else
407                                 Debug( LDAP_DEBUG_ANY,
408             "%s: line %d: missing hash in \"password-hash <hash>\" line\n",
409                                     fname, lineno, 0 );
410 #endif
411
412                                 return( 1 );
413                         }
414                         if ( default_passwd_hash != NULL ) {
415 #ifdef NEW_LOGGING
416                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
417                                            "%s: line %d: already set default password_hash!\n",
418                                            fname, lineno ));
419 #else
420                                 Debug( LDAP_DEBUG_ANY,
421                                         "%s: line %d: already set default password_hash!\n",
422                                         fname, lineno, 0 );
423 #endif
424
425                                 return 1;
426
427                         } else {
428                                 default_passwd_hash = ch_strdup( cargv[1] );
429                         }
430
431                 /* set SASL host */
432                 } else if ( strcasecmp( cargv[0], "sasl-host" ) == 0 ) {
433                         if ( cargc < 2 ) {
434 #ifdef NEW_LOGGING
435                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
436                                            "%s: line %d: missing host in \"sasl-host <host>\" line\n",
437                                            fname, lineno ));
438 #else
439                                 Debug( LDAP_DEBUG_ANY,
440             "%s: line %d: missing host in \"sasl-host <host>\" line\n",
441                                     fname, lineno, 0 );
442 #endif
443
444                                 return( 1 );
445                         }
446
447                         if ( global_host != NULL ) {
448 #ifdef NEW_LOGGING
449                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
450                                            "%s: line %d: already set sasl-host!\n",
451                                            fname, lineno ));
452 #else
453                                 Debug( LDAP_DEBUG_ANY,
454                                         "%s: line %d: already set sasl-host!\n",
455                                         fname, lineno, 0 );
456 #endif
457
458                                 return 1;
459
460                         } else {
461                                 global_host = ch_strdup( cargv[1] );
462                         }
463
464                 /* set SASL realm */
465                 } else if ( strcasecmp( cargv[0], "sasl-realm" ) == 0 ) {
466                         if ( cargc < 2 ) {
467 #ifdef NEW_LOGGING
468                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
469                                            "%s: line %d: missing realm in \"sasl-realm <realm>\" line.\n",
470                                            fname, lineno ));
471 #else
472                                 Debug( LDAP_DEBUG_ANY,
473             "%s: line %d: missing realm in \"sasl-realm <realm>\" line\n",
474                                     fname, lineno, 0 );
475 #endif
476
477                                 return( 1 );
478                         }
479
480                         if ( global_realm != NULL ) {
481 #ifdef NEW_LOGGING
482                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
483                                            "%s: line %d: already set sasl-realm!\n",
484                                            fname, lineno ));
485 #else
486                                 Debug( LDAP_DEBUG_ANY,
487                                         "%s: line %d: already set sasl-realm!\n",
488                                         fname, lineno, 0 );
489 #endif
490
491                                 return 1;
492
493                         } else {
494                                 global_realm = ch_strdup( cargv[1] );
495                         }
496
497                 } else if ( !strcasecmp( cargv[0], "sasl-regexp" ) 
498                         || !strcasecmp( cargv[0], "saslregexp" ) )
499                 {
500                         int rc;
501                         if ( cargc != 3 ) {
502 #ifdef NEW_LOGGING
503                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
504                                            "%s: line %d: need 2 args in "
505                                            "\"saslregexp <match> <replace>\"\n",
506                                            fname, lineno ));
507 #else
508                                 Debug( LDAP_DEBUG_ANY, 
509                                 "%s: line %d: need 2 args in \"saslregexp <match> <replace>\"\n",
510                                     fname, lineno, 0 );
511 #endif
512
513                                 return( 1 );
514                         }
515                         rc = slap_sasl_regexp_config( cargv[1], cargv[2] );
516                         if ( rc ) {
517                                 return rc;
518                         }
519
520                 /* SASL security properties */
521                 } else if ( strcasecmp( cargv[0], "sasl-secprops" ) == 0 ) {
522                         char *txt;
523
524                         if ( cargc < 2 ) {
525 #ifdef NEW_LOGGING
526                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
527                                            "%s: line %d: missing flags in "
528                                            "\"sasl-secprops <properties>\" line\n",
529                                            fname, lineno ));
530 #else
531                                 Debug( LDAP_DEBUG_ANY,
532             "%s: line %d: missing flags in \"sasl-secprops <properties>\" line\n",
533                                     fname, lineno, 0 );
534 #endif
535
536                                 return 1;
537                         }
538
539                         txt = slap_sasl_secprops( cargv[1] );
540                         if ( txt != NULL ) {
541 #ifdef NEW_LOGGING
542                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
543                                            "%s: line %d sas-secprops: %s\n",
544                                            fname, lineno, txt ));
545 #else
546                                 Debug( LDAP_DEBUG_ANY,
547             "%s: line %d: sasl-secprops: %s\n",
548                                     fname, lineno, txt );
549 #endif
550
551                                 return 1;
552                         }
553
554                 } else if ( strcasecmp( cargv[0], "sasl-external-x509dn-convert" ) == 0 ) {
555                         sasl_external_x509dn_convert++;
556
557                 /* set UCDATA path */
558                 } else if ( strcasecmp( cargv[0], "ucdata-path" ) == 0 ) {
559                         int err;
560                         if ( cargc < 2 ) {
561 #ifdef NEW_LOGGING
562                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
563                                            "%s: line %d: missing path in "
564                                            "\"ucdata-path <path>\" line.\n",
565                                            fname, lineno ));
566 #else
567                                 Debug( LDAP_DEBUG_ANY,
568             "%s: line %d: missing path in \"ucdata-path <path>\" line\n",
569                                     fname, lineno, 0 );
570 #endif
571
572                                 return( 1 );
573                         }
574
575                         err = load_ucdata( cargv[1] );
576                         if ( err <= 0 ) {
577                                 if ( err == 0 ) {
578 #ifdef NEW_LOGGING
579                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
580                                                    "%s: line %d: ucdata already loaded, ucdata-path "
581                                                    "must be set earlier in the file and/or be "
582                                                    "specified only once!\n",
583                                                    fname, lineno ));
584 #else
585                                         Debug( LDAP_DEBUG_ANY,
586                                                "%s: line %d: ucdata already loaded, ucdata-path must be set earlier in the file and/or be specified only once!\n",
587                                                fname, lineno, 0 );
588 #endif
589
590                                 }
591                                 return( 1 );
592                         }
593
594                 /* set time limit */
595                 } else if ( strcasecmp( cargv[0], "sizelimit" ) == 0 ) {
596                         if ( cargc < 2 ) {
597 #ifdef NEW_LOGGING
598                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
599                                            "%s: line %d: missing limit in \"sizelimit <limit>\" line.\n",
600                                            fname, lineno ));
601 #else
602                                 Debug( LDAP_DEBUG_ANY,
603             "%s: line %d: missing limit in \"sizelimit <limit>\" line\n",
604                                     fname, lineno, 0 );
605 #endif
606
607                                 return( 1 );
608                         }
609                         if ( be == NULL ) {
610                                 defsize = atoi( cargv[1] );
611                         } else {
612                                 be->be_sizelimit = atoi( cargv[1] );
613                         }
614
615                 /* set time limit */
616                 } else if ( strcasecmp( cargv[0], "timelimit" ) == 0 ) {
617                         if ( cargc < 2 ) {
618 #ifdef NEW_LOGGING
619                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
620                                            "%s: line %d missing limit in \"timelimit <limit>\" line.\n",
621                                            fname, lineno ));
622 #else
623                                 Debug( LDAP_DEBUG_ANY,
624             "%s: line %d: missing limit in \"timelimit <limit>\" line\n",
625                                     fname, lineno, 0 );
626 #endif
627
628                                 return( 1 );
629                         }
630                         if ( be == NULL ) {
631                                 deftime = atoi( cargv[1] );
632                         } else {
633                                 be->be_timelimit = atoi( cargv[1] );
634                         }
635
636                 /* set database suffix */
637                 } else if ( strcasecmp( cargv[0], "suffix" ) == 0 ) {
638                         Backend *tmp_be;
639                         if ( cargc < 2 ) {
640 #ifdef NEW_LOGGING
641                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
642                                            "%s: line %d: missing dn in \"suffix <dn>\" line.\n",
643                                            fname, lineno ));
644 #else
645                                 Debug( LDAP_DEBUG_ANY,
646                     "%s: line %d: missing dn in \"suffix <dn>\" line\n",
647                                     fname, lineno, 0 );
648 #endif
649
650                                 return( 1 );
651                         } else if ( cargc > 2 ) {
652 #ifdef NEW_LOGGING
653                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
654                                            "%s: line %d: extra cruft after <dn> in \"suffix %s\""
655                                            " line (ignored).\n", fname, lineno, cargv[1] ));
656 #else
657                                 Debug( LDAP_DEBUG_ANY,
658     "%s: line %d: extra cruft after <dn> in \"suffix %s\" line (ignored)\n",
659                                     fname, lineno, cargv[1] );
660 #endif
661
662                         }
663                         if ( be == NULL ) {
664 #ifdef NEW_LOGGING
665                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
666                                            "%s: line %d: suffix line must appear inside a database "
667                                            "definition (ignored).\n", fname, lineno ));
668 #else
669                                 Debug( LDAP_DEBUG_ANY,
670 "%s: line %d: suffix line must appear inside a database definition (ignored)\n",
671                                     fname, lineno, 0 );
672 #endif
673
674                         } else if ( ( tmp_be = select_backend( cargv[1], 0 ) ) == be ) {
675 #ifdef NEW_LOGGING
676                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
677                                            "%s: line %d: suffix already served by this backend "
678                                            "(ignored)\n", fname, lineno ));
679 #else
680                                 Debug( LDAP_DEBUG_ANY,
681 "%s: line %d: suffix already served by this backend (ignored)\n",
682                                     fname, lineno, 0 );
683 #endif
684
685                         } else if ( tmp_be  != NULL ) {
686 #ifdef NEW_LOGGING
687                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
688                                            "%s: line %d: suffix already served by a preceding "
689                                            "backend \"%s\" (ignored)\n", fname, lineno,
690                                            tmp_be->be_suffix[0] ));
691 #else
692                                 Debug( LDAP_DEBUG_ANY,
693 "%s: line %d: suffix already served by a preceeding backend \"%s\" (ignored)\n",
694                                     fname, lineno, tmp_be->be_suffix[0] );
695 #endif
696
697                         } else {
698                                 char *dn = ch_strdup( cargv[1] );
699                                 if ( load_ucdata( NULL ) < 0 ) {
700                                         return( 1 );
701                                 }
702                                 if( dn_validate( dn ) == NULL ) {
703 #ifdef NEW_LOGGING
704                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
705                                                    "%s: line %d: suffix DN invalid\"%s\"\n",
706                                                    fname, lineno, cargv[1] ));
707 #else
708                                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
709                                                 "suffix DN invalid \"%s\"\n",
710                                         fname, lineno, cargv[1] );
711 #endif
712
713                                         return 1;
714
715                                 } else if( *dn == '\0' && default_search_nbase != NULL ) {
716 #ifdef NEW_LOGGING
717                                         LDAP_LOG(( "config", LDAP_LEVEL_INFO,
718                                                    "%s: line %d: suffix DN empty and default search "
719                                                    "base provided \"%s\" (assuming okay).\n",
720                                                    fname, lineno, default_search_base ));
721 #else
722                                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
723                                                 "suffix DN empty and default "
724                                                 "search base provided \"%s\" (assuming okay)\n",
725                                         fname, lineno, default_search_base );
726 #endif
727
728                                 }
729                                 charray_add( &be->be_suffix, dn );
730                                 (void) ldap_pvt_str2upper( dn );
731                                 charray_add( &be->be_nsuffix, dn );
732                                 free( dn );
733                         }
734
735                 /* set database suffixAlias */
736                 } else if ( strcasecmp( cargv[0], "suffixAlias" ) == 0 ) {
737                         Backend *tmp_be;
738                         if ( cargc < 2 ) {
739 #ifdef NEW_LOGGING
740                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
741                                            "%s: line %d: missing alias and aliased_dn in "
742                                            "\"suffixAlias <alias> <aliased_dn>\" line.\n",
743                                            fname, lineno ));
744 #else
745                                 Debug( LDAP_DEBUG_ANY,
746 "%s: line %d: missing alias and aliased_dn in \"suffixAlias <alias> <aliased_dn>\" line\n",
747                                         fname, lineno, 0 );
748 #endif
749
750                                 return( 1 );
751                         } else if ( cargc < 3 ) {
752 #ifdef NEW_LOGGING
753                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
754                                            "%s: line %d: missing aliased_dn in "
755                                            "\"suffixAlias <alias> <aliased_dn>\" line\n",
756                                            fname, lineno ));
757 #else
758                                 Debug( LDAP_DEBUG_ANY,
759 "%s: line %d: missing aliased_dn in \"suffixAlias <alias> <aliased_dn>\" line\n",
760                                 fname, lineno, 0 );
761 #endif
762
763                                 return( 1 );
764                         } else if ( cargc > 3 ) {
765 #ifdef NEW_LOGGING
766                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
767                                            "%s: line %d: extra cruft in suffixAlias line (ignored)\n",
768                                            fname, lineno ));
769 #else
770                                 Debug( LDAP_DEBUG_ANY,
771                                         "%s: line %d: extra cruft in suffixAlias line (ignored)\n",
772                                 fname, lineno, 0 );
773 #endif
774
775                         }
776
777                         if ( be == NULL ) {
778 #ifdef NEW_LOGGING
779                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
780                                            "%s: line %d: suffixAlias line must appear inside a "
781                                            "database definition (ignored).\n", fname, lineno ));
782 #else
783                                 Debug( LDAP_DEBUG_ANY,
784                                         "%s: line %d: suffixAlias line"
785                                         " must appear inside a database definition (ignored)\n",
786                                         fname, lineno, 0 );
787 #endif
788
789                         } else if ( (tmp_be = select_backend( cargv[1], 0 )) != NULL ) {
790 #ifdef NEW_LOGGING
791                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
792                                            "%s: line %d: suffixAlias served by a preceeding "
793                                            "backend \"%s\" (ignored).\n", fname, lineno,
794                                            tmp_be->be_suffix[0] ));
795 #else
796                                 Debug( LDAP_DEBUG_ANY,
797                                         "%s: line %d: suffixAlias served by"
798                                         "  a preceeding backend \"%s\" (ignored)\n",
799                                         fname, lineno, tmp_be->be_suffix[0] );
800 #endif
801
802
803                         } else if ( (tmp_be = select_backend( cargv[2], 0 )) != NULL ) {
804 #ifdef NEW_LOGGING
805                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
806                                            "%s: line %d: suffixAlias derefs to a different backend "
807                                            "a preceeding backend \"%s\" (ignored)\n",
808                                            fname, lineno, tmp_be->be_suffix[0] ));
809 #else
810                                 Debug( LDAP_DEBUG_ANY,
811                                         "%s: line %d: suffixAlias derefs to differnet backend"
812                                         "  a preceeding backend \"%s\" (ignored)\n",
813                                         fname, lineno, tmp_be->be_suffix[0] );
814 #endif
815
816
817                         } else {
818                                 char *alias, *aliased_dn;
819
820                                 alias = ch_strdup( cargv[1] );
821                                 if ( load_ucdata( NULL ) < 0 ) {
822                                         return( 1 );
823                                 }
824                                 (void) dn_normalize( alias );
825
826                                 aliased_dn = ch_strdup( cargv[2] );
827                                 (void) dn_normalize( aliased_dn );
828
829                                 charray_add( &be->be_suffixAlias, alias );
830                                 charray_add( &be->be_suffixAlias, aliased_dn );
831
832                                 free(alias);
833                                 free(aliased_dn);
834                         }
835
836                /* set max deref depth */
837                } else if ( strcasecmp( cargv[0], "maxDerefDepth" ) == 0 ) {
838                                         int i;
839                        if ( cargc < 2 ) {
840 #ifdef NEW_LOGGING
841                                LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
842                                           "%s: line %d: missing depth in \"maxDerefDepth <depth>\""
843                                           " line\n", fname, lineno ));
844 #else
845                                Debug( LDAP_DEBUG_ANY,
846                    "%s: line %d: missing depth in \"maxDerefDepth <depth>\" line\n",
847                                    fname, lineno, 0 );
848 #endif
849
850                                return( 1 );
851                        }
852                        if ( be == NULL ) {
853 #ifdef NEW_LOGGING
854                                LDAP_LOG(( "config", LDAP_LEVEL_INFO,
855                                           "%s: line %d: depth line must appear inside a database "
856                                           "definition (ignored)\n", fname, lineno ));
857 #else
858                                Debug( LDAP_DEBUG_ANY,
859 "%s: line %d: depth line must appear inside a database definition (ignored)\n",
860                                    fname, lineno, 0 );
861 #endif
862
863                        } else if ((i = atoi(cargv[1])) < 0) {
864 #ifdef NEW_LOGGING
865                                LDAP_LOG(( "config", LDAP_LEVEL_INFO,
866                                           "%s: line %d: depth must be positive (ignored).\n",
867                                           fname, lineno ));
868 #else
869                                Debug( LDAP_DEBUG_ANY,
870 "%s: line %d: depth must be positive (ignored)\n",
871                                    fname, lineno, 0 );
872 #endif
873
874
875                        } else {
876                            be->be_max_deref_depth = i;
877                                            }
878
879
880                 /* set magic "root" dn for this database */
881                 } else if ( strcasecmp( cargv[0], "rootdn" ) == 0 ) {
882                         if ( cargc < 2 ) {
883 #ifdef NEW_LOGGING
884                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
885                                            "%s: line %d: missing dn in \"rootdn <dn>\" line.\n",
886                                            fname, lineno ));
887 #else
888                                 Debug( LDAP_DEBUG_ANY,
889                     "%s: line %d: missing dn in \"rootdn <dn>\" line\n",
890                                     fname, lineno, 0 );
891 #endif
892
893                                 return( 1 );
894                         }
895                         if ( be == NULL ) {
896 #ifdef NEW_LOGGING
897                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
898                                            "%s: line %d: rootdn line must appear inside a database "
899                                            "definition (ignored).\n", fname, lineno ));
900 #else
901                                 Debug( LDAP_DEBUG_ANY,
902 "%s: line %d: rootdn line must appear inside a database definition (ignored)\n",
903                                     fname, lineno, 0 );
904 #endif
905
906                         } else {
907                                 be->be_root_dn = ch_strdup( cargv[1] );
908                                 be->be_root_ndn = ch_strdup( cargv[1] );
909
910                                 if ( load_ucdata( NULL ) < 0 ) {
911                                         return( 1 );
912                                 }
913                                 if( dn_normalize( be->be_root_ndn ) == NULL ) {
914                                         free( be->be_root_dn );
915                                         free( be->be_root_ndn );
916 #ifdef NEW_LOGGING
917                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
918                                                    "%s: line %d: rootdn DN is invalid.\n",
919                                                    fname, lineno ));
920 #else
921                                         Debug( LDAP_DEBUG_ANY,
922 "%s: line %d: rootdn DN is invalid\n",
923                                            fname, lineno, 0 );
924 #endif
925
926                                         return( 1 );
927                                 }
928                         }
929
930                 /* set super-secret magic database password */
931                 } else if ( strcasecmp( cargv[0], "rootpw" ) == 0 ) {
932                         if ( cargc < 2 ) {
933 #ifdef NEW_LOGGING
934                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
935                                            "%s: line %d: missing passwd in \"rootpw <passwd>\""
936                                            " line\n", fname, lineno ));
937 #else
938                                 Debug( LDAP_DEBUG_ANY,
939             "%s: line %d: missing passwd in \"rootpw <passwd>\" line\n",
940                                     fname, lineno, 0 );
941 #endif
942
943                                 return( 1 );
944                         }
945                         if ( be == NULL ) {
946 #ifdef NEW_LOGGING
947                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
948                                            "%s: line %d: rootpw line must appear inside a database "
949                                            "definition (ignored)\n", fname, lineno ));
950 #else
951                                 Debug( LDAP_DEBUG_ANY,
952 "%s: line %d: rootpw line must appear inside a database definition (ignored)\n",
953                                     fname, lineno, 0 );
954 #endif
955
956                         } else {
957                                 be->be_root_pw.bv_val = ch_strdup( cargv[1] );
958                                 be->be_root_pw.bv_len = strlen( be->be_root_pw.bv_val );
959                         }
960
961                 /* make this database read-only */
962                 } else if ( strcasecmp( cargv[0], "readonly" ) == 0 ) {
963                         if ( cargc < 2 ) {
964 #ifdef NEW_LOGGING
965                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
966                                            "%s: line %d: missing on|off in \"readonly <on|off>\" line.\n",
967                                            fname, lineno ));
968 #else
969                                 Debug( LDAP_DEBUG_ANY,
970             "%s: line %d: missing on|off in \"readonly <on|off>\" line\n",
971                                     fname, lineno, 0 );
972 #endif
973
974                                 return( 1 );
975                         }
976                         if ( be == NULL ) {
977                                 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
978                                         global_restrictops |= SLAP_RESTRICT_OP_WRITES;
979                                 } else {
980                                         global_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
981                                 }
982                         } else {
983                                 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
984                                         be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
985                                 } else {
986                                         be->be_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
987                                 }
988                         }
989
990
991                 /* allow these features */
992                 } else if ( strcasecmp( cargv[0], "allows" ) == 0 ||
993                         strcasecmp( cargv[0], "allow" ) == 0 )
994                 {
995                         slap_mask_t     allows;
996
997                         if ( be != NULL ) {
998 #ifdef NEW_LOGGING
999                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1000                                            "%s: line %d: allow line must appear prior to "
1001                                            "database definitions.\n", fname, lineno ));
1002 #else
1003                                 Debug( LDAP_DEBUG_ANY,
1004 "%s: line %d: allow line must appear prior to database definitions\n",
1005                                     fname, lineno, 0 );
1006 #endif
1007
1008                         }
1009
1010                         if ( cargc < 2 ) {
1011 #ifdef NEW_LOGGING
1012                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1013                                            "%s: line %d: missing feature(s) in \"allow <features>\""
1014                                            " line\n", fname, lineno ));
1015 #else
1016                                 Debug( LDAP_DEBUG_ANY,
1017             "%s: line %d: missing feature(s) in \"allow <features>\" line\n",
1018                                     fname, lineno, 0 );
1019 #endif
1020
1021                                 return( 1 );
1022                         }
1023
1024                         allows = 0;
1025
1026                         for( i=1; i < cargc; i++ ) {
1027                                 if( strcasecmp( cargv[i], "tls_2_anon" ) == 0 ) {
1028                                         allows |= SLAP_ALLOW_TLS_2_ANON;
1029
1030                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1031 #ifdef NEW_LOGGING
1032                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1033                                                    "%s: line %d: unknown feature %s in "
1034                                                    "\"allow <features>\" line.\n",
1035                                                    fname, lineno, cargv[1] ));
1036 #else
1037                                         Debug( LDAP_DEBUG_ANY,
1038                     "%s: line %d: unknown feature %s in \"allow <features>\" line\n",
1039                                             fname, lineno, cargv[i] );
1040 #endif
1041
1042                                         return( 1 );
1043                                 }
1044                         }
1045
1046                         global_allows = allows;
1047
1048                 /* disallow these features */
1049                 } else if ( strcasecmp( cargv[0], "disallows" ) == 0 ||
1050                         strcasecmp( cargv[0], "disallow" ) == 0 )
1051                 {
1052                         slap_mask_t     disallows;
1053
1054                         if ( be != NULL ) {
1055 #ifdef NEW_LOGGING
1056                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1057                                            "%s: line %d: disallow line must appear prior to "
1058                                            "database definitions.\n", fname, lineno ));
1059 #else
1060                                 Debug( LDAP_DEBUG_ANY,
1061 "%s: line %d: disallow line must appear prior to database definitions\n",
1062                                     fname, lineno, 0 );
1063 #endif
1064
1065                         }
1066
1067                         if ( cargc < 2 ) {
1068 #ifdef NEW_LOGGING
1069                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1070                                            "%s: line %d: missing feature(s) in \"disallow <features>\""
1071                                            " line.\n", fname, lineno ));
1072 #else
1073                                 Debug( LDAP_DEBUG_ANY,
1074             "%s: line %d: missing feature(s) in \"disallow <features>\" line\n",
1075                                     fname, lineno, 0 );
1076 #endif
1077
1078                                 return( 1 );
1079                         }
1080
1081                         disallows = 0;
1082
1083                         for( i=1; i < cargc; i++ ) {
1084                                 if( strcasecmp( cargv[i], "bind_v2" ) == 0 ) {
1085                                         disallows |= SLAP_DISALLOW_BIND_V2;
1086
1087                                 } else if( strcasecmp( cargv[i], "bind_anon" ) == 0 ) {
1088                                         disallows |= SLAP_DISALLOW_BIND_ANON;
1089
1090                                 } else if( strcasecmp( cargv[i], "bind_anon_cred" ) == 0 ) {
1091                                         disallows |= SLAP_DISALLOW_BIND_ANON_CRED;
1092
1093                                 } else if( strcasecmp( cargv[i], "bind_anon_dn" ) == 0 ) {
1094                                         disallows |= SLAP_DISALLOW_BIND_ANON_DN;
1095
1096                                 } else if( strcasecmp( cargv[i], "bind_simple" ) == 0 ) {
1097                                         disallows |= SLAP_DISALLOW_BIND_SIMPLE;
1098
1099                                 } else if( strcasecmp( cargv[i], "bind_krbv4" ) == 0 ) {
1100                                         disallows |= SLAP_DISALLOW_BIND_KRBV4;
1101
1102                                 } else if( strcasecmp( cargv[i], "tls_authc" ) == 0 ) {
1103                                         disallows |= SLAP_DISALLOW_TLS_AUTHC;
1104
1105                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1106 #ifdef NEW_LOGGING
1107                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1108                                                    "%s: line %d: unknownfeature %s in "
1109                                                    "\"disallow <features>\" line.\n",
1110                                                    fname, lineno ));
1111 #else
1112                                         Debug( LDAP_DEBUG_ANY,
1113                     "%s: line %d: unknown feature %s in \"disallow <features>\" line\n",
1114                                             fname, lineno, cargv[i] );
1115 #endif
1116
1117                                         return( 1 );
1118                                 }
1119                         }
1120
1121                         global_disallows = disallows;
1122
1123                 /* require these features */
1124                 } else if ( strcasecmp( cargv[0], "requires" ) == 0 ||
1125                         strcasecmp( cargv[0], "require" ) == 0 )
1126                 {
1127                         slap_mask_t     requires;
1128
1129                         if ( cargc < 2 ) {
1130 #ifdef NEW_LOGGING
1131                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1132                                            "%s: line %d: missing feature(s) in "
1133                                            "\"require <features>\" line.\n", fname, lineno ));
1134 #else
1135                                 Debug( LDAP_DEBUG_ANY,
1136             "%s: line %d: missing feature(s) in \"require <features>\" line\n",
1137                                     fname, lineno, 0 );
1138 #endif
1139
1140                                 return( 1 );
1141                         }
1142
1143                         requires = 0;
1144
1145                         for( i=1; i < cargc; i++ ) {
1146                                 if( strcasecmp( cargv[i], "bind" ) == 0 ) {
1147                                         requires |= SLAP_REQUIRE_BIND;
1148
1149                                 } else if( strcasecmp( cargv[i], "LDAPv3" ) == 0 ) {
1150                                         requires |= SLAP_REQUIRE_LDAP_V3;
1151
1152                                 } else if( strcasecmp( cargv[i], "authc" ) == 0 ) {
1153                                         requires |= SLAP_REQUIRE_AUTHC;
1154
1155                                 } else if( strcasecmp( cargv[i], "SASL" ) == 0 ) {
1156                                         requires |= SLAP_REQUIRE_SASL;
1157
1158                                 } else if( strcasecmp( cargv[i], "strong" ) == 0 ) {
1159                                         requires |= SLAP_REQUIRE_STRONG;
1160
1161                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1162 #ifdef NEW_LOGGING
1163                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1164                                                    "%s: line %d: unknown feature %s in "
1165                                                    "\"require <features>\" line.\n",
1166                                                    fname, lineno ));
1167 #else
1168                                         Debug( LDAP_DEBUG_ANY,
1169                     "%s: line %d: unknown feature %s in \"require <features>\" line\n",
1170                                             fname, lineno, cargv[i] );
1171 #endif
1172
1173                                         return( 1 );
1174                                 }
1175                         }
1176
1177                         if ( be == NULL ) {
1178                                 global_requires = requires;
1179                         } else {
1180                                 be->be_requires = requires;
1181                         }
1182
1183                 /* required security factors */
1184                 } else if ( strcasecmp( cargv[0], "security" ) == 0 ) {
1185                         slap_ssf_set_t *set;
1186
1187                         if ( cargc < 2 ) {
1188 #ifdef NEW_LOGGING
1189                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1190                                            "%s: line %d: missing factor(s) in \"security <factors>\""
1191                                            " line.\n", fname, lineno ));
1192 #else
1193                                 Debug( LDAP_DEBUG_ANY,
1194             "%s: line %d: missing factor(s) in \"security <factors>\" line\n",
1195                                     fname, lineno, 0 );
1196 #endif
1197
1198                                 return( 1 );
1199                         }
1200
1201                         if ( be == NULL ) {
1202                                 set = &global_ssf_set;
1203                         } else {
1204                                 set = &be->be_ssf_set;
1205                         }
1206
1207                         for( i=1; i < cargc; i++ ) {
1208                                 if( strncasecmp( cargv[i], "ssf=",
1209                                         sizeof("ssf") ) == 0 )
1210                                 {
1211                                         set->sss_ssf =
1212                                                 atoi( &cargv[i][sizeof("ssf")] );
1213
1214                                 } else if( strncasecmp( cargv[i], "transport=",
1215                                         sizeof("transport") ) == 0 )
1216                                 {
1217                                         set->sss_transport =
1218                                                 atoi( &cargv[i][sizeof("transport")] );
1219
1220                                 } else if( strncasecmp( cargv[i], "tls=",
1221                                         sizeof("tls") ) == 0 )
1222                                 {
1223                                         set->sss_tls =
1224                                                 atoi( &cargv[i][sizeof("tls")] );
1225
1226                                 } else if( strncasecmp( cargv[i], "sasl=",
1227                                         sizeof("sasl") ) == 0 )
1228                                 {
1229                                         set->sss_sasl =
1230                                                 atoi( &cargv[i][sizeof("sasl")] );
1231
1232                                 } else if( strncasecmp( cargv[i], "update_ssf=",
1233                                         sizeof("update_ssf") ) == 0 )
1234                                 {
1235                                         set->sss_update_ssf =
1236                                                 atoi( &cargv[i][sizeof("update_ssf")] );
1237
1238                                 } else if( strncasecmp( cargv[i], "update_transport=",
1239                                         sizeof("update_transport") ) == 0 )
1240                                 {
1241                                         set->sss_update_transport =
1242                                                 atoi( &cargv[i][sizeof("update_transport")] );
1243
1244                                 } else if( strncasecmp( cargv[i], "update_tls=",
1245                                         sizeof("update_tls") ) == 0 )
1246                                 {
1247                                         set->sss_update_tls =
1248                                                 atoi( &cargv[i][sizeof("update_tls")] );
1249
1250                                 } else if( strncasecmp( cargv[i], "update_sasl=",
1251                                         sizeof("update_sasl") ) == 0 )
1252                                 {
1253                                         set->sss_update_sasl =
1254                                                 atoi( &cargv[i][sizeof("update_sasl")] );
1255
1256                                 } else {
1257 #ifdef NEW_LOGGING
1258                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1259                                                    "%s: line %d: unknown factor %S in "
1260                                                    "\"security <factors>\" line.\n",
1261                                                    fname, lineno, cargv[1] ));
1262 #else
1263                                         Debug( LDAP_DEBUG_ANY,
1264                     "%s: line %d: unknown factor %s in \"security <factors>\" line\n",
1265                                             fname, lineno, cargv[i] );
1266 #endif
1267
1268                                         return( 1 );
1269                                 }
1270                         }
1271                 /* where to send clients when we don't hold it */
1272                 } else if ( strcasecmp( cargv[0], "referral" ) == 0 ) {
1273                         if ( cargc < 2 ) {
1274 #ifdef NEW_LOGGING
1275                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1276                                            "%s: line %d: missing URL in \"referral <URL>\""
1277                                            " line.\n", fname, lineno ));
1278 #else
1279                                 Debug( LDAP_DEBUG_ANY,
1280                     "%s: line %d: missing URL in \"referral <URL>\" line\n",
1281                                     fname, lineno, 0 );
1282 #endif
1283
1284                                 return( 1 );
1285                         }
1286
1287                         vals[0]->bv_val = cargv[1];
1288                         vals[0]->bv_len = strlen( vals[0]->bv_val );
1289                         value_add( &default_referral, vals );
1290
1291 #ifdef NEW_LOGGING
1292                 } else if ( strcasecmp( cargv[0], "logfile" ) == 0 ) {
1293                         FILE *logfile;
1294                         if ( cargc < 2 ) {
1295 #ifdef NEW_LOGGING
1296                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1297                                            "%s: line %d: Error in logfile directive, "
1298                                            "\"logfile <filename>\"\n", fname, lineno ));
1299 #else
1300                                 Debug( LDAP_DEBUG_ANY,
1301                                        "%s: line %d: Error in logfile directive, \"logfile filename\"\n",
1302                                        fname, lineno, 0 );
1303 #endif
1304
1305                                 return( 1 );
1306                         }
1307                         logfile = fopen( cargv[1], "w" );
1308                         if ( logfile != NULL ) lutil_debug_file( logfile );
1309
1310 #endif
1311                 /* start of a new database definition */
1312                 } else if ( strcasecmp( cargv[0], "debug" ) == 0 ) {
1313                         int level;
1314                         if ( cargc < 3 ) {
1315 #ifdef NEW_LOGGING
1316                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1317                                            "%s: line %d: Error in debug directive, "
1318                                            "\"debug <subsys> <level>\"\n", fname, lineno ));
1319 #else
1320                                 Debug( LDAP_DEBUG_ANY,
1321                                         "%s: line %d: Error in debug directive, \"debug subsys level\"\n",
1322                                         fname, lineno, 0 );
1323 #endif
1324
1325                                 return( 1 );
1326                         }
1327                         level = atoi( cargv[2] );
1328                         if ( level <= 0 ) level = lutil_mnem2level( cargv[2] );
1329                         lutil_set_debug_level( cargv[1], level );
1330                 /* specify an Object Identifier macro */
1331                 } else if ( strcasecmp( cargv[0], "objectidentifier" ) == 0 ) {
1332                         parse_oidm( fname, lineno, cargc, cargv );
1333
1334                 /* specify an objectclass */
1335                 } else if ( strcasecmp( cargv[0], "objectclass" ) == 0 ) {
1336                         if ( *cargv[1] == '(' ) {
1337                                 char * p;
1338                                 p = strchr(saveline,'(');
1339                                 parse_oc( fname, lineno, p, cargv );
1340                         } else {
1341 #ifdef NEW_LOGGING
1342                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1343                                            "%s: line %d: old objectclass format not supported\n",
1344                                            fname, lineno ));
1345 #else
1346                                 Debug( LDAP_DEBUG_ANY,
1347                                        "%s: line %d: old objectclass format not supported.\n",
1348                                        fname, lineno, 0 );
1349 #endif
1350
1351                         }
1352
1353                 /* specify an attribute type */
1354                 } else if (( strcasecmp( cargv[0], "attributetype" ) == 0 )
1355                         || ( strcasecmp( cargv[0], "attribute" ) == 0 ))
1356                 {
1357                         if ( *cargv[1] == '(' ) {
1358                                 char * p;
1359                                 p = strchr(saveline,'(');
1360                                 parse_at( fname, lineno, p, cargv );
1361                         } else {
1362 #ifdef NEW_LOGGING
1363                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1364                                            "%s: line %d: old attribute type format not supported.\n",
1365                                            fname, lineno ));
1366 #else
1367                                 Debug( LDAP_DEBUG_ANY,
1368     "%s: line %d: old attribute type format not supported.\n",
1369                                     fname, lineno, 0 );
1370 #endif
1371
1372                         }
1373
1374                 /* turn on/off schema checking */
1375                 } else if ( strcasecmp( cargv[0], "schemacheck" ) == 0 ) {
1376                         if ( cargc < 2 ) {
1377 #ifdef NEW_LOGGING
1378                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1379                                            "%s: line %d: missing on|off in "
1380                                            "\"schemacheck <on|off>\" line.\n",
1381                                            fname, lineno ));
1382 #else
1383                                 Debug( LDAP_DEBUG_ANY,
1384     "%s: line %d: missing on|off in \"schemacheck <on|off>\" line\n",
1385                                     fname, lineno, 0 );
1386 #endif
1387
1388                                 return( 1 );
1389                         }
1390                         if ( strcasecmp( cargv[1], "off" ) == 0 ) {
1391                                 global_schemacheck = 0;
1392                         } else {
1393                                 global_schemacheck = 1;
1394                         }
1395
1396                 /* specify access control info */
1397                 } else if ( strcasecmp( cargv[0], "access" ) == 0 ) {
1398                         parse_acl( be, fname, lineno, cargc, cargv );
1399
1400                 /* debug level to log things to syslog */
1401                 } else if ( strcasecmp( cargv[0], "loglevel" ) == 0 ) {
1402                         if ( cargc < 2 ) {
1403 #ifdef NEW_LOGGING
1404                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1405                                            "%s: line %d: missing level in \"loglevel <level>\""
1406                                            " line.\n", fname, lineno ));
1407 #else
1408                                 Debug( LDAP_DEBUG_ANY,
1409                     "%s: line %d: missing level in \"loglevel <level>\" line\n",
1410                                     fname, lineno, 0 );
1411 #endif
1412
1413                                 return( 1 );
1414                         }
1415
1416                         ldap_syslog = 0;
1417
1418                         for( i=1; i < cargc; i++ ) {
1419                                 ldap_syslog += atoi( cargv[1] );
1420                         }
1421
1422                 /* list of replicas of the data in this backend (master only) */
1423                 } else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
1424                         if ( cargc < 2 ) {
1425 #ifdef NEW_LOGGING
1426                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1427                                            "%s: line %d: missing host in \"replica "
1428                                            " <host[:port]\" line\n", fname, lineno ));
1429 #else
1430                                 Debug( LDAP_DEBUG_ANY,
1431             "%s: line %d: missing host in \"replica <host[:port]>\" line\n",
1432                                     fname, lineno, 0 );
1433 #endif
1434
1435                                 return( 1 );
1436                         }
1437                         if ( be == NULL ) {
1438 #ifdef NEW_LOGGING
1439                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1440                                            "%s: line %d: replica line must appear inside "
1441                                            "a database definition (ignored).\n", fname, lineno ));
1442 #else
1443                                 Debug( LDAP_DEBUG_ANY,
1444 "%s: line %d: replica line must appear inside a database definition (ignored)\n",
1445                                     fname, lineno, 0 );
1446 #endif
1447
1448                         } else {
1449                                 for ( i = 1; i < cargc; i++ ) {
1450                                         if ( strncasecmp( cargv[i], "host=", 5 )
1451                                             == 0 ) {
1452                                                 charray_add( &be->be_replica,
1453                                                              cargv[i] + 5 );
1454                                                 break;
1455                                         }
1456                                 }
1457                                 if ( i == cargc ) {
1458 #ifdef NEW_LOGGING
1459                                         LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1460                                                    "%s: line %d: missing host in \"replica\" "
1461                                                    "line (ignored)\n", fname, lineno ));
1462 #else
1463                                         Debug( LDAP_DEBUG_ANY,
1464                     "%s: line %d: missing host in \"replica\" line (ignored)\n",
1465                                             fname, lineno, 0 );
1466 #endif
1467
1468                                 }
1469                         }
1470
1471                 /* dn of master entity allowed to write to replica */
1472                 } else if ( strcasecmp( cargv[0], "updatedn" ) == 0 ) {
1473                         if ( cargc < 2 ) {
1474 #ifdef NEW_LOGGING
1475                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1476                                            "%s: line %d: missing dn in \"updatedn <dn>\""
1477                                            " line.\n", fname, lineno ));
1478 #else
1479                                 Debug( LDAP_DEBUG_ANY,
1480                     "%s: line %d: missing dn in \"updatedn <dn>\" line\n",
1481                                     fname, lineno, 0 );
1482 #endif
1483
1484                                 return( 1 );
1485                         }
1486                         if ( be == NULL ) {
1487 #ifdef NEW_LOGGING
1488                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1489                                            "%s: line %d: updatedn line must appear inside "
1490                                            "a database definition (ignored)\n",
1491                                            fname, lineno ));
1492 #else
1493                                 Debug( LDAP_DEBUG_ANY,
1494 "%s: line %d: updatedn line must appear inside a database definition (ignored)\n",
1495                                     fname, lineno, 0 );
1496 #endif
1497
1498                         } else {
1499                                 be->be_update_ndn = ch_strdup( cargv[1] );
1500                                 if ( load_ucdata( NULL ) < 0 ) {
1501                                         return( 1 );
1502                                 }
1503                                 if( dn_normalize( be->be_update_ndn ) == NULL ) {
1504 #ifdef NEW_LOGGING
1505                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1506                                                    "%s: line %d: updatedn DN is invalid.\n",
1507                                                    fname, lineno ));
1508 #else
1509                                         Debug( LDAP_DEBUG_ANY,
1510 "%s: line %d: updatedn DN is invalid\n",
1511                                             fname, lineno, 0 );
1512 #endif
1513
1514                                         return 1;
1515                                 }
1516                         }
1517
1518                 } else if ( strcasecmp( cargv[0], "updateref" ) == 0 ) {
1519                         if ( cargc < 2 ) {
1520 #ifdef NEW_LOGGING
1521                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1522                                            "%s: line %d: missing dn in \"updateref <ldapurl>\" "
1523                                            "line.\n", fname, lineno ));
1524 #else
1525                                 Debug( LDAP_DEBUG_ANY,
1526                     "%s: line %d: missing dn in \"updateref <ldapurl>\" line\n",
1527                                     fname, lineno, 0 );
1528 #endif
1529
1530                                 return( 1 );
1531                         }
1532                         if ( be == NULL ) {
1533 #ifdef NEW_LOGGING
1534                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1535                                            "%s: line %d: updateref line must appear inside "
1536                                            "a database definition (ignored)\n", fname, lineno ));
1537 #else
1538                                 Debug( LDAP_DEBUG_ANY,
1539 "%s: line %d: updateref line must appear inside a database definition (ignored)\n",
1540                                     fname, lineno, 0 );
1541 #endif
1542
1543                         } else if ( be->be_update_ndn == NULL ) {
1544 #ifdef NEW_LOGGING
1545                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1546                                            "%s: line %d: updateref line must come after updatedn "
1547                                            "(ignored).\n", fname, lineno ));
1548 #else
1549                                 Debug( LDAP_DEBUG_ANY,
1550 "%s: line %d: updateref line must after updatedn (ignored)\n",
1551                                     fname, lineno, 0 );
1552 #endif
1553
1554                         } else {
1555                                 vals[0]->bv_val = cargv[1];
1556                                 vals[0]->bv_len = strlen( vals[0]->bv_val );
1557                                 value_add( &be->be_update_refs, vals );
1558                         }
1559
1560                 /* replication log file to which changes are appended */
1561                 } else if ( strcasecmp( cargv[0], "replogfile" ) == 0 ) {
1562                         if ( cargc < 2 ) {
1563 #ifdef NEW_LOGGING
1564                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1565                                            "%s: line %d: missing filename in \"replogfile <filename>\""
1566                                            " line.\n", fname, lineno ));
1567 #else
1568                                 Debug( LDAP_DEBUG_ANY,
1569             "%s: line %d: missing dn in \"replogfile <filename>\" line\n",
1570                                     fname, lineno, 0 );
1571 #endif
1572
1573                                 return( 1 );
1574                         }
1575                         if ( be ) {
1576                                 be->be_replogfile = ch_strdup( cargv[1] );
1577                         } else {
1578                                 replogfile = ch_strdup( cargv[1] );
1579                         }
1580
1581                 /* maintain lastmodified{by,time} attributes */
1582                 } else if ( strcasecmp( cargv[0], "lastmod" ) == 0 ) {
1583                         if ( cargc < 2 ) {
1584 #ifdef NEW_LOGGING
1585                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1586                                            "%s: line %d: missing on|off in \"lastmod <on|off>\""
1587                                            " line.\n", fname, lineno ));
1588 #else
1589                                 Debug( LDAP_DEBUG_ANY,
1590             "%s: line %d: missing on|off in \"lastmod <on|off>\" line\n",
1591                                     fname, lineno, 0 );
1592 #endif
1593
1594                                 return( 1 );
1595                         }
1596                         if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1597                                 if ( be )
1598                                         be->be_lastmod = ON;
1599                                 else
1600                                         global_lastmod = ON;
1601                         } else {
1602                                 if ( be )
1603                                         be->be_lastmod = OFF;
1604                                 else
1605                                         global_lastmod = OFF;
1606                         }
1607
1608                 /* set idle timeout value */
1609                 } else if ( strcasecmp( cargv[0], "idletimeout" ) == 0 ) {
1610                         int i;
1611                         if ( cargc < 2 ) {
1612 #ifdef NEW_LOGGING
1613                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1614                                            "%s: line %d: missing timeout value in "
1615                                            "\"idletimeout <seconds>\" line.\n", fname, lineno ));
1616 #else
1617                                 Debug( LDAP_DEBUG_ANY,
1618             "%s: line %d: missing timeout value in \"idletimeout <seconds>\" line\n",
1619                                     fname, lineno, 0 );
1620 #endif
1621
1622                                 return( 1 );
1623                         }
1624
1625                         i = atoi( cargv[1] );
1626
1627                         if( i < 0 ) {
1628 #ifdef NEW_LOGGING
1629                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1630                                            "%s: line %d: timeout value (%d) invalid "
1631                                            "\"idletimeout <seconds>\" line.\n",
1632                                            fname, lineno, i ));
1633 #else
1634                                 Debug( LDAP_DEBUG_ANY,
1635             "%s: line %d: timeout value (%d) invalid \"idletimeout <seconds>\" line\n",
1636                                     fname, lineno, i );
1637 #endif
1638
1639                                 return( 1 );
1640                         }
1641
1642                         global_idletimeout = i;
1643
1644                 /* include another config file */
1645                 } else if ( strcasecmp( cargv[0], "include" ) == 0 ) {
1646                         if ( cargc < 2 ) {
1647 #ifdef NEW_LOGGING
1648                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1649                                            "%s: line %d: missing filename in \"include "
1650                                            "<filename>\" line.\n", fname, lineno ));
1651 #else
1652                                 Debug( LDAP_DEBUG_ANY,
1653     "%s: line %d: missing filename in \"include <filename>\" line\n",
1654                                     fname, lineno, 0 );
1655 #endif
1656
1657                                 return( 1 );
1658                         }
1659                         savefname = ch_strdup( cargv[1] );
1660                         savelineno = lineno;
1661
1662                         if ( read_config( savefname ) != 0 ) {
1663                                 return( 1 );
1664                         }
1665
1666                         free( savefname );
1667                         lineno = savelineno - 1;
1668
1669                 /* location of kerberos srvtab file */
1670                 } else if ( strcasecmp( cargv[0], "srvtab" ) == 0 ) {
1671                         if ( cargc < 2 ) {
1672 #ifdef NEW_LOGGING
1673                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1674                                            "%s: line %d: missing filename in \"srvtab "
1675                                            "<filename>\" line.\n", fname, lineno ));
1676 #else
1677                                 Debug( LDAP_DEBUG_ANY,
1678             "%s: line %d: missing filename in \"srvtab <filename>\" line\n",
1679                                     fname, lineno, 0 );
1680 #endif
1681
1682                                 return( 1 );
1683                         }
1684                         ldap_srvtab = ch_strdup( cargv[1] );
1685
1686 #ifdef SLAPD_MODULES
1687                 } else if (strcasecmp( cargv[0], "moduleload") == 0 ) {
1688                    if ( cargc < 2 ) {
1689 #ifdef NEW_LOGGING
1690                            LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1691                                       "%s: line %d: missing filename in \"moduleload "
1692                                       "<filename>\" line.\n", fname, lineno ));
1693 #else
1694                       Debug( LDAP_DEBUG_ANY,
1695                              "%s: line %d: missing filename in \"moduleload <filename>\" line\n",
1696                              fname, lineno, 0 );
1697 #endif
1698
1699                       exit( EXIT_FAILURE );
1700                    }
1701                    if (module_load(cargv[1], cargc - 2, (cargc > 2) ? cargv + 2 : NULL)) {
1702 #ifdef NEW_LOGGING
1703                            LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1704                                       "%s: line %d: failed to load or initialize module %s\n"<
1705                                       fname, lineno, cargv[1] ));
1706 #else
1707                       Debug( LDAP_DEBUG_ANY,
1708                              "%s: line %d: failed to load or initialize module %s\n",
1709                              fname, lineno, cargv[1]);
1710 #endif
1711
1712                       exit( EXIT_FAILURE );
1713                    }
1714                 } else if (strcasecmp( cargv[0], "modulepath") == 0 ) {
1715                    if ( cargc != 2 ) {
1716 #ifdef NEW_LOGGING
1717                            LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1718                                       "%s: line %d: missing path in \"modulepath <path>\""
1719                                       " line\n", fname, lineno ));
1720 #else
1721                       Debug( LDAP_DEBUG_ANY,
1722                              "%s: line %d: missing path in \"modulepath <path>\" line\n",
1723                              fname, lineno, 0 );
1724 #endif
1725
1726                       exit( EXIT_FAILURE );
1727                    }
1728                    if (module_path( cargv[1] )) {
1729 #ifdef NEW_LOGGING
1730                            LDAP_LOG(( "cofig", LDAP_LEVEL_CRIT,
1731                                       "%s: line %d: failed to set module search path to %s.\n",
1732                                       fname, lineno, cargv[1] ));
1733 #else
1734                            Debug( LDAP_DEBUG_ANY,
1735                                   "%s: line %d: failed to set module search path to %s\n",
1736                                   fname, lineno, cargv[1]);
1737 #endif
1738
1739                       exit( EXIT_FAILURE );
1740                    }
1741                    
1742 #endif /*SLAPD_MODULES*/
1743
1744 #ifdef HAVE_TLS
1745                 } else if ( !strcasecmp( cargv[0], "TLSProtocol" ) ) {
1746                         rc = ldap_pvt_tls_set_option( NULL,
1747                                                       LDAP_OPT_X_TLS_PROTOCOL,
1748                                                       cargv[1] );
1749                         if ( rc )
1750                                 return rc;
1751
1752                 } else if ( !strcasecmp( cargv[0], "TLSCipherSuite" ) ) {
1753                         rc = ldap_pvt_tls_set_option( NULL,
1754                                                       LDAP_OPT_X_TLS_CIPHER_SUITE,
1755                                                       cargv[1] );
1756                         if ( rc )
1757                                 return rc;
1758
1759                 } else if ( !strcasecmp( cargv[0], "TLSCertificateFile" ) ) {
1760                         rc = ldap_pvt_tls_set_option( NULL,
1761                                                       LDAP_OPT_X_TLS_CERTFILE,
1762                                                       cargv[1] );
1763                         if ( rc )
1764                                 return rc;
1765
1766                 } else if ( !strcasecmp( cargv[0], "TLSCertificateKeyFile" ) ) {
1767                         rc = ldap_pvt_tls_set_option( NULL,
1768                                                       LDAP_OPT_X_TLS_KEYFILE,
1769                                                       cargv[1] );
1770                         if ( rc )
1771                                 return rc;
1772
1773                 } else if ( !strcasecmp( cargv[0], "TLSCACertificatePath" ) ) {
1774                         rc = ldap_pvt_tls_set_option( NULL,
1775                                                       LDAP_OPT_X_TLS_CACERTDIR,
1776                                                       cargv[1] );
1777                         if ( rc )
1778                                 return rc;
1779
1780                 } else if ( !strcasecmp( cargv[0], "TLSCACertificateFile" ) ) {
1781                         rc = ldap_pvt_tls_set_option( NULL,
1782                                                       LDAP_OPT_X_TLS_CACERTFILE,
1783                                                       cargv[1] );
1784                         if ( rc )
1785                                 return rc;
1786                 } else if ( !strcasecmp( cargv[0], "TLSVerifyClient" ) ) {
1787                         i = atoi(cargv[1]);
1788                         rc = ldap_pvt_tls_set_option( NULL,
1789                                                       LDAP_OPT_X_TLS_REQUIRE_CERT,
1790                                                       &i );
1791                         if ( rc )
1792                                 return rc;
1793
1794 #endif
1795
1796                 /* pass anything else to the current backend info/db config routine */
1797                 } else {
1798                         if ( bi != NULL ) {
1799                                 if ( bi->bi_config == 0 ) {
1800 #ifdef NEW_LOGGING
1801                                         LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1802                                                    "%s: line %d: unknown directive \"%s\" inside "
1803                                                    "backend info definition (ignored).\n",
1804                                                    fname, lineno, cargv[0] ));
1805 #else
1806                                         Debug( LDAP_DEBUG_ANY,
1807 "%s: line %d: unknown directive \"%s\" inside backend info definition (ignored)\n",
1808                                                 fname, lineno, cargv[0] );
1809 #endif
1810
1811                                 } else {
1812                                         if ( (*bi->bi_config)( bi, fname, lineno, cargc, cargv )
1813                                                 != 0 )
1814                                         {
1815                                                 return( 1 );
1816                                         }
1817                                 }
1818                         } else if ( be != NULL ) {
1819                                 if ( be->be_config == 0 ) {
1820 #ifdef NEW_LOGGING
1821                                         LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1822                                                    "%s: line %d: uknown directive \"%s\" inside "
1823                                                    "backend database definition (ignored).\n",
1824                                                    fname, lineno, cargv[0] ));
1825 #else
1826                                         Debug( LDAP_DEBUG_ANY,
1827 "%s: line %d: unknown directive \"%s\" inside backend database definition (ignored)\n",
1828                                         fname, lineno, cargv[0] );
1829 #endif
1830
1831                                 } else {
1832                                         if ( (*be->be_config)( be, fname, lineno, cargc, cargv )
1833                                                 != 0 )
1834                                         {
1835                                                 return( 1 );
1836                                         }
1837                                 }
1838                         } else {
1839 #ifdef NEW_LOGGING
1840                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1841                                            "%s: line %d: unknown directive \"%s\" outside backend "
1842                                            "info and database definitions (ignored).\n",
1843                                            fname, lineno, cargv[0] ));
1844 #else
1845                                 Debug( LDAP_DEBUG_ANY,
1846 "%s: line %d: unknown directive \"%s\" outside backend info and database definitions (ignored)\n",
1847                                     fname, lineno, cargv[0] );
1848 #endif
1849
1850                         }
1851                 }
1852                 free( saveline );
1853         }
1854         fclose( fp );
1855         if ( load_ucdata( NULL ) < 0 ) {
1856                 return( 1 );
1857         }
1858         return( 0 );
1859 }
1860
1861 static int
1862 fp_parse_line(
1863     char        *line,
1864     int         *argcp,
1865     char        **argv
1866 )
1867 {
1868         char *  token;
1869
1870         *argcp = 0;
1871         for ( token = strtok_quote( line, " \t" ); token != NULL;
1872             token = strtok_quote( NULL, " \t" ) ) {
1873                 if ( *argcp == MAXARGS ) {
1874 #ifdef NEW_LOGGING
1875                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1876                                    "fp_parse_line: too many tokens (%d max).\n",
1877                                    MAXARGS ));
1878 #else
1879                         Debug( LDAP_DEBUG_ANY, "Too many tokens (max %d)\n",
1880                             MAXARGS, 0, 0 );
1881 #endif
1882
1883                         return( 1 );
1884                 }
1885                 argv[(*argcp)++] = token;
1886         }
1887         argv[*argcp] = NULL;
1888         return 0;
1889 }
1890
1891 static char *
1892 strtok_quote( char *line, char *sep )
1893 {
1894         int             inquote;
1895         char            *tmp;
1896         static char     *next;
1897
1898         if ( line != NULL ) {
1899                 next = line;
1900         }
1901         while ( *next && strchr( sep, *next ) ) {
1902                 next++;
1903         }
1904
1905         if ( *next == '\0' ) {
1906                 next = NULL;
1907                 return( NULL );
1908         }
1909         tmp = next;
1910
1911         for ( inquote = 0; *next; ) {
1912                 switch ( *next ) {
1913                 case '"':
1914                         if ( inquote ) {
1915                                 inquote = 0;
1916                         } else {
1917                                 inquote = 1;
1918                         }
1919                         AC_MEMCPY( next, next + 1, strlen( next + 1 ) + 1 );
1920                         break;
1921
1922                 case '\\':
1923                         if ( next[1] )
1924                                 AC_MEMCPY( next,
1925                                             next + 1, strlen( next + 1 ) + 1 );
1926                         next++;         /* dont parse the escaped character */
1927                         break;
1928
1929                 default:
1930                         if ( ! inquote ) {
1931                                 if ( strchr( sep, *next ) != NULL ) {
1932                                         *next++ = '\0';
1933                                         return( tmp );
1934                                 }
1935                         }
1936                         next++;
1937                         break;
1938                 }
1939         }
1940
1941         return( tmp );
1942 }
1943
1944 static char     buf[BUFSIZ];
1945 static char     *line;
1946 static int      lmax, lcur;
1947
1948 #define CATLINE( buf )  { \
1949         int     len; \
1950         len = strlen( buf ); \
1951         while ( lcur + len + 1 > lmax ) { \
1952                 lmax += BUFSIZ; \
1953                 line = (char *) ch_realloc( line, lmax ); \
1954         } \
1955         strcpy( line + lcur, buf ); \
1956         lcur += len; \
1957 }
1958
1959 static char *
1960 fp_getline( FILE *fp, int *lineno )
1961 {
1962         char            *p;
1963
1964         lcur = 0;
1965         CATLINE( buf );
1966         (*lineno)++;
1967
1968         /* hack attack - keeps us from having to keep a stack of bufs... */
1969         if ( strncasecmp( line, "include", 7 ) == 0 ) {
1970                 buf[0] = '\0';
1971                 return( line );
1972         }
1973
1974         while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
1975                 if ( (p = strchr( buf, '\n' )) != NULL ) {
1976                         *p = '\0';
1977                 }
1978                 if ( ! isspace( (unsigned char) buf[0] ) ) {
1979                         return( line );
1980                 }
1981
1982                 CATLINE( buf );
1983                 (*lineno)++;
1984         }
1985         buf[0] = '\0';
1986
1987         return( line[0] ? line : NULL );
1988 }
1989
1990 static void
1991 fp_getline_init( int *lineno )
1992 {
1993         *lineno = -1;
1994         buf[0] = '\0';
1995 }
1996
1997 /* Loads ucdata, returns 1 if loading, 0 if already loaded, -1 on error */
1998 static int
1999 load_ucdata( char *path )
2000 {
2001         static int loaded = 0;
2002         int err;
2003         
2004         if ( loaded ) {
2005                 return( 0 );
2006         }
2007         err = ucdata_load( path ? path : SLAPD_DEFAULT_UCDATA,
2008                            UCDATA_CASE|UCDATA_CTYPE|UCDATA_NUM );
2009         if ( err ) {
2010 #ifdef NEW_LOGGING
2011                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
2012                            "load_ucdata: Error %d loading ucdata.\n", err ));
2013 #else
2014                 Debug( LDAP_DEBUG_ANY, "error loading ucdata (error %d)\n",
2015                        err, 0, 0 );
2016 #endif
2017
2018                 return( -1 );
2019         }
2020         loaded = 1;
2021         return( 1 );
2022 }