1 /* config.c - configuration file handling routines */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/config.c,v 1.441.2.16 2008/04/14 22:20:28 quanah Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2008 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
16 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
17 * All rights reserved.
19 * Redistribution and use in source and binary forms are permitted
20 * provided that this notice is preserved and that due credit is given
21 * to the University of Michigan at Ann Arbor. The name of the University
22 * may not be used to endorse or promote products derived from this
23 * software without specific prior written permission. This software
24 * is provided ``as is'' without express or implied warranty.
31 #include <ac/string.h>
33 #include <ac/signal.h>
34 #include <ac/socket.h>
37 #include <sys/types.h>
41 #define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
50 #include "slapi/slapi.h"
53 #include "lutil_ldap.h"
59 * defaults for various global variables
61 slap_mask_t global_allows
= 0;
62 slap_mask_t global_disallows
= 0;
63 int global_gentlehup
= 0;
64 int global_idletimeout
= 0;
65 char *global_host
= NULL
;
66 char *global_realm
= NULL
;
67 char *sasl_host
= NULL
;
68 char **default_passwd_hash
= NULL
;
69 struct berval default_search_base
= BER_BVNULL
;
70 struct berval default_search_nbase
= BER_BVNULL
;
72 ber_len_t sockbuf_max_incoming
= SLAP_SB_MAX_INCOMING_DEFAULT
;
73 ber_len_t sockbuf_max_incoming_auth
= SLAP_SB_MAX_INCOMING_AUTH
;
75 int slap_conn_max_pending
= SLAP_CONN_MAX_PENDING_DEFAULT
;
76 int slap_conn_max_pending_auth
= SLAP_CONN_MAX_PENDING_AUTH
;
78 char *slapd_pid_file
= NULL
;
79 char *slapd_args_file
= NULL
;
81 int use_reverse_lookup
= 0;
84 int slapi_plugins_used
= 0;
87 static int fp_getline(FILE *fp
, ConfigArgs
*c
);
88 static void fp_getline_init(ConfigArgs
*c
);
89 static int fp_parse_line(ConfigArgs
*c
);
91 static char *strtok_quote(char *line
, char *sep
, char **quote_ptr
);
92 static char *strtok_quote_ldif(char **line
);
95 new_config_args( BackendDB
*be
, const char *fname
, int lineno
, int argc
, char **argv
)
98 c
= ch_calloc( 1, sizeof( ConfigArgs
) );
99 if ( c
== NULL
) return(NULL
);
105 snprintf( c
->log
, sizeof( c
->log
), "%s: line %d", fname
, lineno
);
110 init_config_argv( ConfigArgs
*c
)
112 c
->argv
= ch_calloc( ARGS_STEP
+ 1, sizeof( *c
->argv
) );
113 c
->argv_size
= ARGS_STEP
+ 1;
116 ConfigTable
*config_find_keyword(ConfigTable
*Conf
, ConfigArgs
*c
) {
119 for(i
= 0; Conf
[i
].name
; i
++)
120 if( (Conf
[i
].length
&& (!strncasecmp(c
->argv
[0], Conf
[i
].name
, Conf
[i
].length
))) ||
121 (!strcasecmp(c
->argv
[0], Conf
[i
].name
)) ) break;
122 if ( !Conf
[i
].name
) return NULL
;
126 int config_check_vals(ConfigTable
*Conf
, ConfigArgs
*c
, int check_only
) {
127 int rc
, arg_user
, arg_type
, arg_syn
, iarg
;
132 if(Conf
->arg_type
== ARG_IGNORED
) {
133 Debug(LDAP_DEBUG_CONFIG
, "%s: keyword <%s> ignored\n",
134 c
->log
, Conf
->name
, 0);
137 arg_type
= Conf
->arg_type
& ARGS_TYPES
;
138 arg_user
= Conf
->arg_type
& ARGS_USERLAND
;
139 arg_syn
= Conf
->arg_type
& ARGS_SYNTAX
;
141 if((arg_type
== ARG_DN
) && c
->argc
== 1) {
145 if(Conf
->min_args
&& (c
->argc
< Conf
->min_args
)) {
146 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
), "<%s> missing <%s> argument",
147 c
->argv
[0], Conf
->what
);
148 Debug(LDAP_DEBUG_CONFIG
|LDAP_DEBUG_NONE
, "%s: keyword %s\n", c
->log
, c
->cr_msg
, 0 );
149 return(ARG_BAD_CONF
);
151 if(Conf
->max_args
&& (c
->argc
> Conf
->max_args
)) {
152 char *ignored
= " ignored";
154 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
), "<%s> extra cruft after <%s>",
155 c
->argv
[0], Conf
->what
);
158 Debug(LDAP_DEBUG_CONFIG
|LDAP_DEBUG_NONE
, "%s: %s%s.\n",
159 c
->log
, c
->cr_msg
, ignored
);
160 return(ARG_BAD_CONF
);
162 if((arg_syn
& ARG_DB
) && !c
->be
) {
163 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
), "<%s> only allowed within database declaration",
165 Debug(LDAP_DEBUG_CONFIG
|LDAP_DEBUG_NONE
, "%s: keyword %s\n",
166 c
->log
, c
->cr_msg
, 0);
167 return(ARG_BAD_CONF
);
169 if((arg_syn
& ARG_PRE_BI
) && c
->bi
) {
170 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
), "<%s> must occur before any backend %sdeclaration",
171 c
->argv
[0], (arg_syn
& ARG_PRE_DB
) ? "or database " : "" );
172 Debug(LDAP_DEBUG_CONFIG
|LDAP_DEBUG_NONE
, "%s: keyword %s\n",
173 c
->log
, c
->cr_msg
, 0 );
174 return(ARG_BAD_CONF
);
176 if((arg_syn
& ARG_PRE_DB
) && c
->be
&& c
->be
!= frontendDB
) {
177 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
), "<%s> must occur before any database declaration",
179 Debug(LDAP_DEBUG_CONFIG
|LDAP_DEBUG_NONE
, "%s: keyword %s\n",
180 c
->log
, c
->cr_msg
, 0);
181 return(ARG_BAD_CONF
);
183 if((arg_syn
& ARG_PAREN
) && *c
->argv
[1] != '(' /*')'*/) {
184 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
), "<%s> old format not supported", c
->argv
[0] );
185 Debug(LDAP_DEBUG_CONFIG
|LDAP_DEBUG_NONE
, "%s: %s\n",
186 c
->log
, c
->cr_msg
, 0);
187 return(ARG_BAD_CONF
);
189 if(arg_type
&& !Conf
->arg_item
&& !(arg_syn
& ARG_OFFSET
)) {
190 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
), "<%s> invalid config_table, arg_item is NULL",
192 Debug(LDAP_DEBUG_CONFIG
|LDAP_DEBUG_NONE
, "%s: %s\n",
193 c
->log
, c
->cr_msg
, 0);
194 return(ARG_BAD_CONF
);
197 memset(&c
->values
, 0, sizeof(c
->values
));
198 if(arg_type
== ARG_STRING
) {
200 c
->value_string
= ch_strdup(c
->argv
[1]);
201 } else if(arg_type
== ARG_BERVAL
) {
203 ber_str2bv( c
->argv
[1], 0, 1, &c
->value_bv
);
204 } else if(arg_type
== ARG_DN
) {
206 ber_str2bv( c
->argv
[1], 0, 0, &bv
);
207 rc
= dnPrettyNormal( NULL
, &bv
, &c
->value_dn
, &c
->value_ndn
, NULL
);
208 if ( rc
!= LDAP_SUCCESS
) {
209 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
), "<%s> invalid DN %d (%s)",
210 c
->argv
[0], rc
, ldap_err2string( rc
));
211 Debug(LDAP_DEBUG_CONFIG
|LDAP_DEBUG_NONE
, "%s: %s\n" , c
->log
, c
->cr_msg
, 0);
212 return(ARG_BAD_CONF
);
215 ch_free( c
->value_ndn
.bv_val
);
216 ch_free( c
->value_dn
.bv_val
);
218 } else { /* all numeric */
220 iarg
= 0; larg
= 0; barg
= 0;
223 if ( lutil_atoix( &iarg
, c
->argv
[1], 0 ) != 0 ) {
224 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
),
225 "<%s> unable to parse \"%s\" as int",
226 c
->argv
[0], c
->argv
[1] );
227 Debug(LDAP_DEBUG_CONFIG
|LDAP_DEBUG_NONE
, "%s: %s\n",
228 c
->log
, c
->cr_msg
, 0);
229 return(ARG_BAD_CONF
);
233 if ( lutil_atoux( &uiarg
, c
->argv
[1], 0 ) != 0 ) {
234 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
),
235 "<%s> unable to parse \"%s\" as unsigned int",
236 c
->argv
[0], c
->argv
[1] );
237 Debug(LDAP_DEBUG_CONFIG
|LDAP_DEBUG_NONE
, "%s: %s\n",
238 c
->log
, c
->cr_msg
, 0);
239 return(ARG_BAD_CONF
);
243 if ( lutil_atolx( &larg
, c
->argv
[1], 0 ) != 0 ) {
244 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
),
245 "<%s> unable to parse \"%s\" as long",
246 c
->argv
[0], c
->argv
[1] );
247 Debug(LDAP_DEBUG_CONFIG
|LDAP_DEBUG_NONE
, "%s: %s\n",
248 c
->log
, c
->cr_msg
, 0);
249 return(ARG_BAD_CONF
);
252 case ARG_BER_LEN_T
: {
254 if ( lutil_atoulx( &l
, c
->argv
[1], 0 ) != 0 ) {
255 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
),
256 "<%s> unable to parse \"%s\" as ber_len_t",
257 c
->argv
[0], c
->argv
[1] );
258 Debug(LDAP_DEBUG_CONFIG
|LDAP_DEBUG_NONE
, "%s: %s\n",
259 c
->log
, c
->cr_msg
, 0);
260 return(ARG_BAD_CONF
);
267 } else if ( !strcasecmp(c
->argv
[1], "on") ||
268 !strcasecmp(c
->argv
[1], "true") ||
269 !strcasecmp(c
->argv
[1], "yes") )
272 } else if ( !strcasecmp(c
->argv
[1], "off") ||
273 !strcasecmp(c
->argv
[1], "false") ||
274 !strcasecmp(c
->argv
[1], "no") )
278 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
), "<%s> invalid value",
280 Debug(LDAP_DEBUG_ANY
|LDAP_DEBUG_NONE
, "%s: %s\n",
281 c
->log
, c
->cr_msg
, 0 );
282 return(ARG_BAD_CONF
);
286 j
= (arg_type
& ARG_NONZERO
) ? 1 : 0;
287 if(iarg
< j
&& larg
< j
&& barg
< j
) {
288 larg
= larg
? larg
: (barg
? barg
: iarg
);
289 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
), "<%s> invalid value",
291 Debug(LDAP_DEBUG_ANY
|LDAP_DEBUG_NONE
, "%s: %s\n",
292 c
->log
, c
->cr_msg
, 0 );
293 return(ARG_BAD_CONF
);
297 case ARG_INT
: c
->value_int
= iarg
; break;
298 case ARG_UINT
: c
->value_uint
= uiarg
; break;
299 case ARG_LONG
: c
->value_long
= larg
; break;
300 case ARG_BER_LEN_T
: c
->value_ber_t
= barg
; break;
306 int config_set_vals(ConfigTable
*Conf
, ConfigArgs
*c
) {
310 arg_type
= Conf
->arg_type
;
311 if(arg_type
& ARG_MAGIC
) {
312 if(!c
->be
) c
->be
= frontendDB
;
314 rc
= (*((ConfigDriver
*)Conf
->arg_item
))(c
);
316 if(c
->be
== frontendDB
) c
->be
= NULL
;
319 if ( !c
->cr_msg
[0] ) {
320 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
), "<%s> handler exited with %d",
322 Debug(LDAP_DEBUG_CONFIG
, "%s: %s!\n",
323 c
->log
, c
->cr_msg
, 0 );
325 return(ARG_BAD_CONF
);
329 if(arg_type
& ARG_OFFSET
) {
330 if (c
->be
&& c
->table
== Cft_Database
)
331 ptr
= c
->be
->be_private
;
333 ptr
= c
->bi
->bi_private
;
335 snprintf( c
->cr_msg
, sizeof( c
->cr_msg
), "<%s> offset is missing base pointer",
337 Debug(LDAP_DEBUG_CONFIG
, "%s: %s!\n",
338 c
->log
, c
->cr_msg
, 0);
339 return(ARG_BAD_CONF
);
341 ptr
= (void *)((char *)ptr
+ (long)Conf
->arg_item
);
342 } else if (arg_type
& ARGS_TYPES
) {
343 ptr
= Conf
->arg_item
;
345 if(arg_type
& ARGS_TYPES
)
346 switch(arg_type
& ARGS_TYPES
) {
348 case ARG_INT
: *(int*)ptr
= c
->value_int
; break;
349 case ARG_UINT
: *(unsigned*)ptr
= c
->value_uint
; break;
350 case ARG_LONG
: *(long*)ptr
= c
->value_long
; break;
351 case ARG_BER_LEN_T
: *(ber_len_t
*)ptr
= c
->value_ber_t
; break;
353 char *cc
= *(char**)ptr
;
355 if ((arg_type
& ARG_UNIQUE
) && c
->op
== SLAP_CONFIG_ADD
) {
356 Debug(LDAP_DEBUG_CONFIG
, "%s: already set %s!\n",
357 c
->log
, Conf
->name
, 0 );
358 return(ARG_BAD_CONF
);
362 *(char **)ptr
= c
->value_string
;
366 *(struct berval
*)ptr
= c
->value_bv
;
372 int config_add_vals(ConfigTable
*Conf
, ConfigArgs
*c
) {
375 arg_type
= Conf
->arg_type
;
376 if(arg_type
== ARG_IGNORED
) {
377 Debug(LDAP_DEBUG_CONFIG
, "%s: keyword <%s> ignored\n",
378 c
->log
, Conf
->name
, 0);
381 rc
= config_check_vals( Conf
, c
, 0 );
383 return config_set_vals( Conf
, c
);
387 config_del_vals(ConfigTable
*cf
, ConfigArgs
*c
)
391 /* If there is no handler, just ignore it */
392 if ( cf
->arg_type
& ARG_MAGIC
) {
393 c
->op
= LDAP_MOD_DELETE
;
394 c
->type
= cf
->arg_type
& ARGS_USERLAND
;
395 rc
= (*((ConfigDriver
*)cf
->arg_item
))(c
);
401 config_get_vals(ConfigTable
*cf
, ConfigArgs
*c
)
407 if ( cf
->arg_type
& ARG_IGNORED
) {
411 memset(&c
->values
, 0, sizeof(c
->values
));
412 c
->rvalue_vals
= NULL
;
413 c
->rvalue_nvals
= NULL
;
414 c
->op
= SLAP_CONFIG_EMIT
;
415 c
->type
= cf
->arg_type
& ARGS_USERLAND
;
417 if ( cf
->arg_type
& ARG_MAGIC
) {
418 rc
= (*((ConfigDriver
*)cf
->arg_item
))(c
);
421 if ( cf
->arg_type
& ARG_OFFSET
) {
422 if (c
->be
&& c
->table
== Cft_Database
)
423 ptr
= c
->be
->be_private
;
425 ptr
= c
->bi
->bi_private
;
428 ptr
= (void *)((char *)ptr
+ (long)cf
->arg_item
);
433 switch(cf
->arg_type
& ARGS_TYPES
) {
435 case ARG_INT
: c
->value_int
= *(int *)ptr
; break;
436 case ARG_UINT
: c
->value_uint
= *(unsigned *)ptr
; break;
437 case ARG_LONG
: c
->value_long
= *(long *)ptr
; break;
438 case ARG_BER_LEN_T
: c
->value_ber_t
= *(ber_len_t
*)ptr
; break;
441 c
->value_string
= ch_strdup(*(char **)ptr
);
444 ber_dupbv( &c
->value_bv
, (struct berval
*)ptr
); break;
447 if ( cf
->arg_type
& ARGS_TYPES
) {
450 switch(cf
->arg_type
& ARGS_TYPES
) {
451 case ARG_INT
: bv
.bv_len
= snprintf(bv
.bv_val
, sizeof( c
->log
), "%d", c
->value_int
); break;
452 case ARG_UINT
: bv
.bv_len
= snprintf(bv
.bv_val
, sizeof( c
->log
), "%u", c
->value_uint
); break;
453 case ARG_LONG
: bv
.bv_len
= snprintf(bv
.bv_val
, sizeof( c
->log
), "%ld", c
->value_long
); break;
454 case ARG_BER_LEN_T
: bv
.bv_len
= snprintf(bv
.bv_val
, sizeof( c
->log
), "%ld", c
->value_ber_t
); break;
455 case ARG_ON_OFF
: bv
.bv_len
= snprintf(bv
.bv_val
, sizeof( c
->log
), "%s",
456 c
->value_int
? "TRUE" : "FALSE"); break;
458 if ( c
->value_string
&& c
->value_string
[0]) {
459 ber_str2bv( c
->value_string
, 0, 0, &bv
);
465 if ( !BER_BVISEMPTY( &c
->value_bv
)) {
475 if (bv
.bv_val
== c
->log
&& bv
.bv_len
>= sizeof( c
->log
) ) {
478 if (( cf
->arg_type
& ARGS_TYPES
) == ARG_STRING
) {
479 ber_bvarray_add(&c
->rvalue_vals
, &bv
);
480 } else if ( !BER_BVISNULL( &bv
) ) {
481 value_add_one(&c
->rvalue_vals
, &bv
);
483 /* else: maybe c->rvalue_vals already set? */
489 init_config_attrs(ConfigTable
*ct
) {
492 for (i
=0; ct
[i
].name
; i
++ ) {
493 if ( !ct
[i
].attribute
) continue;
494 code
= register_at( ct
[i
].attribute
, &ct
[i
].ad
, 1 );
496 fprintf( stderr
, "init_config_attrs: register_at failed\n" );
505 init_config_ocs( ConfigOCs
*ocs
) {
508 for (i
=0;ocs
[i
].co_def
;i
++) {
509 code
= register_oc( ocs
[i
].co_def
, &ocs
[i
].co_oc
, 1 );
511 fprintf( stderr
, "init_config_ocs: register_oc failed\n" );
518 /* Split an LDIF line into space-separated tokens. Words may be grouped
519 * by quotes. A quoted string may begin in the middle of a word, but must
520 * end at the end of the word (be followed by whitespace or EOS). Any other
521 * quotes are passed through unchanged. All other characters are passed
525 strtok_quote_ldif( char **line
)
527 char *beg
, *ptr
, *quote
=NULL
;
535 while( isspace( (unsigned char) *ptr
)) ptr
++;
546 if ( inquote
&& ( !ptr
[1] || isspace((unsigned char) ptr
[1]))) {
556 if ( isspace( (unsigned char) *ptr
)) {
562 while ( quote
< ptr
) {
570 while ( isspace( (unsigned char) *ptr
)) ptr
++;
577 config_parse_ldif( ConfigArgs
*c
)
580 c
->tline
= ch_strdup(c
->line
);
583 while ((c
->argv
[c
->argc
] = strtok_quote_ldif( &next
)) != NULL
) {
585 if ( c
->argc
>= c
->argv_size
) {
586 char **tmp
= ch_realloc( c
->argv
, (c
->argv_size
+ ARGS_STEP
) *
589 c
->argv_size
+= ARGS_STEP
;
592 c
->argv
[c
->argc
] = NULL
;
596 config_parse_vals(ConfigTable
*ct
, ConfigArgs
*c
, int valx
)
600 snprintf( c
->log
, sizeof( c
->log
), "%s: value #%d",
601 ct
->ad
->ad_cname
.bv_val
, valx
);
603 c
->argv
[0] = ct
->ad
->ad_cname
.bv_val
;
605 if ( ( ct
->arg_type
& ARG_QUOTE
) && c
->line
[ 0 ] != '"' ) {
606 c
->argv
[c
->argc
] = c
->line
;
608 c
->argv
[c
->argc
] = NULL
;
611 config_parse_ldif( c
);
613 rc
= config_check_vals( ct
, c
, 1 );
618 rc
= LDAP_CONSTRAINT_VIOLATION
;
624 config_parse_add(ConfigTable
*ct
, ConfigArgs
*c
, int valx
)
628 snprintf( c
->log
, sizeof( c
->log
), "%s: value #%d",
629 ct
->ad
->ad_cname
.bv_val
, valx
);
631 c
->argv
[0] = ct
->ad
->ad_cname
.bv_val
;
633 if ( ( ct
->arg_type
& ARG_QUOTE
) && c
->line
[ 0 ] != '"' ) {
634 c
->argv
[c
->argc
] = c
->line
;
636 c
->argv
[c
->argc
] = NULL
;
639 config_parse_ldif( c
);
641 c
->op
= LDAP_MOD_ADD
;
642 rc
= config_add_vals( ct
, c
);
649 read_config_file(const char *fname
, int depth
, ConfigArgs
*cf
, ConfigTable
*cft
)
657 c
= ch_calloc( 1, sizeof( ConfigArgs
) );
663 memcpy( c
, cf
, sizeof( ConfigArgs
) );
665 c
->depth
= depth
; /* XXX */
672 init_config_argv( c
);
674 if ( stat( fname
, &s
) != 0 ) {
676 Debug(LDAP_DEBUG_ANY
,
677 "could not stat config file \"%s\": %s (%d)\n",
678 fname
, strerror(errno
), errno
);
683 if ( !S_ISREG( s
.st_mode
) ) {
685 Debug(LDAP_DEBUG_ANY
,
686 "regular file expected, got \"%s\"\n",
692 fp
= fopen( fname
, "r" );
695 Debug(LDAP_DEBUG_ANY
,
696 "could not open config file \"%s\": %s (%d)\n",
697 fname
, strerror(errno
), errno
);
702 Debug(LDAP_DEBUG_CONFIG
, "reading config file %s\n", fname
, 0, 0);
708 while ( fp_getline( fp
, c
) ) {
709 /* skip comments and blank lines */
710 if ( c
->line
[0] == '#' || c
->line
[0] == '\0' ) {
714 snprintf( c
->log
, sizeof( c
->log
), "%s: line %d",
715 c
->fname
, c
->lineno
);
719 if ( fp_parse_line( c
) ) {
725 Debug( LDAP_DEBUG_ANY
, "%s: bad config line.\n",
731 c
->op
= SLAP_CONFIG_ADD
;
733 ct
= config_find_keyword( cft
, c
);
735 c
->table
= Cft_Global
;
736 rc
= config_add_vals( ct
, c
);
739 if ( rc
& ARGS_USERLAND
) {
740 /* XXX a usertype would be opaque here */
741 Debug(LDAP_DEBUG_CONFIG
, "%s: unknown user type <%s>\n",
742 c
->log
, c
->argv
[0], 0);
746 } else if ( rc
== ARG_BAD_CONF
) {
751 } else if ( c
->bi
&& !c
->be
) {
752 rc
= SLAP_CONF_UNKNOWN
;
753 if ( c
->bi
->bi_cf_ocs
) {
754 ct
= config_find_keyword( c
->bi
->bi_cf_ocs
->co_table
, c
);
756 c
->table
= c
->bi
->bi_cf_ocs
->co_type
;
757 rc
= config_add_vals( ct
, c
);
760 if ( c
->bi
->bi_config
&& rc
== SLAP_CONF_UNKNOWN
) {
761 rc
= (*c
->bi
->bi_config
)(c
->bi
, c
->fname
, c
->lineno
,
766 case SLAP_CONF_UNKNOWN
:
767 Debug( LDAP_DEBUG_ANY
, "%s: unknown directive "
768 "<%s> inside backend info definition.\n",
769 c
->log
, *c
->argv
, 0);
776 } else if ( c
->be
&& c
->be
!= frontendDB
) {
777 rc
= SLAP_CONF_UNKNOWN
;
778 if ( c
->be
->be_cf_ocs
) {
779 ct
= config_find_keyword( c
->be
->be_cf_ocs
->co_table
, c
);
781 c
->table
= c
->be
->be_cf_ocs
->co_type
;
782 rc
= config_add_vals( ct
, c
);
785 if ( c
->be
->be_config
&& rc
== SLAP_CONF_UNKNOWN
) {
786 rc
= (*c
->be
->be_config
)(c
->be
, c
->fname
, c
->lineno
,
789 if ( rc
== SLAP_CONF_UNKNOWN
&& SLAP_ISGLOBALOVERLAY( frontendDB
) )
791 /* global overlays may need
792 * definitions inside other databases...
794 rc
= (*frontendDB
->be_config
)( frontendDB
,
795 c
->fname
, (int)c
->lineno
, c
->argc
, c
->argv
);
802 case SLAP_CONF_UNKNOWN
:
803 Debug( LDAP_DEBUG_ANY
, "%s: unknown directive "
804 "<%s> inside backend database definition.\n",
805 c
->log
, *c
->argv
, 0);
812 } else if ( frontendDB
->be_config
) {
813 rc
= (*frontendDB
->be_config
)( frontendDB
,
814 c
->fname
, (int)c
->lineno
, c
->argc
, c
->argv
);
817 case SLAP_CONF_UNKNOWN
:
818 Debug( LDAP_DEBUG_ANY
, "%s: unknown directive "
819 "<%s> inside global database definition.\n",
820 c
->log
, *c
->argv
, 0);
829 Debug( LDAP_DEBUG_ANY
, "%s: unknown directive "
830 "<%s> outside backend info and database definitions.\n",
831 c
->log
, *c
->argv
, 0);
851 /* restrictops, allows, disallows, requires, loglevel */
854 bverb_to_mask(struct berval
*bword
, slap_verbmasks
*v
) {
856 for(i
= 0; !BER_BVISNULL(&v
[i
].word
); i
++) {
857 if(!ber_bvstrcasecmp(bword
, &v
[i
].word
)) break;
863 verb_to_mask(const char *word
, slap_verbmasks
*v
) {
865 ber_str2bv( word
, 0, 0, &bword
);
866 return bverb_to_mask( &bword
, v
);
870 verbs_to_mask(int argc
, char *argv
[], slap_verbmasks
*v
, slap_mask_t
*m
) {
872 for(i
= 1; i
< argc
; i
++) {
873 j
= verb_to_mask(argv
[i
], v
);
874 if(BER_BVISNULL(&v
[j
].word
)) return i
;
875 while (!v
[j
].mask
) j
--;
881 /* Mask keywords that represent multiple bits should occur before single
882 * bit keywords in the verbmasks array.
885 mask_to_verbs(slap_verbmasks
*v
, slap_mask_t m
, BerVarray
*bva
) {
889 for (i
=0; !BER_BVISNULL(&v
[i
].word
); i
++) {
890 if (!v
[i
].mask
) continue;
891 if (( m
& v
[i
].mask
) == v
[i
].mask
) {
892 value_add_one( bva
, &v
[i
].word
);
903 slap_verbmasks_init( slap_verbmasks
**vp
, slap_verbmasks
*v
)
907 assert( *vp
== NULL
);
909 for ( i
= 0; !BER_BVISNULL( &v
[ i
].word
); i
++ ) /* EMPTY */;
911 *vp
= ch_calloc( i
+ 1, sizeof( slap_verbmasks
) );
913 for ( i
= 0; !BER_BVISNULL( &v
[ i
].word
); i
++ ) {
914 ber_dupbv( &(*vp
)[ i
].word
, &v
[ i
].word
);
915 *((slap_mask_t
*)&(*vp
)[ i
].mask
) = v
[ i
].mask
;
918 BER_BVZERO( &(*vp
)[ i
].word
);
924 slap_verbmasks_destroy( slap_verbmasks
*v
)
930 for ( i
= 0; !BER_BVISNULL( &v
[ i
].word
); i
++ ) {
931 ch_free( v
[ i
].word
.bv_val
);
940 slap_verbmasks_append(
944 slap_mask_t
*ignore
)
949 return LDAP_OPERATIONS_ERROR
;
952 for ( i
= 0; !BER_BVISNULL( &(*vp
)[ i
].word
); i
++ ) {
953 if ( !(*vp
)[ i
].mask
) continue;
955 if ( ignore
!= NULL
) {
958 for ( j
= 0; ignore
[ j
] != 0; j
++ ) {
959 if ( (*vp
)[ i
].mask
== ignore
[ j
] ) {
965 if ( ( m
& (*vp
)[ i
].mask
) == (*vp
)[ i
].mask
) {
966 if ( ber_bvstrcasecmp( v
, &(*vp
)[ i
].word
) == 0 ) {
967 /* already set; ignore */
971 return LDAP_TYPE_OR_VALUE_EXISTS
;
974 if ( m
& (*vp
)[ i
].mask
) {
976 return LDAP_CONSTRAINT_VIOLATION
;
981 *vp
= ch_realloc( *vp
, sizeof( slap_verbmasks
) * ( i
+ 2 ) );
982 ber_dupbv( &(*vp
)[ i
].word
, v
);
983 *((slap_mask_t
*)&(*vp
)[ i
].mask
) = m
;
984 BER_BVZERO( &(*vp
)[ i
+ 1 ].word
);
990 enum_to_verb(slap_verbmasks
*v
, slap_mask_t m
, struct berval
*bv
) {
993 for (i
=0; !BER_BVISNULL(&v
[i
].word
); i
++) {
994 if ( m
== v
[i
].mask
) {
1004 /* register a new verbmask */
1006 slap_verbmask_register( slap_verbmasks
*vm_
, slap_verbmasks
**vmp
, struct berval
*bv
, int mask
)
1008 slap_verbmasks
*vm
= *vmp
;
1011 /* check for duplicate word */
1012 /* NOTE: we accept duplicate codes; the first occurrence will be used
1013 * when mapping from mask to verb */
1014 i
= verb_to_mask( bv
->bv_val
, vm
);
1015 if ( !BER_BVISNULL( &vm
[ i
].word
) ) {
1019 for ( i
= 0; !BER_BVISNULL( &vm
[ i
].word
); i
++ )
1023 /* first time: duplicate array */
1024 vm
= ch_calloc( i
+ 2, sizeof( slap_verbmasks
) );
1025 for ( i
= 0; !BER_BVISNULL( &vm_
[ i
].word
); i
++ )
1027 ber_dupbv( &vm
[ i
].word
, &vm_
[ i
].word
);
1028 *((slap_mask_t
*)&vm
[ i
].mask
) = vm_
[ i
].mask
;
1032 vm
= ch_realloc( vm
, (i
+ 2) * sizeof( slap_verbmasks
) );
1035 ber_dupbv( &vm
[ i
].word
, bv
);
1036 *((slap_mask_t
*)&vm
[ i
].mask
) = mask
;
1038 BER_BVZERO( &vm
[ i
+1 ].word
);
1045 static slap_verbmasks slap_ldap_response_code_
[] = {
1046 { BER_BVC("success"), LDAP_SUCCESS
},
1048 { BER_BVC("operationsError"), LDAP_OPERATIONS_ERROR
},
1049 { BER_BVC("protocolError"), LDAP_PROTOCOL_ERROR
},
1050 { BER_BVC("timelimitExceeded"), LDAP_TIMELIMIT_EXCEEDED
},
1051 { BER_BVC("sizelimitExceeded"), LDAP_SIZELIMIT_EXCEEDED
},
1052 { BER_BVC("compareFalse"), LDAP_COMPARE_FALSE
},
1053 { BER_BVC("compareTrue"), LDAP_COMPARE_TRUE
},
1055 { BER_BVC("authMethodNotSupported"), LDAP_AUTH_METHOD_NOT_SUPPORTED
},
1056 { BER_BVC("strongAuthNotSupported"), LDAP_STRONG_AUTH_NOT_SUPPORTED
},
1057 { BER_BVC("strongAuthRequired"), LDAP_STRONG_AUTH_REQUIRED
},
1058 { BER_BVC("strongerAuthRequired"), LDAP_STRONGER_AUTH_REQUIRED
},
1059 #if 0 /* not LDAPv3 */
1060 { BER_BVC("partialResults"), LDAP_PARTIAL_RESULTS
},
1063 { BER_BVC("referral"), LDAP_REFERRAL
},
1064 { BER_BVC("adminlimitExceeded"), LDAP_ADMINLIMIT_EXCEEDED
},
1065 { BER_BVC("unavailableCriticalExtension"), LDAP_UNAVAILABLE_CRITICAL_EXTENSION
},
1066 { BER_BVC("confidentialityRequired"), LDAP_CONFIDENTIALITY_REQUIRED
},
1067 { BER_BVC("saslBindInProgress"), LDAP_SASL_BIND_IN_PROGRESS
},
1069 { BER_BVC("noSuchAttribute"), LDAP_NO_SUCH_ATTRIBUTE
},
1070 { BER_BVC("undefinedType"), LDAP_UNDEFINED_TYPE
},
1071 { BER_BVC("inappropriateMatching"), LDAP_INAPPROPRIATE_MATCHING
},
1072 { BER_BVC("constraintViolation"), LDAP_CONSTRAINT_VIOLATION
},
1073 { BER_BVC("typeOrValueExists"), LDAP_TYPE_OR_VALUE_EXISTS
},
1074 { BER_BVC("invalidSyntax"), LDAP_INVALID_SYNTAX
},
1076 { BER_BVC("noSuchObject"), LDAP_NO_SUCH_OBJECT
},
1077 { BER_BVC("aliasProblem"), LDAP_ALIAS_PROBLEM
},
1078 { BER_BVC("invalidDnSyntax"), LDAP_INVALID_DN_SYNTAX
},
1079 #if 0 /* not LDAPv3 */
1080 { BER_BVC("isLeaf"), LDAP_IS_LEAF
},
1082 { BER_BVC("aliasDerefProblem"), LDAP_ALIAS_DEREF_PROBLEM
},
1084 { BER_BVC("proxyAuthzFailure"), LDAP_X_PROXY_AUTHZ_FAILURE
},
1085 { BER_BVC("inappropriateAuth"), LDAP_INAPPROPRIATE_AUTH
},
1086 { BER_BVC("invalidCredentials"), LDAP_INVALID_CREDENTIALS
},
1087 { BER_BVC("insufficientAccess"), LDAP_INSUFFICIENT_ACCESS
},
1089 { BER_BVC("busy"), LDAP_BUSY
},
1090 { BER_BVC("unavailable"), LDAP_UNAVAILABLE
},
1091 { BER_BVC("unwillingToPerform"), LDAP_UNWILLING_TO_PERFORM
},
1092 { BER_BVC("loopDetect"), LDAP_LOOP_DETECT
},
1094 { BER_BVC("namingViolation"), LDAP_NAMING_VIOLATION
},
1095 { BER_BVC("objectClassViolation"), LDAP_OBJECT_CLASS_VIOLATION
},
1096 { BER_BVC("notAllowedOnNonleaf"), LDAP_NOT_ALLOWED_ON_NONLEAF
},
1097 { BER_BVC("notAllowedOnRdn"), LDAP_NOT_ALLOWED_ON_RDN
},
1098 { BER_BVC("alreadyExists"), LDAP_ALREADY_EXISTS
},
1099 { BER_BVC("noObjectClassMods"), LDAP_NO_OBJECT_CLASS_MODS
},
1100 { BER_BVC("resultsTooLarge"), LDAP_RESULTS_TOO_LARGE
},
1101 { BER_BVC("affectsMultipleDsas"), LDAP_AFFECTS_MULTIPLE_DSAS
},
1103 { BER_BVC("other"), LDAP_OTHER
},
1105 /* extension-specific */
1107 { BER_BVC("cupResourcesExhausted"), LDAP_CUP_RESOURCES_EXHAUSTED
},
1108 { BER_BVC("cupSecurityViolation"), LDAP_CUP_SECURITY_VIOLATION
},
1109 { BER_BVC("cupInvalidData"), LDAP_CUP_INVALID_DATA
},
1110 { BER_BVC("cupUnsupportedScheme"), LDAP_CUP_UNSUPPORTED_SCHEME
},
1111 { BER_BVC("cupReloadRequired"), LDAP_CUP_RELOAD_REQUIRED
},
1113 { BER_BVC("cancelled"), LDAP_CANCELLED
},
1114 { BER_BVC("noSuchOperation"), LDAP_NO_SUCH_OPERATION
},
1115 { BER_BVC("tooLate"), LDAP_TOO_LATE
},
1116 { BER_BVC("cannotCancel"), LDAP_CANNOT_CANCEL
},
1118 { BER_BVC("assertionFailed"), LDAP_ASSERTION_FAILED
},
1120 { BER_BVC("proxiedAuthorizationDenied"), LDAP_PROXIED_AUTHORIZATION_DENIED
},
1122 { BER_BVC("syncRefreshRequired"), LDAP_SYNC_REFRESH_REQUIRED
},
1124 { BER_BVC("noOperation"), LDAP_X_NO_OPERATION
},
1129 slap_verbmasks
*slap_ldap_response_code
= slap_ldap_response_code_
;
1132 slap_ldap_response_code_register( struct berval
*bv
, int err
)
1134 return slap_verbmask_register( slap_ldap_response_code_
,
1135 &slap_ldap_response_code
, bv
, err
);
1139 static slap_verbmasks tlskey
[] = {
1140 { BER_BVC("no"), SB_TLS_OFF
},
1141 { BER_BVC("yes"), SB_TLS_ON
},
1142 { BER_BVC("critical"), SB_TLS_CRITICAL
},
1146 static slap_verbmasks crlkeys
[] = {
1147 { BER_BVC("none"), LDAP_OPT_X_TLS_CRL_NONE
},
1148 { BER_BVC("peer"), LDAP_OPT_X_TLS_CRL_PEER
},
1149 { BER_BVC("all"), LDAP_OPT_X_TLS_CRL_ALL
},
1153 static slap_verbmasks vfykeys
[] = {
1154 { BER_BVC("never"), LDAP_OPT_X_TLS_NEVER
},
1155 { BER_BVC("demand"), LDAP_OPT_X_TLS_DEMAND
},
1156 { BER_BVC("try"), LDAP_OPT_X_TLS_TRY
},
1157 { BER_BVC("hard"), LDAP_OPT_X_TLS_HARD
},
1162 static slap_verbmasks methkey
[] = {
1163 { BER_BVC("none"), LDAP_AUTH_NONE
},
1164 { BER_BVC("simple"), LDAP_AUTH_SIMPLE
},
1165 #ifdef HAVE_CYRUS_SASL
1166 { BER_BVC("sasl"), LDAP_AUTH_SASL
},
1171 static slap_verbmasks versionkey
[] = {
1172 { BER_BVC("2"), LDAP_VERSION2
},
1173 { BER_BVC("3"), LDAP_VERSION3
},
1177 static slap_cf_aux_table bindkey
[] = {
1178 { BER_BVC("uri="), offsetof(slap_bindconf
, sb_uri
), 'b', 1, NULL
},
1179 { BER_BVC("version="), offsetof(slap_bindconf
, sb_version
), 'i', 0, versionkey
},
1180 { BER_BVC("bindmethod="), offsetof(slap_bindconf
, sb_method
), 'i', 0, methkey
},
1181 { BER_BVC("timeout="), offsetof(slap_bindconf
, sb_timeout_api
), 'i', 0, NULL
},
1182 { BER_BVC("network-timeout="), offsetof(slap_bindconf
, sb_timeout_net
), 'i', 0, NULL
},
1183 { BER_BVC("binddn="), offsetof(slap_bindconf
, sb_binddn
), 'b', 1, (slap_verbmasks
*)dnNormalize
},
1184 { BER_BVC("credentials="), offsetof(slap_bindconf
, sb_cred
), 'b', 1, NULL
},
1185 { BER_BVC("saslmech="), offsetof(slap_bindconf
, sb_saslmech
), 'b', 0, NULL
},
1186 { BER_BVC("secprops="), offsetof(slap_bindconf
, sb_secprops
), 's', 0, NULL
},
1187 { BER_BVC("realm="), offsetof(slap_bindconf
, sb_realm
), 'b', 0, NULL
},
1188 { BER_BVC("authcID="), offsetof(slap_bindconf
, sb_authcId
), 'b', 1, NULL
},
1189 { BER_BVC("authzID="), offsetof(slap_bindconf
, sb_authzId
), 'b', 1, (slap_verbmasks
*)authzNormalize
},
1191 { BER_BVC("starttls="), offsetof(slap_bindconf
, sb_tls
), 'i', 0, tlskey
},
1193 /* NOTE: replace "13" with the actual index
1194 * of the first TLS-related line */
1195 #define aux_TLS (bindkey+13) /* beginning of TLS keywords */
1197 { BER_BVC("tls_cert="), offsetof(slap_bindconf
, sb_tls_cert
), 's', 1, NULL
},
1198 { BER_BVC("tls_key="), offsetof(slap_bindconf
, sb_tls_key
), 's', 1, NULL
},
1199 { BER_BVC("tls_cacert="), offsetof(slap_bindconf
, sb_tls_cacert
), 's', 1, NULL
},
1200 { BER_BVC("tls_cacertdir="), offsetof(slap_bindconf
, sb_tls_cacertdir
), 's', 1, NULL
},
1201 { BER_BVC("tls_reqcert="), offsetof(slap_bindconf
, sb_tls_reqcert
), 's', 1, NULL
},
1202 { BER_BVC("tls_cipher_suite="), offsetof(slap_bindconf
, sb_tls_cipher_suite
), 's', 1, NULL
},
1203 #ifdef HAVE_OPENSSL_CRL
1204 { BER_BVC("tls_crlcheck="), offsetof(slap_bindconf
, sb_tls_crlcheck
), 's', 1, NULL
},
1207 { BER_BVNULL
, 0, 0, 0, NULL
}
1212 * 'b': struct berval; if !NULL, normalize using ((slap_mr_normalize_func *)aux)
1213 * 'i': int; if !NULL, compute using ((slap_verbmasks *)aux)
1216 * 'U': unsigned long
1220 slap_cf_aux_table_parse( const char *word
, void *dst
, slap_cf_aux_table
*tab0
, LDAP_CONST
char *tabmsg
)
1222 int rc
= SLAP_CONF_UNKNOWN
;
1223 slap_cf_aux_table
*tab
;
1225 for ( tab
= tab0
; !BER_BVISNULL( &tab
->key
); tab
++ ) {
1226 if ( !strncasecmp( word
, tab
->key
.bv_val
, tab
->key
.bv_len
) ) {
1231 unsigned long *ulptr
;
1232 struct berval
*bptr
;
1233 const char *val
= word
+ tab
->key
.bv_len
;
1235 switch ( tab
->type
) {
1237 cptr
= (char **)((char *)dst
+ tab
->off
);
1238 *cptr
= ch_strdup( val
);
1243 bptr
= (struct berval
*)((char *)dst
+ tab
->off
);
1244 if ( tab
->aux
!= NULL
) {
1246 slap_mr_normalize_func
*normalize
= (slap_mr_normalize_func
*)tab
->aux
;
1248 ber_str2bv( val
, 0, 0, &dn
);
1249 rc
= normalize( 0, NULL
, NULL
, &dn
, bptr
, NULL
);
1252 ber_str2bv( val
, 0, 1, bptr
);
1258 iptr
= (int *)((char *)dst
+ tab
->off
);
1260 if ( tab
->aux
!= NULL
) {
1261 slap_verbmasks
*aux
= (slap_verbmasks
*)tab
->aux
;
1263 assert( aux
!= NULL
);
1266 for ( j
= 0; !BER_BVISNULL( &aux
[j
].word
); j
++ ) {
1267 if ( !strcasecmp( val
, aux
[j
].word
.bv_val
) ) {
1268 *iptr
= aux
[j
].mask
;
1275 rc
= lutil_atoix( iptr
, val
, 0 );
1280 uptr
= (unsigned *)((char *)dst
+ tab
->off
);
1282 rc
= lutil_atoux( uptr
, val
, 0 );
1286 lptr
= (long *)((char *)dst
+ tab
->off
);
1288 rc
= lutil_atolx( lptr
, val
, 0 );
1292 ulptr
= (unsigned long *)((char *)dst
+ tab
->off
);
1294 rc
= lutil_atoulx( ulptr
, val
, 0 );
1299 Debug( LDAP_DEBUG_ANY
, "invalid %s value %s\n",
1311 slap_cf_aux_table_unparse( void *src
, struct berval
*bv
, slap_cf_aux_table
*tab0
)
1313 char buf
[AC_LINE_MAX
], *ptr
;
1314 slap_cf_aux_table
*tab
;
1318 for (tab
= tab0
; !BER_BVISNULL(&tab
->key
); tab
++ ) {
1323 unsigned long *ulptr
;
1324 struct berval
*bptr
;
1326 cptr
= (char **)((char *)src
+ tab
->off
);
1328 switch ( tab
->type
) {
1330 bptr
= (struct berval
*)((char *)src
+ tab
->off
);
1331 cptr
= &bptr
->bv_val
;
1336 ptr
= lutil_strcopy( ptr
, tab
->key
.bv_val
);
1337 if ( tab
->quote
) *ptr
++ = '"';
1338 ptr
= lutil_strcopy( ptr
, *cptr
);
1339 if ( tab
->quote
) *ptr
++ = '"';
1344 iptr
= (int *)((char *)src
+ tab
->off
);
1346 if ( tab
->aux
!= NULL
) {
1347 slap_verbmasks
*aux
= (slap_verbmasks
*)tab
->aux
;
1349 for ( i
= 0; !BER_BVISNULL( &aux
[i
].word
); i
++ ) {
1350 if ( *iptr
== aux
[i
].mask
) {
1352 ptr
= lutil_strcopy( ptr
, tab
->key
.bv_val
);
1353 ptr
= lutil_strcopy( ptr
, aux
[i
].word
.bv_val
);
1360 ptr
= lutil_strcopy( ptr
, tab
->key
.bv_val
);
1361 ptr
+= snprintf( ptr
, sizeof( buf
) - ( ptr
- buf
), "%d", *iptr
);
1366 uptr
= (unsigned *)((char *)src
+ tab
->off
);
1368 ptr
= lutil_strcopy( ptr
, tab
->key
.bv_val
);
1369 ptr
+= snprintf( ptr
, sizeof( buf
) - ( ptr
- buf
), "%u", *uptr
);
1373 lptr
= (long *)((char *)src
+ tab
->off
);
1375 ptr
= lutil_strcopy( ptr
, tab
->key
.bv_val
);
1376 ptr
+= snprintf( ptr
, sizeof( buf
) - ( ptr
- buf
), "%ld", *lptr
);
1380 ulptr
= (unsigned long *)((char *)src
+ tab
->off
);
1382 ptr
= lutil_strcopy( ptr
, tab
->key
.bv_val
);
1383 ptr
+= snprintf( ptr
, sizeof( buf
) - ( ptr
- buf
), "%lu", *ulptr
);
1391 tmp
.bv_len
= ptr
- buf
;
1392 ber_dupbv( bv
, &tmp
);
1397 slap_tls_get_config( LDAP
*ld
, int opt
, char **val
)
1400 slap_verbmasks
*keys
;
1405 case LDAP_OPT_X_TLS_CRLCHECK
:
1408 case LDAP_OPT_X_TLS_REQUIRE_CERT
:
1414 ldap_pvt_tls_get_option( ld
, opt
, &ival
);
1415 for (i
=0; !BER_BVISNULL(&keys
[i
].word
); i
++) {
1416 if (keys
[i
].mask
== ival
) {
1417 *val
= ch_strdup( keys
[i
].word
.bv_val
);
1426 bindconf_tls_parse( const char *word
, slap_bindconf
*bc
)
1429 if ( slap_cf_aux_table_parse( word
, bc
, aux_TLS
, "tls config" ) == 0 ) {
1430 bc
->sb_tls_do_init
= 1;
1438 bindconf_tls_unparse( slap_bindconf
*bc
, struct berval
*bv
)
1441 return slap_cf_aux_table_unparse( bc
, bv
, aux_TLS
);
1447 bindconf_parse( const char *word
, slap_bindconf
*bc
)
1450 /* Detect TLS config changes explicitly */
1451 if ( bindconf_tls_parse( word
, bc
) == 0 ) {
1455 return slap_cf_aux_table_parse( word
, bc
, bindkey
, "bind config" );
1459 bindconf_unparse( slap_bindconf
*bc
, struct berval
*bv
)
1461 return slap_cf_aux_table_unparse( bc
, bv
, bindkey
);
1464 void bindconf_free( slap_bindconf
*bc
) {
1465 if ( !BER_BVISNULL( &bc
->sb_uri
) ) {
1466 ch_free( bc
->sb_uri
.bv_val
);
1467 BER_BVZERO( &bc
->sb_uri
);
1469 if ( !BER_BVISNULL( &bc
->sb_binddn
) ) {
1470 ch_free( bc
->sb_binddn
.bv_val
);
1471 BER_BVZERO( &bc
->sb_binddn
);
1473 if ( !BER_BVISNULL( &bc
->sb_cred
) ) {
1474 ch_free( bc
->sb_cred
.bv_val
);
1475 BER_BVZERO( &bc
->sb_cred
);
1477 if ( !BER_BVISNULL( &bc
->sb_saslmech
) ) {
1478 ch_free( bc
->sb_saslmech
.bv_val
);
1479 BER_BVZERO( &bc
->sb_saslmech
);
1481 if ( bc
->sb_secprops
) {
1482 ch_free( bc
->sb_secprops
);
1483 bc
->sb_secprops
= NULL
;
1485 if ( !BER_BVISNULL( &bc
->sb_realm
) ) {
1486 ch_free( bc
->sb_realm
.bv_val
);
1487 BER_BVZERO( &bc
->sb_realm
);
1489 if ( !BER_BVISNULL( &bc
->sb_authcId
) ) {
1490 ch_free( bc
->sb_authcId
.bv_val
);
1491 BER_BVZERO( &bc
->sb_authcId
);
1493 if ( !BER_BVISNULL( &bc
->sb_authzId
) ) {
1494 ch_free( bc
->sb_authzId
.bv_val
);
1495 BER_BVZERO( &bc
->sb_authzId
);
1498 if ( bc
->sb_tls_cert
) {
1499 ch_free( bc
->sb_tls_cert
);
1500 bc
->sb_tls_cert
= NULL
;
1502 if ( bc
->sb_tls_key
) {
1503 ch_free( bc
->sb_tls_key
);
1504 bc
->sb_tls_key
= NULL
;
1506 if ( bc
->sb_tls_cacert
) {
1507 ch_free( bc
->sb_tls_cacert
);
1508 bc
->sb_tls_cacert
= NULL
;
1510 if ( bc
->sb_tls_cacertdir
) {
1511 ch_free( bc
->sb_tls_cacertdir
);
1512 bc
->sb_tls_cacertdir
= NULL
;
1514 if ( bc
->sb_tls_reqcert
) {
1515 ch_free( bc
->sb_tls_reqcert
);
1516 bc
->sb_tls_reqcert
= NULL
;
1518 if ( bc
->sb_tls_cipher_suite
) {
1519 ch_free( bc
->sb_tls_cipher_suite
);
1520 bc
->sb_tls_cipher_suite
= NULL
;
1522 #ifdef HAVE_OPENSSL_CRL
1523 if ( bc
->sb_tls_crlcheck
) {
1524 ch_free( bc
->sb_tls_crlcheck
);
1525 bc
->sb_tls_crlcheck
= NULL
;
1532 bindconf_tls_defaults( slap_bindconf
*bc
)
1535 if ( bc
->sb_tls_do_init
) {
1536 if ( !bc
->sb_tls_cacert
)
1537 ldap_pvt_tls_get_option( slap_tls_ld
, LDAP_OPT_X_TLS_CACERTFILE
,
1538 &bc
->sb_tls_cacert
);
1539 if ( !bc
->sb_tls_cacertdir
)
1540 ldap_pvt_tls_get_option( slap_tls_ld
, LDAP_OPT_X_TLS_CACERTDIR
,
1541 &bc
->sb_tls_cacertdir
);
1542 if ( !bc
->sb_tls_cert
)
1543 ldap_pvt_tls_get_option( slap_tls_ld
, LDAP_OPT_X_TLS_CERTFILE
,
1545 if ( !bc
->sb_tls_key
)
1546 ldap_pvt_tls_get_option( slap_tls_ld
, LDAP_OPT_X_TLS_KEYFILE
,
1548 if ( !bc
->sb_tls_cipher_suite
)
1549 ldap_pvt_tls_get_option( slap_tls_ld
, LDAP_OPT_X_TLS_CIPHER_SUITE
,
1550 &bc
->sb_tls_cipher_suite
);
1551 if ( !bc
->sb_tls_reqcert
)
1552 bc
->sb_tls_reqcert
= ch_strdup("demand");
1553 #ifdef HAVE_OPENSSL_CRL
1554 if ( !bc
->sb_tls_crlcheck
)
1555 slap_tls_get_config( slap_tls_ld
, LDAP_OPT_X_TLS_CRLCHECK
,
1556 &bc
->sb_tls_crlcheck
);
1568 { "tls_cert", offsetof(slap_bindconf
, sb_tls_cert
), LDAP_OPT_X_TLS_CERTFILE
},
1569 { "tls_key", offsetof(slap_bindconf
, sb_tls_key
), LDAP_OPT_X_TLS_KEYFILE
},
1570 { "tls_cacert", offsetof(slap_bindconf
, sb_tls_cacert
), LDAP_OPT_X_TLS_CACERTFILE
},
1571 { "tls_cacertdir", offsetof(slap_bindconf
, sb_tls_cacertdir
), LDAP_OPT_X_TLS_CACERTDIR
},
1572 { "tls_cipher_suite", offsetof(slap_bindconf
, sb_tls_cipher_suite
), LDAP_OPT_X_TLS_CIPHER_SUITE
},
1576 int bindconf_tls_set( slap_bindconf
*bc
, LDAP
*ld
)
1578 int i
, rc
, newctx
= 0, res
= 0;
1579 char *ptr
= (char *)bc
, **word
;
1581 bc
->sb_tls_do_init
= 0;
1583 for (i
=0; bindtlsopts
[i
].opt
; i
++) {
1584 word
= (char **)(ptr
+ bindtlsopts
[i
].offset
);
1586 rc
= ldap_set_option( ld
, bindtlsopts
[i
].opt
, *word
);
1588 Debug( LDAP_DEBUG_ANY
,
1589 "bindconf_tls_set: failed to set %s to %s\n",
1590 bindtlsopts
[i
].key
, *word
, 0 );
1596 if ( bc
->sb_tls_reqcert
) {
1597 rc
= ldap_int_tls_config( ld
, LDAP_OPT_X_TLS_REQUIRE_CERT
,
1598 bc
->sb_tls_reqcert
);
1600 Debug( LDAP_DEBUG_ANY
,
1601 "bindconf_tls_set: failed to set tls_reqcert to %s\n",
1602 bc
->sb_tls_reqcert
, 0, 0 );
1607 #ifdef HAVE_OPENSSL_CRL
1608 if ( bc
->sb_tls_crlcheck
) {
1609 rc
= ldap_int_tls_config( ld
, LDAP_OPT_X_TLS_CRLCHECK
,
1610 bc
->sb_tls_crlcheck
);
1612 Debug( LDAP_DEBUG_ANY
,
1613 "bindconf_tls_set: failed to set tls_crlcheck to %s\n",
1614 bc
->sb_tls_crlcheck
, 0, 0 );
1623 if ( bc
->sb_tls_ctx
) {
1624 ldap_pvt_tls_ctx_free( bc
->sb_tls_ctx
);
1625 bc
->sb_tls_ctx
= NULL
;
1627 rc
= ldap_set_option( ld
, LDAP_OPT_X_TLS_NEWCTX
, &opt
);
1631 ldap_get_option( ld
, LDAP_OPT_X_TLS_CTX
, &bc
->sb_tls_ctx
);
1639 * connect to a client using the bindconf data
1640 * note: should move "version" into bindconf...
1643 slap_client_connect( LDAP
**ldp
, slap_bindconf
*sb
)
1649 /* Init connection to master */
1650 rc
= ldap_initialize( &ld
, sb
->sb_uri
.bv_val
);
1651 if ( rc
!= LDAP_SUCCESS
) {
1652 Debug( LDAP_DEBUG_ANY
,
1653 "slap_client_connect: "
1654 "ldap_initialize(%s) failed (%d)\n",
1655 sb
->sb_uri
.bv_val
, rc
, 0 );
1659 if ( sb
->sb_version
!= 0 ) {
1660 ldap_set_option( ld
, LDAP_OPT_PROTOCOL_VERSION
,
1661 (const void *)&sb
->sb_version
);
1664 if ( sb
->sb_timeout_api
) {
1665 tv
.tv_sec
= sb
->sb_timeout_api
;
1667 ldap_set_option( ld
, LDAP_OPT_TIMEOUT
, &tv
);
1670 if ( sb
->sb_timeout_net
) {
1671 tv
.tv_sec
= sb
->sb_timeout_net
;
1673 ldap_set_option( ld
, LDAP_OPT_NETWORK_TIMEOUT
, &tv
);
1677 if ( sb
->sb_tls_do_init
) {
1678 rc
= bindconf_tls_set( sb
, ld
);
1680 } else if ( sb
->sb_tls_ctx
) {
1681 rc
= ldap_set_option( ld
, LDAP_OPT_X_TLS_CTX
,
1686 Debug( LDAP_DEBUG_ANY
,
1687 "slap_client_connect: "
1688 "URI=%s TLS context initialization failed (%d)\n",
1689 sb
->sb_uri
.bv_val
, rc
, 0 );
1696 rc
= ldap_start_tls_s( ld
, NULL
, NULL
);
1697 if ( rc
!= LDAP_SUCCESS
) {
1698 Debug( LDAP_DEBUG_ANY
,
1699 "slap_client_connect: URI=%s "
1700 "%s, ldap_start_tls failed (%d)\n",
1702 sb
->sb_tls
== SB_TLS_CRITICAL
?
1703 "Error" : "Warning",
1705 if ( sb
->sb_tls
== SB_TLS_CRITICAL
) {
1711 if ( sb
->sb_method
== LDAP_AUTH_SASL
) {
1712 #ifdef HAVE_CYRUS_SASL
1715 if ( sb
->sb_secprops
!= NULL
) {
1716 rc
= ldap_set_option( ld
,
1717 LDAP_OPT_X_SASL_SECPROPS
, sb
->sb_secprops
);
1719 if( rc
!= LDAP_OPT_SUCCESS
) {
1720 Debug( LDAP_DEBUG_ANY
,
1721 "slap_client_connect: "
1722 "error, ldap_set_option "
1723 "(%s,SECPROPS,\"%s\") failed!\n",
1724 sb
->sb_uri
.bv_val
, sb
->sb_secprops
, 0 );
1729 defaults
= lutil_sasl_defaults( ld
,
1730 sb
->sb_saslmech
.bv_val
,
1731 sb
->sb_realm
.bv_val
,
1732 sb
->sb_authcId
.bv_val
,
1734 sb
->sb_authzId
.bv_val
);
1735 if ( defaults
== NULL
) {
1740 rc
= ldap_sasl_interactive_bind_s( ld
,
1741 sb
->sb_binddn
.bv_val
,
1742 sb
->sb_saslmech
.bv_val
,
1745 lutil_sasl_interact
,
1748 lutil_sasl_freedefs( defaults
);
1750 /* FIXME: different error behaviors according to
1752 * 2) on err policy : exit, retry, backoff ...
1754 if ( rc
!= LDAP_SUCCESS
) {
1755 static struct berval bv_GSSAPI
= BER_BVC( "GSSAPI" );
1757 Debug( LDAP_DEBUG_ANY
, "slap_client_connect: URI=%s "
1758 "ldap_sasl_interactive_bind_s failed (%d)\n",
1759 sb
->sb_uri
.bv_val
, rc
, 0 );
1761 /* FIXME (see above comment) */
1762 /* if Kerberos credentials cache is not active, retry */
1763 if ( ber_bvcmp( &sb
->sb_saslmech
, &bv_GSSAPI
) == 0 &&
1764 rc
== LDAP_LOCAL_ERROR
)
1766 rc
= LDAP_SERVER_DOWN
;
1771 #else /* HAVE_CYRUS_SASL */
1772 /* Should never get here, we trapped this at config time */
1774 Debug( LDAP_DEBUG_SYNC
, "not compiled with SASL support\n", 0, 0, 0 );
1779 } else if ( sb
->sb_method
== LDAP_AUTH_SIMPLE
) {
1780 rc
= ldap_sasl_bind_s( ld
,
1781 sb
->sb_binddn
.bv_val
, LDAP_SASL_SIMPLE
,
1782 &sb
->sb_cred
, NULL
, NULL
, NULL
);
1783 if ( rc
!= LDAP_SUCCESS
) {
1784 Debug( LDAP_DEBUG_ANY
, "slap_client_connect: "
1786 "ldap_sasl_bind_s failed (%d)\n",
1787 sb
->sb_uri
.bv_val
, sb
->sb_binddn
.bv_val
, rc
);
1795 ldap_unbind_ext( ld
, NULL
, NULL
);
1806 /* -------------------------------------- */
1810 strtok_quote( char *line
, char *sep
, char **quote_ptr
)
1817 if ( line
!= NULL
) {
1820 while ( *next
&& strchr( sep
, *next
) ) {
1824 if ( *next
== '\0' ) {
1830 for ( inquote
= 0; *next
; ) {
1838 AC_MEMCPY( next
, next
+ 1, strlen( next
+ 1 ) + 1 );
1844 next
+ 1, strlen( next
+ 1 ) + 1 );
1845 next
++; /* dont parse the escaped character */
1850 if ( strchr( sep
, *next
) != NULL
) {
1864 static char buf
[AC_LINE_MAX
];
1866 static size_t lmax
, lcur
;
1868 #define CATLINE( buf ) \
1870 size_t len = strlen( buf ); \
1871 while ( lcur + len + 1 > lmax ) { \
1872 lmax += AC_LINE_MAX; \
1873 line = (char *) ch_realloc( line, lmax ); \
1875 strcpy( line + lcur, buf ); \
1880 fp_getline_init(ConfigArgs
*c
) {
1886 fp_getline( FILE *fp
, ConfigArgs
*c
)
1894 /* avoid stack of bufs */
1895 if ( strncasecmp( line
, "include", STRLENOF( "include" ) ) == 0 ) {
1901 while ( fgets( buf
, sizeof( buf
), fp
) ) {
1902 p
= strchr( buf
, '\n' );
1904 if ( p
> buf
&& p
[-1] == '\r' ) {
1912 && ( p
= line
+ strlen( line
) - 1 )[0] == '\\'
1919 if ( !isspace( (unsigned char)buf
[0] ) ) {
1930 return(line
[0] ? 1 : 0);
1934 fp_parse_line(ConfigArgs
*c
)
1937 static char *const hide
[] = {
1938 "rootpw", "replica", "syncrepl", /* in slapd */
1939 "acl-bind", "acl-method", "idassert-bind", /* in back-ldap */
1940 "acl-passwd", "bindpw", /* in back-<ldap/meta> */
1941 "pseudorootpw", /* in back-meta */
1942 "dbpasswd", /* in back-sql */
1946 int i
= (int)(sizeof(hide
)/sizeof(hide
[0])) - 1;
1948 c
->tline
= ch_strdup(c
->line
);
1949 token
= strtok_quote(c
->tline
, " \t", "e_ptr
);
1951 if(token
) for(i
= 0; hide
[i
]; i
++) if(!strcasecmp(token
, hide
[i
])) break;
1952 if(quote_ptr
) *quote_ptr
= ' ';
1953 Debug(LDAP_DEBUG_CONFIG
, "line %d (%s%s)\n", c
->lineno
,
1954 hide
[i
] ? hide
[i
] : c
->line
, hide
[i
] ? " ***" : "");
1955 if(quote_ptr
) *quote_ptr
= '\0';
1957 for(;; token
= strtok_quote(NULL
, " \t", "e_ptr
)) {
1958 if(c
->argc
>= c
->argv_size
) {
1960 tmp
= ch_realloc(c
->argv
, (c
->argv_size
+ ARGS_STEP
) * sizeof(*c
->argv
));
1962 Debug(LDAP_DEBUG_ANY
, "line %d: out of memory\n", c
->lineno
, 0, 0);
1966 c
->argv_size
+= ARGS_STEP
;
1970 c
->argv
[c
->argc
++] = token
;
1972 c
->argv
[c
->argc
] = NULL
;
1979 ucdata_unload( UCDATA_ALL
);
1981 /* NOTE: in case of early exit, frontendDB can be NULL */
1982 if ( frontendDB
->be_schemandn
.bv_val
)
1983 free( frontendDB
->be_schemandn
.bv_val
);
1984 if ( frontendDB
->be_schemadn
.bv_val
)
1985 free( frontendDB
->be_schemadn
.bv_val
);
1986 if ( frontendDB
->be_acl
)
1987 acl_destroy( frontendDB
->be_acl
, NULL
);
1990 if ( slapd_args_file
)
1991 free ( slapd_args_file
);
1992 if ( slapd_pid_file
)
1993 free ( slapd_pid_file
);
1994 if ( default_passwd_hash
)
1995 ldap_charray_free( default_passwd_hash
);
1999 slap_str2clist( char ***out
, char *in
, const char *brkstr
)
2007 /* find last element in list */
2008 for (i
= 0; *out
&& (*out
)[i
]; i
++);
2010 /* protect the input string from strtok */
2011 str
= ch_strdup( in
);
2013 if ( *str
== '\0' ) {
2018 /* Count words in string */
2020 for ( s
= str
; *s
; s
++ ) {
2021 if ( strchr( brkstr
, *s
) != NULL
) {
2026 *out
= ch_realloc( *out
, ( i
+ j
+ 1 ) * sizeof( char * ) );
2028 for ( s
= ldap_pvt_strtok( str
, brkstr
, &lasts
);
2030 s
= ldap_pvt_strtok( NULL
, brkstr
, &lasts
) )
2032 *new = ch_strdup( s
);
2041 int config_generic_wrapper( Backend
*be
, const char *fname
, int lineno
,
2042 int argc
, char **argv
)
2044 ConfigArgs c
= { 0 };
2055 c
.op
= SLAP_CONFIG_ADD
;
2056 snprintf( c
.log
, sizeof( c
.log
), "%s: line %d", fname
, lineno
);
2058 rc
= SLAP_CONF_UNKNOWN
;
2059 ct
= config_find_keyword( be
->be_cf_ocs
->co_table
, &c
);
2061 c
.table
= be
->be_cf_ocs
->co_type
;
2062 rc
= config_add_vals( ct
, &c
);