config.c 52.8 KB
Newer Older
1
/* config.c - ldap backend configuration file routine */
2
/* $OpenLDAP$ */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
3
4
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 *
Kurt Zeilenga's avatar
Kurt Zeilenga committed
5
 * Copyright 2003-2007 The OpenLDAP Foundation.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
6
7
 * Portions Copyright 1999-2003 Howard Chu.
 * Portions Copyright 2000-2003 Pierangelo Masarati.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.
 *
 * A copy of this license is available in the file LICENSE in the
 * top-level directory of the distribution or, alternatively, at
 * <http://www.OpenLDAP.org/license.html>.
 */
/* ACKNOWLEDGEMENTS:
 * This work was initially developed by the Howard Chu for inclusion
 * in OpenLDAP Software and subsequently enhanced by Pierangelo
 * Masarati.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
22
 */
23
24
25
26
27
28

#include "portable.h"

#include <stdio.h>

#include <ac/string.h>
29
#include <ac/ctype.h>
30
31
32
#include <ac/socket.h>

#include "slap.h"
33
#include "config.h"
34
#include "back-ldap.h"
35
#include "lutil.h"
36
#include "ldif.h"
37
38
39
#undef ldap_debug
/* for advanced URL parsing */
#include "../../../libraries/libldap/ldap-int.h"
40

41
42
static SLAP_EXTOP_MAIN_FN ldap_back_exop_whoami;

43
44
45
46
47
48
49
50
static ConfigDriver ldap_back_cf_gen;

enum {
	LDAP_BACK_CFG_URI = 1,
	LDAP_BACK_CFG_TLS,
	LDAP_BACK_CFG_ACL_AUTHCDN,
	LDAP_BACK_CFG_ACL_PASSWD,
	LDAP_BACK_CFG_ACL_METHOD,
51
	LDAP_BACK_CFG_ACL_BIND,
52
53
54
55
56
	LDAP_BACK_CFG_IDASSERT_MODE,
	LDAP_BACK_CFG_IDASSERT_AUTHCDN,
	LDAP_BACK_CFG_IDASSERT_PASSWD,
	LDAP_BACK_CFG_IDASSERT_AUTHZFROM,
	LDAP_BACK_CFG_IDASSERT_METHOD,
57
	LDAP_BACK_CFG_IDASSERT_BIND,
58
59
60
61
	LDAP_BACK_CFG_REBIND,
	LDAP_BACK_CFG_CHASE,
	LDAP_BACK_CFG_T_F,
	LDAP_BACK_CFG_WHOAMI,
62
	LDAP_BACK_CFG_TIMEOUT,
63
	LDAP_BACK_CFG_IDLE_TIMEOUT,
64
	LDAP_BACK_CFG_CONN_TTL,
65
	LDAP_BACK_CFG_NETWORK_TIMEOUT,
66
	LDAP_BACK_CFG_VERSION,
67
	LDAP_BACK_CFG_SINGLECONN,
68
	LDAP_BACK_CFG_USETEMP,
69
	LDAP_BACK_CFG_CONNPOOLMAX,
70
	LDAP_BACK_CFG_CANCEL,
71
	LDAP_BACK_CFG_QUARANTINE,
72
73
74
	LDAP_BACK_CFG_REWRITE,

	LDAP_BACK_CFG_LAST
75
76
77
78
};

static ConfigTable ldapcfg[] = {
	{ "uri", "uri", 2, 2, 0,
Pierangelo Masarati's avatar
Pierangelo Masarati committed
79
		ARG_MAGIC|LDAP_BACK_CFG_URI,
80
81
		ldap_back_cf_gen, "( OLcfgDbAt:0.14 "
			"NAME 'olcDbURI' "
82
			"DESC 'URI (list) for remote DSA' "
83
84
			"SYNTAX OMsDirectoryString "
			"SINGLE-VALUE )",
85
		NULL, NULL },
Howard Chu's avatar
Howard Chu committed
86
	{ "tls", "what", 2, 0, 0,
Pierangelo Masarati's avatar
Pierangelo Masarati committed
87
		ARG_MAGIC|LDAP_BACK_CFG_TLS,
88
89
		ldap_back_cf_gen, "( OLcfgDbAt:3.1 "
			"NAME 'olcDbStartTLS' "
90
			"DESC 'StartTLS' "
91
92
			"SYNTAX OMsDirectoryString "
			"SINGLE-VALUE )",
93
94
95
		NULL, NULL },
	{ "acl-authcDN", "DN", 2, 2, 0,
		ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_ACL_AUTHCDN,
96
97
		ldap_back_cf_gen, "( OLcfgDbAt:3.2 "
			"NAME 'olcDbACLAuthcDn' "
98
			"DESC 'Remote ACL administrative identity' "
99
100
101
			"OBSOLETE "
			"SYNTAX OMsDN "
			"SINGLE-VALUE )",
102
		NULL, NULL },
103
	/* deprecated, will be removed; aliases "acl-authcDN" */
104
105
106
107
	{ "binddn", "DN", 2, 2, 0,
		ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_ACL_AUTHCDN,
		ldap_back_cf_gen, NULL, NULL, NULL },
	{ "acl-passwd", "cred", 2, 2, 0,
Pierangelo Masarati's avatar
Pierangelo Masarati committed
108
		ARG_MAGIC|LDAP_BACK_CFG_ACL_PASSWD,
109
110
		ldap_back_cf_gen, "( OLcfgDbAt:3.3 "
			"NAME 'olcDbACLPasswd' "
111
			"DESC 'Remote ACL administrative identity credentials' "
112
113
114
			"OBSOLETE "
			"SYNTAX OMsDirectoryString "
			"SINGLE-VALUE )",
115
		NULL, NULL },
116
	/* deprecated, will be removed; aliases "acl-passwd" */
117
	{ "bindpw", "cred", 2, 2, 0,
Pierangelo Masarati's avatar
Pierangelo Masarati committed
118
		ARG_MAGIC|LDAP_BACK_CFG_ACL_PASSWD,
119
		ldap_back_cf_gen, NULL, NULL, NULL },
120
121
	/* deprecated, will be removed; aliases "acl-bind" */
	{ "acl-method", "args", 2, 0, 0,
Pierangelo Masarati's avatar
Pierangelo Masarati committed
122
		ARG_MAGIC|LDAP_BACK_CFG_ACL_METHOD,
123
		ldap_back_cf_gen, NULL, NULL, NULL },
124
	{ "acl-bind", "args", 2, 0, 0,
Pierangelo Masarati's avatar
Pierangelo Masarati committed
125
		ARG_MAGIC|LDAP_BACK_CFG_ACL_BIND,
126
127
128
129
130
		ldap_back_cf_gen, "( OLcfgDbAt:3.4 "
			"NAME 'olcDbACLBind' "
			"DESC 'Remote ACL administrative identity auth bind configuration' "
			"SYNTAX OMsDirectoryString "
			"SINGLE-VALUE )",
131
132
133
		NULL, NULL },
	{ "idassert-authcDN", "DN", 2, 2, 0,
		ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_AUTHCDN,
134
135
		ldap_back_cf_gen, "( OLcfgDbAt:3.5 "
			"NAME 'olcDbIDAssertAuthcDn' "
136
			"DESC 'Remote Identity Assertion administrative identity' "
137
138
139
			"OBSOLETE "
			"SYNTAX OMsDN "
			"SINGLE-VALUE )",
140
		NULL, NULL },
141
	/* deprecated, will be removed; partially aliases "idassert-authcDN" */
142
143
144
145
	{ "proxyauthzdn", "DN", 2, 2, 0,
		ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_AUTHCDN,
		ldap_back_cf_gen, NULL, NULL, NULL },
	{ "idassert-passwd", "cred", 2, 2, 0,
Pierangelo Masarati's avatar
Pierangelo Masarati committed
146
		ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_PASSWD,
147
148
		ldap_back_cf_gen, "( OLcfgDbAt:3.6 "
			"NAME 'olcDbIDAssertPasswd' "
149
			"DESC 'Remote Identity Assertion administrative identity credentials' "
150
151
152
			"OBSOLETE "
			"SYNTAX OMsDirectoryString "
			"SINGLE-VALUE )",
153
		NULL, NULL },
154
	/* deprecated, will be removed; partially aliases "idassert-passwd" */
155
	{ "proxyauthzpw", "cred", 2, 2, 0,
Pierangelo Masarati's avatar
Pierangelo Masarati committed
156
		ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_PASSWD,
157
		ldap_back_cf_gen, NULL, NULL, NULL },
158
	{ "idassert-bind", "args", 2, 0, 0,
Pierangelo Masarati's avatar
Pierangelo Masarati committed
159
		ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_BIND,
160
161
162
163
164
		ldap_back_cf_gen, "( OLcfgDbAt:3.7 "
			"NAME 'olcDbIDAssertBind' "
			"DESC 'Remote Identity Assertion administrative identity auth bind configuration' "
			"SYNTAX OMsDirectoryString "
			"SINGLE-VALUE )",
165
		NULL, NULL },
166
	{ "idassert-method", "args", 2, 0, 0,
Pierangelo Masarati's avatar
Pierangelo Masarati committed
167
		ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_METHOD,
168
		ldap_back_cf_gen, NULL, NULL, NULL },
169
170
	{ "idassert-mode", "mode>|u:<user>|[dn:]<DN", 2, 0, 0,
		ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_MODE,
171
172
		ldap_back_cf_gen, "( OLcfgDbAt:3.8 "
			"NAME 'olcDbIDAssertMode' "
173
			"DESC 'Remote Identity Assertion mode' "
174
175
176
			"OBSOLETE "
			"SYNTAX OMsDirectoryString "
			"SINGLE-VALUE)",
177
178
		NULL, NULL },
	{ "idassert-authzFrom", "authzRule", 2, 2, 0,
Pierangelo Masarati's avatar
Pierangelo Masarati committed
179
		ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_AUTHZFROM,
180
181
		ldap_back_cf_gen, "( OLcfgDbAt:3.9 "
			"NAME 'olcDbIDAssertAuthzFrom' "
182
			"DESC 'Remote Identity Assertion authz rules' "
183
184
			"SYNTAX OMsDirectoryString "
			"X-ORDERED 'VALUES' )",
185
186
		NULL, NULL },
	{ "rebind-as-user", "NO|yes", 1, 2, 0,
187
		ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_REBIND,
188
189
		ldap_back_cf_gen, "( OLcfgDbAt:3.10 "
			"NAME 'olcDbRebindAsUser' "
190
			"DESC 'Rebind as user' "
191
			"SYNTAX OMsBoolean "
192
			"SINGLE-VALUE )",
193
194
		NULL, NULL },
	{ "chase-referrals", "YES|no", 2, 2, 0,
195
		ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_CHASE,
196
197
		ldap_back_cf_gen, "( OLcfgDbAt:3.11 "
			"NAME 'olcDbChaseReferrals' "
198
			"DESC 'Chase referrals' "
199
			"SYNTAX OMsBoolean "
200
			"SINGLE-VALUE )",
201
202
		NULL, NULL },
	{ "t-f-support", "NO|yes|discover", 2, 2, 0,
Pierangelo Masarati's avatar
Pierangelo Masarati committed
203
		ARG_MAGIC|LDAP_BACK_CFG_T_F,
204
205
		ldap_back_cf_gen, "( OLcfgDbAt:3.12 "
			"NAME 'olcDbTFSupport' "
206
			"DESC 'Absolute filters support' "
207
208
			"SYNTAX OMsDirectoryString "
			"SINGLE-VALUE )",
209
210
		NULL, NULL },
	{ "proxy-whoami", "NO|yes", 1, 2, 0,
211
		ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_WHOAMI,
212
213
		ldap_back_cf_gen, "( OLcfgDbAt:3.13 "
			"NAME 'olcDbProxyWhoAmI' "
214
			"DESC 'Proxy whoAmI exop' "
215
			"SYNTAX OMsBoolean "
216
			"SINGLE-VALUE )",
217
		NULL, NULL },
218
	{ "timeout", "timeout(list)", 2, 0, 0,
219
220
221
222
223
224
225
		ARG_MAGIC|LDAP_BACK_CFG_TIMEOUT,
		ldap_back_cf_gen, "( OLcfgDbAt:3.14 "
			"NAME 'olcDbTimeout' "
			"DESC 'Per-operation timeouts' "
			"SYNTAX OMsDirectoryString "
			"SINGLE-VALUE )",
		NULL, NULL },
226
227
228
229
230
231
232
233
	{ "idle-timeout", "timeout", 2, 0, 0,
		ARG_MAGIC|LDAP_BACK_CFG_IDLE_TIMEOUT,
		ldap_back_cf_gen, "( OLcfgDbAt:3.15 "
			"NAME 'olcDbIdleTimeout' "
			"DESC 'connection idle timeout' "
			"SYNTAX OMsDirectoryString "
			"SINGLE-VALUE )",
		NULL, NULL },
234
235
236
237
238
239
240
241
	{ "conn-ttl", "ttl", 2, 0, 0,
		ARG_MAGIC|LDAP_BACK_CFG_CONN_TTL,
		ldap_back_cf_gen, "( OLcfgDbAt:3.16 "
			"NAME 'olcDbConnTtl' "
			"DESC 'connection ttl' "
			"SYNTAX OMsDirectoryString "
			"SINGLE-VALUE )",
		NULL, NULL },
242
243
244
245
246
247
248
249
	{ "network-timeout", "timeout", 2, 0, 0,
		ARG_MAGIC|LDAP_BACK_CFG_NETWORK_TIMEOUT,
		ldap_back_cf_gen, "( OLcfgDbAt:3.17 "
			"NAME 'olcDbNetworkTimeout' "
			"DESC 'connection network timeout' "
			"SYNTAX OMsDirectoryString "
			"SINGLE-VALUE )",
		NULL, NULL },
250
251
252
253
254
255
256
257
	{ "protocol-version", "version", 2, 0, 0,
		ARG_MAGIC|ARG_INT|LDAP_BACK_CFG_VERSION,
		ldap_back_cf_gen, "( OLcfgDbAt:3.18 "
			"NAME 'olcDbProtocolVersion' "
			"DESC 'protocol version' "
			"SYNTAX OMsInteger "
			"SINGLE-VALUE )",
		NULL, NULL },
Pierangelo Masarati's avatar
Pierangelo Masarati committed
258
	{ "single-conn", "TRUE/FALSE", 2, 0, 0,
259
260
261
262
263
264
265
		ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_SINGLECONN,
		ldap_back_cf_gen, "( OLcfgDbAt:3.19 "
			"NAME 'olcDbSingleConn' "
			"DESC 'cache a single connection per identity' "
			"SYNTAX OMsBoolean "
			"SINGLE-VALUE )",
		NULL, NULL },
266
267
268
269
270
271
272
273
	{ "cancel", "ABANDON|ignore|exop", 2, 0, 0,
		ARG_MAGIC|LDAP_BACK_CFG_CANCEL,
		ldap_back_cf_gen, "( OLcfgDbAt:3.20 "
			"NAME 'olcDbCancel' "
			"DESC 'abandon/ignore/exop operations when appropriate' "
			"SYNTAX OMsDirectoryString "
			"SINGLE-VALUE )",
		NULL, NULL },
274
275
276
277
278
279
280
281
	{ "quarantine", "retrylist", 2, 0, 0,
		ARG_MAGIC|LDAP_BACK_CFG_QUARANTINE,
		ldap_back_cf_gen, "( OLcfgDbAt:3.21 "
			"NAME 'olcDbQuarantine' "
			"DESC 'Quarantine database if connection fails and retry according to rule' "
			"SYNTAX OMsDirectoryString "
			"SINGLE-VALUE )",
		NULL, NULL },
282
	{ "use-temporary-conn", "TRUE/FALSE", 2, 0, 0,
283
284
		ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_USETEMP,
		ldap_back_cf_gen, "( OLcfgDbAt:3.22 "
285
			"NAME 'olcDbUseTemporaryConn' "
286
287
288
289
			"DESC 'Use temporary connections if the cached one is busy' "
			"SYNTAX OMsBoolean "
			"SINGLE-VALUE )",
		NULL, NULL },
290
291
292
293
294
295
296
297
	{ "conn-pool-max", "<n>", 2, 0, 0,
		ARG_MAGIC|ARG_INT|LDAP_BACK_CFG_CONNPOOLMAX,
		ldap_back_cf_gen, "( OLcfgDbAt:3.23 "
			"NAME 'olcDbConnectionPoolMax' "
			"DESC 'Max size of privileged connections pool' "
			"SYNTAX OMsInteger "
			"SINGLE-VALUE )",
		NULL, NULL },
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
	{ "suffixmassage", "[virtual]> <real", 2, 3, 0,
		ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
		ldap_back_cf_gen, NULL, NULL, NULL },
	{ "map", "attribute|objectClass> [*|<local>] *|<remote", 3, 4, 0,
		ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
		ldap_back_cf_gen, NULL, NULL, NULL },
	{ "rewrite", "<arglist>", 2, 4, STRLENOF( "rewrite" ),
		ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
		ldap_back_cf_gen, NULL, NULL, NULL },
	{ NULL, NULL, 0, 0, 0, ARG_IGNORED,
		NULL, NULL, NULL, NULL }
};

static ConfigOCs ldapocs[] = {
	{ "( OLcfgDbOc:3.1 "
		"NAME 'olcLDAPConfig' "
		"DESC 'LDAP backend configuration' "
		"SUP olcDatabaseConfig "
316
317
		"MAY ( olcDbURI "
			"$ olcDbStartTLS "
318
319
320
			"$ olcDbACLAuthcDn "
			"$ olcDbACLPasswd "
			"$ olcDbACLBind "
321
322
			"$ olcDbIDAssertAuthcDn "
			"$ olcDbIDAssertPasswd "
323
			"$ olcDbIDAssertBind "
324
325
326
327
328
329
			"$ olcDbIDAssertMode "
			"$ olcDbIDAssertAuthzFrom "
			"$ olcDbRebindAsUser "
			"$ olcDbChaseReferrals "
			"$ olcDbTFSupport "
			"$ olcDbProxyWhoAmI "
330
			"$ olcDbTimeout "
331
			"$ olcDbIdleTimeout "
332
			"$ olcDbSingleConn "
333
			"$ olcDbCancel "
334
			"$ olcDbQuarantine "
Pierangelo Masarati's avatar
Pierangelo Masarati committed
335
			"$ olcDbUseTemporaryConn "
336
			"$ olcDbConnectionPoolMax "
337
338
339
340
341
342
343
344
345
		") )",
		 	Cft_Database, ldapcfg},
	{ NULL, 0, NULL }
};

static slap_verbmasks idassert_mode[] = {
	{ BER_BVC("self"),		LDAP_BACK_IDASSERT_SELF },
	{ BER_BVC("anonymous"),		LDAP_BACK_IDASSERT_ANONYMOUS },
	{ BER_BVC("none"),		LDAP_BACK_IDASSERT_NOASSERT },
346
	{ BER_BVC("legacy"),		LDAP_BACK_IDASSERT_LEGACY },
347
348
349
350
	{ BER_BVNULL,			0 }
};

static slap_verbmasks tls_mode[] = {
351
352
353
354
	{ BER_BVC( "propagate" ),	LDAP_BACK_F_TLS_PROPAGATE_MASK },
	{ BER_BVC( "try-propagate" ),	LDAP_BACK_F_PROPAGATE_TLS },
	{ BER_BVC( "start" ),		LDAP_BACK_F_TLS_USE_MASK },
	{ BER_BVC( "try-start" ),	LDAP_BACK_F_USE_TLS },
Howard Chu's avatar
Howard Chu committed
355
	{ BER_BVC( "ldaps" ),		LDAP_BACK_F_TLS_LDAPS },
356
	{ BER_BVC( "none" ),		LDAP_BACK_F_NONE },
357
358
359
360
	{ BER_BVNULL,			0 }
};

static slap_verbmasks t_f_mode[] = {
361
362
	{ BER_BVC( "yes" ),		LDAP_BACK_F_T_F },
	{ BER_BVC( "discover" ),	LDAP_BACK_F_T_F_DISCOVER },
363
	{ BER_BVC( "no" ),		LDAP_BACK_F_NONE },
364
365
366
	{ BER_BVNULL,			0 }
};

367
368
369
370
371
372
373
374
static slap_verbmasks cancel_mode[] = {
	{ BER_BVC( "ignore" ),		LDAP_BACK_F_CANCEL_IGNORE },
	{ BER_BVC( "exop" ),		LDAP_BACK_F_CANCEL_EXOP },
	{ BER_BVC( "exop-discover" ),	LDAP_BACK_F_CANCEL_EXOP_DISCOVER },
	{ BER_BVC( "abandon" ),		LDAP_BACK_F_CANCEL_ABANDON },
	{ BER_BVNULL,			0 }
};

375
/* see enum in slap.h */
376
static slap_cf_aux_table timeout_table[] = {
377
378
379
380
381
382
383
384
385
386
387
388
389
390
	{ BER_BVC("bind="),	SLAP_OP_BIND * sizeof( time_t ),	'u', 0, NULL },
	/* unbind makes no sense */
	{ BER_BVC("add="),	SLAP_OP_ADD * sizeof( time_t ),		'u', 0, NULL },
	{ BER_BVC("delete="),	SLAP_OP_DELETE * sizeof( time_t ),	'u', 0, NULL },
	{ BER_BVC("modrdn="),	SLAP_OP_MODRDN * sizeof( time_t ),	'u', 0, NULL },
	{ BER_BVC("modify="),	SLAP_OP_MODIFY * sizeof( time_t ),	'u', 0, NULL },
	{ BER_BVC("compare="),	SLAP_OP_COMPARE * sizeof( time_t ),	'u', 0, NULL },
#if 0	/* uses timelimit instead */
	{ BER_BVC("search="),	SLAP_OP_SEARCH * sizeof( time_t ),	'u', 0, NULL },
#endif
	/* abandon makes little sense */
#if 0	/* not implemented yet */
	{ BER_BVC("extended="),	SLAP_OP_EXTENDED * sizeof( time_t ),	'u', 0, NULL },
#endif
391
392
393
	{ BER_BVNULL, 0, 0, 0, NULL }
};

394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
int
slap_retry_info_parse(
	char			*in,
	slap_retry_info_t 	*ri,
	char			*buf,
	ber_len_t		buflen )
{
	char			**retrylist = NULL;
	int			rc = 0;
	int			i;

	slap_str2clist( &retrylist, in, " ;" );
	if ( retrylist == NULL ) {
		return 1;
	}

	for ( i = 0; retrylist[ i ] != NULL; i++ )
		/* count */ ;

	ri->ri_interval = ch_calloc( sizeof( time_t ), i + 1 );
	ri->ri_num = ch_calloc( sizeof( int ), i + 1 );

	for ( i = 0; retrylist[ i ] != NULL; i++ ) {
417
418
		unsigned long	t;
		char		*sep = strchr( retrylist[ i ], ',' );
419
420
421
422
423
424
425
426
427
428
429

		if ( sep == NULL ) {
			snprintf( buf, buflen,
				"missing comma in retry pattern #%d \"%s\"",
				i, retrylist[ i ] );
			rc = 1;
			goto done;
		}

		*sep++ = '\0';

430
		if ( lutil_parse_time( retrylist[ i ], &t ) ) {
431
432
433
434
435
436
			snprintf( buf, buflen,
				"unable to parse interval #%d \"%s\"",
				i, retrylist[ i ] );
			rc = 1;
			goto done;
		}
437
		ri->ri_interval[ i ] = (time_t)t;
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499

		if ( strcmp( sep, "+" ) == 0 ) {
			if ( retrylist[ i + 1 ] != NULL ) {
				snprintf( buf, buflen,
					"extra cruft after retry pattern "
					"#%d \"%s,+\" with \"forever\" mark",
					i, retrylist[ i ] );
				rc = 1;
				goto done;
			}
			ri->ri_num[ i ] = SLAP_RETRYNUM_FOREVER;
			
		} else if ( lutil_atoi( &ri->ri_num[ i ], sep ) ) {
			snprintf( buf, buflen,
				"unable to parse retry num #%d \"%s\"",
				i, sep );
			rc = 1;
			goto done;
		}
	}

	ri->ri_num[ i ] = SLAP_RETRYNUM_TAIL;

	ri->ri_idx = 0;
	ri->ri_count = 0;
	ri->ri_last = (time_t)(-1);

done:;
	ldap_charray_free( retrylist );

	if ( rc ) {
		slap_retry_info_destroy( ri );
	}

	return rc;
}

int
slap_retry_info_unparse(
	slap_retry_info_t	*ri,
	struct berval		*bvout )
{
	int		i;
	char		buf[ BUFSIZ * 2 ],
			*ptr = buf;
	struct berval	bv = BER_BVNULL;

	assert( ri != NULL );
	assert( bvout != NULL );

	BER_BVZERO( bvout );

#define WHATSLEFT	( sizeof( buf ) - ( ptr - buf ) )

	for ( i = 0; ri->ri_num[ i ] != SLAP_RETRYNUM_TAIL; i++ ) {
		if ( i > 0 ) {
			if ( WHATSLEFT <= 1 ) {
				return 1;
			}
			*ptr++ = ';';
		}

500
		if ( lutil_unparse_time( ptr, WHATSLEFT, (long)ri->ri_interval[i] ) ) {
501
502
			return 1;
		}
503
504
505
506
507
508
		ptr += strlen( ptr );

		if ( WHATSLEFT <= 1 ) {
			return 1;
		}
		*ptr++ = ',';
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546

		if ( ri->ri_num[i] == SLAP_RETRYNUM_FOREVER ) {
			if ( WHATSLEFT <= 1 ) {
				return 1;
			}
			*ptr++ = '+';

		} else {
			ptr += snprintf( ptr, WHATSLEFT, "%d", ri->ri_num[i] );
			if ( WHATSLEFT <= 0 ) {
				return 1;
			}
		}
	}

	bv.bv_val = buf;
	bv.bv_len = ptr - buf;

	ber_dupbv( bvout, &bv );

	return 0;
}

void
slap_retry_info_destroy(
	slap_retry_info_t	*ri )
{
	assert( ri != NULL );

	assert( ri->ri_interval != NULL );
	ch_free( ri->ri_interval );
	ri->ri_interval = NULL;

	assert( ri->ri_num != NULL );
	ch_free( ri->ri_num );
	ri->ri_num = NULL;
}

547
548
549
550
551
552
553
static int
slap_idassert_authzfrom_parse( ConfigArgs *c, slap_idassert_t *si )
{
	struct berval	bv;
	struct berval	in;
	int		rc;

554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
 	if ( strcmp( c->argv[ 1 ], "*" ) == 0
 		|| strcmp( c->argv[ 1 ], "dn:*" ) == 0
 		|| strcasecmp( c->argv[ 1 ], "dn.regex:.*" ) == 0 )
 	{
 		if ( si->si_authz != NULL ) {
 			snprintf( c->msg, sizeof( c->msg ),
 				"\"idassert-authzFrom <authz>\": "
 				"\"%s\" conflicts with existing authz rules",
 				c->argv[ 1 ] );
 			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 			return 1;
 		}
 
 		si->si_flags |= LDAP_BACK_AUTH_AUTHZ_ALL;
 
 		return 0;
 
 	} else if ( ( si->si_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) {
  		snprintf( c->msg, sizeof( c->msg ),
  			"\"idassert-authzFrom <authz>\": "
 			"\"<authz>\" conflicts with \"*\"" );
  		Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
  		return 1;
  	}
 	
 	ber_str2bv( c->argv[ 1 ], 0, 0, &in );
 	rc = authzNormalize( 0, NULL, NULL, &in, &bv, NULL );
 	if ( rc != LDAP_SUCCESS ) {
 		snprintf( c->msg, sizeof( c->msg ),
 			"\"idassert-authzFrom <authz>\": "
 			"invalid syntax" );
 		Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 		return 1;
 	}
  
589
	ber_bvarray_add( &si->si_authz, &bv );
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714

	return 0;
}

static int
slap_idassert_parse( ConfigArgs *c, slap_idassert_t *si )
{
	int		i;

	for ( i = 1; i < c->argc; i++ ) {
		if ( strncasecmp( c->argv[ i ], "mode=", STRLENOF( "mode=" ) ) == 0 ) {
			char	*argvi = c->argv[ i ] + STRLENOF( "mode=" );
			int	j;

			j = verb_to_mask( argvi, idassert_mode );
			if ( BER_BVISNULL( &idassert_mode[ j ].word ) ) {
				snprintf( c->msg, sizeof( c->msg ),
					"\"idassert-bind <args>\": "
					"unknown mode \"%s\"",
					argvi );
				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
				return 1;
			}

			si->si_mode = idassert_mode[ j ].mask;

		} else if ( strncasecmp( c->argv[ i ], "authz=", STRLENOF( "authz=" ) ) == 0 ) {
			char	*argvi = c->argv[ i ] + STRLENOF( "authz=" );

			if ( strcasecmp( argvi, "native" ) == 0 ) {
				if ( si->si_bc.sb_method != LDAP_AUTH_SASL ) {
					snprintf( c->msg, sizeof( c->msg ),
						"\"idassert-bind <args>\": "
						"authz=\"native\" incompatible "
						"with auth method" );
					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
					return 1;
				}
				si->si_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ;

			} else if ( strcasecmp( argvi, "proxyAuthz" ) == 0 ) {
				si->si_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;

			} else {
				snprintf( c->msg, sizeof( c->msg ),
					"\"idassert-bind <args>\": "
					"unknown authz \"%s\"",
					argvi );
				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
				return 1;
			}

		} else if ( strncasecmp( c->argv[ i ], "flags=", STRLENOF( "flags=" ) ) == 0 ) {
			char	*argvi = c->argv[ i ] + STRLENOF( "flags=" );
			char	**flags = ldap_str2charray( argvi, "," );
			int	j, err = 0;

			if ( flags == NULL ) {
				snprintf( c->msg, sizeof( c->msg ),
					"\"idassert-bind <args>\": "
					"unable to parse flags \"%s\"",
					argvi );
				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
				return 1;
			}

			for ( j = 0; flags[ j ] != NULL; j++ ) {

				if ( strcasecmp( flags[ j ], "override" ) == 0 ) {
					si->si_flags |= LDAP_BACK_AUTH_OVERRIDE;

				} else if ( strcasecmp( flags[ j ], "prescriptive" ) == 0 ) {
					si->si_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE;

				} else if ( strcasecmp( flags[ j ], "non-prescriptive" ) == 0 ) {
					si->si_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE );

				} else if ( strcasecmp( flags[ j ], "obsolete-proxy-authz" ) == 0 ) {
					if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) {
						Debug( LDAP_DEBUG_ANY,
                                      		 		"%s: \"obsolete-proxy-authz\" flag "
                                      		 		"in \"idassert-mode <args>\" "
                                      		 		"incompatible with previously issued \"obsolete-encoding-workaround\" flag.\n",
                                      	 			c->log, 0, 0 );
						err = 1;
						break;

					} else {
						si->si_flags |= LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ;
					}

				} else if ( strcasecmp( flags[ j ], "obsolete-encoding-workaround" ) == 0 ) {
					if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) {
						Debug( LDAP_DEBUG_ANY,
                                      	 			"%s: \"obsolete-encoding-workaround\" flag "
                                       			"in \"idassert-mode <args>\" "
                                       			"incompatible with previously issued \"obsolete-proxy-authz\" flag.\n",
                                       			c->log, 0, 0 );
						err = 1;
						break;

					} else {
						si->si_flags |= LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND;
					}

				} else {
					snprintf( c->msg, sizeof( c->msg ),
						"\"idassert-bind <args>\": "
						"unknown flag \"%s\"",
						flags[ j ] );
					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
					err = 1;
					break;
				}
			}

			ldap_charray_free( flags );
			if ( err ) {
				return 1;
			}

		} else if ( bindconf_parse( c->argv[ i ], &si->si_bc ) ) {
			return 1;
		}
	}
Howard Chu's avatar
Howard Chu committed
715
	bindconf_tls_defaults( &si->si_bc );
716
717
718
719
720
721
722
723
724

	return 0;
}

/* NOTE: temporary, until back-meta is ported to back-config */
int
slap_idassert_authzfrom_parse_cf( const char *fname, int lineno, const char *arg, slap_idassert_t *si )
{
	ConfigArgs	c = { 0 };
725
	char		*argv[ 3 ];
726
727
728
729

	snprintf( c.log, sizeof( c.log ), "%s: line %d", fname, lineno );
	c.argc = 2;
	c.argv = argv;
730
731
732
	argv[ 0 ] = "idassert-authzFrom";
	argv[ 1 ] = (char *)arg;
	argv[ 2 ] = NULL;
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748

	return slap_idassert_authzfrom_parse( &c, si );
}

int
slap_idassert_parse_cf( const char *fname, int lineno, int argc, char *argv[], slap_idassert_t *si )
{
	ConfigArgs	c = { 0 };

	snprintf( c.log, sizeof( c.log ), "%s: line %d", fname, lineno );
	c.argc = argc;
	c.argv = argv;

	return slap_idassert_parse( &c, si );
}

749
750
751
static int
ldap_back_cf_gen( ConfigArgs *c )
{
752
	ldapinfo_t	*li = ( ldapinfo_t * )c->be->be_private;
753
	int		rc = 0;
754
755
756
	int		i;

	if ( c->op == SLAP_CONFIG_EMIT ) {
757
758
		struct berval	bv = BER_BVNULL;

759
760
761
762
		if ( li == NULL ) {
			return 1;
		}

763
764
		switch( c->type ) {
		case LDAP_BACK_CFG_URI:
765
			if ( li->li_uri != NULL ) {
766
				struct berval	bv, bv2;
Pierangelo Masarati's avatar
Pierangelo Masarati committed
767
768

				ber_str2bv( li->li_uri, 0, 0, &bv );
769
770
771
772
773
				bv2.bv_len = bv.bv_len + STRLENOF( "\"\"" );
				bv2.bv_val = ch_malloc( bv2.bv_len + 1 );
				snprintf( bv2.bv_val, bv2.bv_len + 1,
					"\"%s\"", bv.bv_val );
				ber_bvarray_add( &c->rvalue_vals, &bv2 );
774
775
776
777
778
779

			} else {
				rc = 1;
			}
			break;

Howard Chu's avatar
Howard Chu committed
780
781
		case LDAP_BACK_CFG_TLS: {
			struct berval bc = BER_BVNULL, bv2;
782
			enum_to_verb( tls_mode, ( li->li_flags & LDAP_BACK_F_TLS_MASK ), &bv );
783
			assert( !BER_BVISNULL( &bv ) );
Howard Chu's avatar
Howard Chu committed
784
785
786
787
			bindconf_tls_unparse( &li->li_tls, &bc );

			if ( !BER_BVISEMPTY( &bc )) {
				bv2.bv_len = bv.bv_len + bc.bv_len + 1;
Pierangelo Masarati's avatar
Pierangelo Masarati committed
788
				bv2.bv_val = ch_malloc( bv2.bv_len + 1 );
Howard Chu's avatar
Howard Chu committed
789
790
				strcpy( bv2.bv_val, bv.bv_val );
				bv2.bv_val[bv.bv_len] = ' ';
Pierangelo Masarati's avatar
Pierangelo Masarati committed
791
				strcpy( &bv2.bv_val[bv.bv_len + 1], bc.bv_val );
Howard Chu's avatar
Howard Chu committed
792
				ber_bvarray_add( &c->rvalue_vals, &bv2 );
Pierangelo Masarati's avatar
Pierangelo Masarati committed
793

Howard Chu's avatar
Howard Chu committed
794
795
796
			} else {
				value_add_one( &c->rvalue_vals, &bv );
			}
Pierangelo Masarati's avatar
Pierangelo Masarati committed
797
			ber_memfree( bc.bv_val );
Howard Chu's avatar
Howard Chu committed
798
			}
799
800
801
802
			break;

		case LDAP_BACK_CFG_ACL_AUTHCDN:
		case LDAP_BACK_CFG_ACL_PASSWD:
803
804
		case LDAP_BACK_CFG_ACL_METHOD:
			/* handled by LDAP_BACK_CFG_ACL_BIND */
805
806
807
			rc = 1;
			break;

808
		case LDAP_BACK_CFG_ACL_BIND: {
809
810
			int	i;

811
812
813
814
			if ( li->li_acl_authmethod == LDAP_AUTH_NONE ) {
				return 1;
			}

815
			bindconf_unparse( &li->li_acl, &bv );
816

817
			for ( i = 0; isspace( (unsigned char) bv.bv_val[ i ] ); i++ )
818
819
820
				/* count spaces */ ;

			if ( i ) {
821
822
823
				bv.bv_len -= i;
				AC_MEMCPY( bv.bv_val, &bv.bv_val[ i ],
					bv.bv_len + 1 );
824
			}
825

826
			ber_bvarray_add( &c->rvalue_vals, &bv );
827
828
829
830
831
832
			break;
		}

		case LDAP_BACK_CFG_IDASSERT_MODE:
		case LDAP_BACK_CFG_IDASSERT_AUTHCDN:
		case LDAP_BACK_CFG_IDASSERT_PASSWD:
833
834
		case LDAP_BACK_CFG_IDASSERT_METHOD:
			/* handled by LDAP_BACK_CFG_IDASSERT_BIND */
835
836
837
838
839
840
			rc = 1;
			break;

		case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: {
			int		i;

841
			if ( li->li_idassert_authz == NULL ) {
842
843
844
845
846
847
848
				if ( ( li->li_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) {
					BER_BVSTR( &bv, "*" );
					value_add_one( &c->rvalue_vals, &bv );

				} else {
					rc = 1;
				}
849
850
851
				break;
			}

852
			for ( i = 0; !BER_BVISNULL( &li->li_idassert_authz[ i ] ); i++ )
853
			{
854
				value_add_one( &c->rvalue_vals, &li->li_idassert_authz[ i ] );
855
856
857
858
			}
			break;
		}

859
860
		case LDAP_BACK_CFG_IDASSERT_BIND: {
			int		i;
861
			struct berval	bc = BER_BVNULL;
862
			char		*ptr;
863

864
865
866
867
			if ( li->li_idassert_authmethod == LDAP_AUTH_NONE ) {
				return 1;
			}

868
			if ( li->li_idassert_authmethod != LDAP_AUTH_NONE ) {
Pierangelo Masarati's avatar
Pierangelo Masarati committed
869
				ber_len_t	len;
870

871
				switch ( li->li_idassert_mode ) {
872
873
874
875
876
				case LDAP_BACK_IDASSERT_OTHERID:
				case LDAP_BACK_IDASSERT_OTHERDN:
					break;

				default: {
877
878
					struct berval	mode = BER_BVNULL;

879
					enum_to_verb( idassert_mode, li->li_idassert_mode, &mode );
880
					if ( BER_BVISNULL( &mode ) ) {
881
882
883
884
885
						/* there's something wrong... */
						assert( 0 );
						rc = 1;
	
					} else {
886
887
888
889
890
						bv.bv_len = STRLENOF( "mode=" ) + mode.bv_len;
						bv.bv_val = ch_malloc( bv.bv_len + 1 );

						ptr = lutil_strcopy( bv.bv_val, "mode=" );
						ptr = lutil_strcopy( ptr, mode.bv_val );
891
892
893
894
					}
					break;
				}
				}
895

896
				if ( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) {
Pierangelo Masarati's avatar
Pierangelo Masarati committed
897
					len = bv.bv_len + STRLENOF( "authz=native" );
898
899
900
901
902
903
904

					if ( !BER_BVISEMPTY( &bv ) ) {
						len += STRLENOF( " " );
					}

					bv.bv_val = ch_realloc( bv.bv_val, len + 1 );

Pierangelo Masarati's avatar
Pierangelo Masarati committed
905
					ptr = &bv.bv_val[ bv.bv_len ];
906
907
908
909
910
911
912
913

					if ( !BER_BVISEMPTY( &bv ) ) {
						ptr = lutil_strcopy( ptr, " " );
					}

					(void)lutil_strcopy( ptr, "authz=native" );
				}

914
				len = bv.bv_len + STRLENOF( "flags=non-prescriptive,override,obsolete-encoding-workaround" );
915
916
917
918
				/* flags */
				if ( !BER_BVISEMPTY( &bv ) ) {
					len += STRLENOF( " " );
				}
919

920
				bv.bv_val = ch_realloc( bv.bv_val, len + 1 );
921

922
				ptr = &bv.bv_val[ bv.bv_len ];
923

924
925
926
				if ( !BER_BVISEMPTY( &bv ) ) {
					ptr = lutil_strcopy( ptr, " " );
				}
927

928
				ptr = lutil_strcopy( ptr, "flags=" );
929

930
				if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
931
932
933
					ptr = lutil_strcopy( ptr, "prescriptive" );
				} else {
					ptr = lutil_strcopy( ptr, "non-prescriptive" );
934
				}
935

936
				if ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) {
937
938
					ptr = lutil_strcopy( ptr, ",override" );
				}
939

940
941
942
943
944
945
946
				if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) {
					ptr = lutil_strcopy( ptr, ",obsolete-proxy-authz" );

				} else if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) {
					ptr = lutil_strcopy( ptr, ",obsolete-encoding-workaround" );
				}

947
948
949
				bv.bv_len = ( ptr - bv.bv_val );
				/* end-of-flags */
			}
950

951
			bindconf_unparse( &li->li_idassert.si_bc, &bc );
952
953

			if ( !BER_BVISNULL( &bv ) ) {
954
955
				ber_len_t	len = bv.bv_len + bc.bv_len;

956
				bv.bv_val = ch_realloc( bv.bv_val, len + 1 );
957

958
				assert( bc.bv_val[ 0 ] == ' ' );
959

960
				ptr = lutil_strcopy( &bv.bv_val[ bv.bv_len ], bc.bv_val );
961
				free( bc.bv_val );
962
				bv.bv_len = ptr - bv.bv_val;
963
964

			} else {
965
				for ( i = 0; isspace( (unsigned char) bc.bv_val[ i ] ); i++ )
966
967
968
					/* count spaces */ ;

				if ( i ) {
969
970
					bc.bv_len -= i;
					AC_MEMCPY( bc.bv_val, &bc.bv_val[ i ], bc.bv_len + 1 );
971
972
				}

973
				bv = bc;
974
975
			}
			
976
977
			ber_bvarray_add( &c->rvalue_vals, &bv );

978
979
980
			break;
		}

981
		case LDAP_BACK_CFG_REBIND:
982
			c->value_int = LDAP_BACK_SAVECRED( li );
983
984
			break;

985
		case LDAP_BACK_CFG_CHASE:
986
			c->value_int = LDAP_BACK_CHASE_REFERRALS( li );
987
988
			break;

989
		case LDAP_BACK_CFG_T_F:
990
			enum_to_verb( t_f_mode, (li->li_flags & LDAP_BACK_F_T_F_MASK2), &bv );
991
			if ( BER_BVISNULL( &bv ) ) {
992
993
994
995
996
				/* there's something wrong... */
				assert( 0 );
				rc = 1;

			} else {
Pierangelo Masarati's avatar
Pierangelo Masarati committed
997
				value_add_one( &c->rvalue_vals, &bv );
998
999
1000
			}
			break;

For faster browsing, not all history is shown. View entire blame