~ttx/openldap/lucid-gssapi-495418

« back to all changes in this revision

Viewing changes to servers/slapd/back-ldap/config.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug
  • Date: 2008-07-10 14:45:49 UTC
  • Revision ID: james.westby@ubuntu.com-20080710144549-wck73med0e72gfyo
Tags: upstream-2.4.10
ImportĀ upstreamĀ versionĀ 2.4.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* config.c - ldap backend configuration file routine */
 
2
/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/config.c,v 1.115.2.8 2008/02/11 23:26:46 kurt Exp $ */
 
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 
4
 *
 
5
 * Copyright 2003-2008 The OpenLDAP Foundation.
 
6
 * Portions Copyright 1999-2003 Howard Chu.
 
7
 * Portions Copyright 2000-2003 Pierangelo Masarati.
 
8
 * All rights reserved.
 
9
 *
 
10
 * Redistribution and use in source and binary forms, with or without
 
11
 * modification, are permitted only as authorized by the OpenLDAP
 
12
 * Public License.
 
13
 *
 
14
 * A copy of this license is available in the file LICENSE in the
 
15
 * top-level directory of the distribution or, alternatively, at
 
16
 * <http://www.OpenLDAP.org/license.html>.
 
17
 */
 
18
/* ACKNOWLEDGEMENTS:
 
19
 * This work was initially developed by the Howard Chu for inclusion
 
20
 * in OpenLDAP Software and subsequently enhanced by Pierangelo
 
21
 * Masarati.
 
22
 */
 
23
 
 
24
#include "portable.h"
 
25
 
 
26
#include <stdio.h>
 
27
 
 
28
#include <ac/string.h>
 
29
#include <ac/ctype.h>
 
30
#include <ac/socket.h>
 
31
 
 
32
#include "slap.h"
 
33
#include "config.h"
 
34
#include "back-ldap.h"
 
35
#include "lutil.h"
 
36
#include "ldif.h"
 
37
#undef ldap_debug
 
38
/* for advanced URL parsing */
 
39
#include "../../../libraries/libldap/ldap-int.h"
 
40
 
 
41
static SLAP_EXTOP_MAIN_FN ldap_back_exop_whoami;
 
42
 
 
43
static ConfigDriver ldap_back_cf_gen;
 
44
 
 
45
enum {
 
46
        LDAP_BACK_CFG_URI = 1,
 
47
        LDAP_BACK_CFG_TLS,
 
48
        LDAP_BACK_CFG_ACL_AUTHCDN,
 
49
        LDAP_BACK_CFG_ACL_PASSWD,
 
50
        LDAP_BACK_CFG_ACL_METHOD,
 
51
        LDAP_BACK_CFG_ACL_BIND,
 
52
        LDAP_BACK_CFG_IDASSERT_MODE,
 
53
        LDAP_BACK_CFG_IDASSERT_AUTHCDN,
 
54
        LDAP_BACK_CFG_IDASSERT_PASSWD,
 
55
        LDAP_BACK_CFG_IDASSERT_AUTHZFROM,
 
56
        LDAP_BACK_CFG_IDASSERT_METHOD,
 
57
        LDAP_BACK_CFG_IDASSERT_BIND,
 
58
        LDAP_BACK_CFG_REBIND,
 
59
        LDAP_BACK_CFG_CHASE,
 
60
        LDAP_BACK_CFG_T_F,
 
61
        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
        LDAP_BACK_CFG_ST_REQUEST,
 
73
        LDAP_BACK_CFG_REWRITE,
 
74
 
 
75
        LDAP_BACK_CFG_LAST
 
76
};
 
77
 
 
78
static ConfigTable ldapcfg[] = {
 
79
        { "uri", "uri", 2, 2, 0,
 
80
                ARG_MAGIC|LDAP_BACK_CFG_URI,
 
81
                ldap_back_cf_gen, "( OLcfgDbAt:0.14 "
 
82
                        "NAME 'olcDbURI' "
 
83
                        "DESC 'URI (list) for remote DSA' "
 
84
                        "SYNTAX OMsDirectoryString "
 
85
                        "SINGLE-VALUE )",
 
86
                NULL, NULL },
 
87
        { "tls", "what", 2, 0, 0,
 
88
                ARG_MAGIC|LDAP_BACK_CFG_TLS,
 
89
                ldap_back_cf_gen, "( OLcfgDbAt:3.1 "
 
90
                        "NAME 'olcDbStartTLS' "
 
91
                        "DESC 'StartTLS' "
 
92
                        "SYNTAX OMsDirectoryString "
 
93
                        "SINGLE-VALUE )",
 
94
                NULL, NULL },
 
95
        { "acl-authcDN", "DN", 2, 2, 0,
 
96
                ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_ACL_AUTHCDN,
 
97
                ldap_back_cf_gen, "( OLcfgDbAt:3.2 "
 
98
                        "NAME 'olcDbACLAuthcDn' "
 
99
                        "DESC 'Remote ACL administrative identity' "
 
100
                        "OBSOLETE "
 
101
                        "SYNTAX OMsDN "
 
102
                        "SINGLE-VALUE )",
 
103
                NULL, NULL },
 
104
        /* deprecated, will be removed; aliases "acl-authcDN" */
 
105
        { "binddn", "DN", 2, 2, 0,
 
106
                ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_ACL_AUTHCDN,
 
107
                ldap_back_cf_gen, NULL, NULL, NULL },
 
108
        { "acl-passwd", "cred", 2, 2, 0,
 
109
                ARG_MAGIC|LDAP_BACK_CFG_ACL_PASSWD,
 
110
                ldap_back_cf_gen, "( OLcfgDbAt:3.3 "
 
111
                        "NAME 'olcDbACLPasswd' "
 
112
                        "DESC 'Remote ACL administrative identity credentials' "
 
113
                        "OBSOLETE "
 
114
                        "SYNTAX OMsDirectoryString "
 
115
                        "SINGLE-VALUE )",
 
116
                NULL, NULL },
 
117
        /* deprecated, will be removed; aliases "acl-passwd" */
 
118
        { "bindpw", "cred", 2, 2, 0,
 
119
                ARG_MAGIC|LDAP_BACK_CFG_ACL_PASSWD,
 
120
                ldap_back_cf_gen, NULL, NULL, NULL },
 
121
        /* deprecated, will be removed; aliases "acl-bind" */
 
122
        { "acl-method", "args", 2, 0, 0,
 
123
                ARG_MAGIC|LDAP_BACK_CFG_ACL_METHOD,
 
124
                ldap_back_cf_gen, NULL, NULL, NULL },
 
125
        { "acl-bind", "args", 2, 0, 0,
 
126
                ARG_MAGIC|LDAP_BACK_CFG_ACL_BIND,
 
127
                ldap_back_cf_gen, "( OLcfgDbAt:3.4 "
 
128
                        "NAME 'olcDbACLBind' "
 
129
                        "DESC 'Remote ACL administrative identity auth bind configuration' "
 
130
                        "SYNTAX OMsDirectoryString "
 
131
                        "SINGLE-VALUE )",
 
132
                NULL, NULL },
 
133
        { "idassert-authcDN", "DN", 2, 2, 0,
 
134
                ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_AUTHCDN,
 
135
                ldap_back_cf_gen, "( OLcfgDbAt:3.5 "
 
136
                        "NAME 'olcDbIDAssertAuthcDn' "
 
137
                        "DESC 'Remote Identity Assertion administrative identity' "
 
138
                        "OBSOLETE "
 
139
                        "SYNTAX OMsDN "
 
140
                        "SINGLE-VALUE )",
 
141
                NULL, NULL },
 
142
        /* deprecated, will be removed; partially aliases "idassert-authcDN" */
 
143
        { "proxyauthzdn", "DN", 2, 2, 0,
 
144
                ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_AUTHCDN,
 
145
                ldap_back_cf_gen, NULL, NULL, NULL },
 
146
        { "idassert-passwd", "cred", 2, 2, 0,
 
147
                ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_PASSWD,
 
148
                ldap_back_cf_gen, "( OLcfgDbAt:3.6 "
 
149
                        "NAME 'olcDbIDAssertPasswd' "
 
150
                        "DESC 'Remote Identity Assertion administrative identity credentials' "
 
151
                        "OBSOLETE "
 
152
                        "SYNTAX OMsDirectoryString "
 
153
                        "SINGLE-VALUE )",
 
154
                NULL, NULL },
 
155
        /* deprecated, will be removed; partially aliases "idassert-passwd" */
 
156
        { "proxyauthzpw", "cred", 2, 2, 0,
 
157
                ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_PASSWD,
 
158
                ldap_back_cf_gen, NULL, NULL, NULL },
 
159
        { "idassert-bind", "args", 2, 0, 0,
 
160
                ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_BIND,
 
161
                ldap_back_cf_gen, "( OLcfgDbAt:3.7 "
 
162
                        "NAME 'olcDbIDAssertBind' "
 
163
                        "DESC 'Remote Identity Assertion administrative identity auth bind configuration' "
 
164
                        "SYNTAX OMsDirectoryString "
 
165
                        "SINGLE-VALUE )",
 
166
                NULL, NULL },
 
167
        { "idassert-method", "args", 2, 0, 0,
 
168
                ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_METHOD,
 
169
                ldap_back_cf_gen, NULL, NULL, NULL },
 
170
        { "idassert-mode", "mode>|u:<user>|[dn:]<DN", 2, 0, 0,
 
171
                ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_MODE,
 
172
                ldap_back_cf_gen, "( OLcfgDbAt:3.8 "
 
173
                        "NAME 'olcDbIDAssertMode' "
 
174
                        "DESC 'Remote Identity Assertion mode' "
 
175
                        "OBSOLETE "
 
176
                        "SYNTAX OMsDirectoryString "
 
177
                        "SINGLE-VALUE)",
 
178
                NULL, NULL },
 
179
        { "idassert-authzFrom", "authzRule", 2, 2, 0,
 
180
                ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_AUTHZFROM,
 
181
                ldap_back_cf_gen, "( OLcfgDbAt:3.9 "
 
182
                        "NAME 'olcDbIDAssertAuthzFrom' "
 
183
                        "DESC 'Remote Identity Assertion authz rules' "
 
184
                        "SYNTAX OMsDirectoryString "
 
185
                        "X-ORDERED 'VALUES' )",
 
186
                NULL, NULL },
 
187
        { "rebind-as-user", "true|FALSE", 1, 2, 0,
 
188
                ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_REBIND,
 
189
                ldap_back_cf_gen, "( OLcfgDbAt:3.10 "
 
190
                        "NAME 'olcDbRebindAsUser' "
 
191
                        "DESC 'Rebind as user' "
 
192
                        "SYNTAX OMsBoolean "
 
193
                        "SINGLE-VALUE )",
 
194
                NULL, NULL },
 
195
        { "chase-referrals", "true|FALSE", 2, 2, 0,
 
196
                ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_CHASE,
 
197
                ldap_back_cf_gen, "( OLcfgDbAt:3.11 "
 
198
                        "NAME 'olcDbChaseReferrals' "
 
199
                        "DESC 'Chase referrals' "
 
200
                        "SYNTAX OMsBoolean "
 
201
                        "SINGLE-VALUE )",
 
202
                NULL, NULL },
 
203
        { "t-f-support", "true|FALSE|discover", 2, 2, 0,
 
204
                ARG_MAGIC|LDAP_BACK_CFG_T_F,
 
205
                ldap_back_cf_gen, "( OLcfgDbAt:3.12 "
 
206
                        "NAME 'olcDbTFSupport' "
 
207
                        "DESC 'Absolute filters support' "
 
208
                        "SYNTAX OMsDirectoryString "
 
209
                        "SINGLE-VALUE )",
 
210
                NULL, NULL },
 
211
        { "proxy-whoami", "true|FALSE", 1, 2, 0,
 
212
                ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_WHOAMI,
 
213
                ldap_back_cf_gen, "( OLcfgDbAt:3.13 "
 
214
                        "NAME 'olcDbProxyWhoAmI' "
 
215
                        "DESC 'Proxy whoAmI exop' "
 
216
                        "SYNTAX OMsBoolean "
 
217
                        "SINGLE-VALUE )",
 
218
                NULL, NULL },
 
219
        { "timeout", "timeout(list)", 2, 0, 0,
 
220
                ARG_MAGIC|LDAP_BACK_CFG_TIMEOUT,
 
221
                ldap_back_cf_gen, "( OLcfgDbAt:3.14 "
 
222
                        "NAME 'olcDbTimeout' "
 
223
                        "DESC 'Per-operation timeouts' "
 
224
                        "SYNTAX OMsDirectoryString "
 
225
                        "SINGLE-VALUE )",
 
226
                NULL, NULL },
 
227
        { "idle-timeout", "timeout", 2, 2, 0,
 
228
                ARG_MAGIC|LDAP_BACK_CFG_IDLE_TIMEOUT,
 
229
                ldap_back_cf_gen, "( OLcfgDbAt:3.15 "
 
230
                        "NAME 'olcDbIdleTimeout' "
 
231
                        "DESC 'connection idle timeout' "
 
232
                        "SYNTAX OMsDirectoryString "
 
233
                        "SINGLE-VALUE )",
 
234
                NULL, NULL },
 
235
        { "conn-ttl", "ttl", 2, 2, 0,
 
236
                ARG_MAGIC|LDAP_BACK_CFG_CONN_TTL,
 
237
                ldap_back_cf_gen, "( OLcfgDbAt:3.16 "
 
238
                        "NAME 'olcDbConnTtl' "
 
239
                        "DESC 'connection ttl' "
 
240
                        "SYNTAX OMsDirectoryString "
 
241
                        "SINGLE-VALUE )",
 
242
                NULL, NULL },
 
243
        { "network-timeout", "timeout", 2, 2, 0,
 
244
                ARG_MAGIC|LDAP_BACK_CFG_NETWORK_TIMEOUT,
 
245
                ldap_back_cf_gen, "( OLcfgDbAt:3.17 "
 
246
                        "NAME 'olcDbNetworkTimeout' "
 
247
                        "DESC 'connection network timeout' "
 
248
                        "SYNTAX OMsDirectoryString "
 
249
                        "SINGLE-VALUE )",
 
250
                NULL, NULL },
 
251
        { "protocol-version", "version", 2, 2, 0,
 
252
                ARG_MAGIC|ARG_INT|LDAP_BACK_CFG_VERSION,
 
253
                ldap_back_cf_gen, "( OLcfgDbAt:3.18 "
 
254
                        "NAME 'olcDbProtocolVersion' "
 
255
                        "DESC 'protocol version' "
 
256
                        "SYNTAX OMsInteger "
 
257
                        "SINGLE-VALUE )",
 
258
                NULL, NULL },
 
259
        { "single-conn", "true|FALSE", 2, 2, 0,
 
260
                ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_SINGLECONN,
 
261
                ldap_back_cf_gen, "( OLcfgDbAt:3.19 "
 
262
                        "NAME 'olcDbSingleConn' "
 
263
                        "DESC 'cache a single connection per identity' "
 
264
                        "SYNTAX OMsBoolean "
 
265
                        "SINGLE-VALUE )",
 
266
                NULL, NULL },
 
267
        { "cancel", "ABANDON|ignore|exop", 2, 2, 0,
 
268
                ARG_MAGIC|LDAP_BACK_CFG_CANCEL,
 
269
                ldap_back_cf_gen, "( OLcfgDbAt:3.20 "
 
270
                        "NAME 'olcDbCancel' "
 
271
                        "DESC 'abandon/ignore/exop operations when appropriate' "
 
272
                        "SYNTAX OMsDirectoryString "
 
273
                        "SINGLE-VALUE )",
 
274
                NULL, NULL },
 
275
        { "quarantine", "retrylist", 2, 2, 0,
 
276
                ARG_MAGIC|LDAP_BACK_CFG_QUARANTINE,
 
277
                ldap_back_cf_gen, "( OLcfgDbAt:3.21 "
 
278
                        "NAME 'olcDbQuarantine' "
 
279
                        "DESC 'Quarantine database if connection fails and retry according to rule' "
 
280
                        "SYNTAX OMsDirectoryString "
 
281
                        "SINGLE-VALUE )",
 
282
                NULL, NULL },
 
283
        { "use-temporary-conn", "true|FALSE", 2, 2, 0,
 
284
                ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_USETEMP,
 
285
                ldap_back_cf_gen, "( OLcfgDbAt:3.22 "
 
286
                        "NAME 'olcDbUseTemporaryConn' "
 
287
                        "DESC 'Use temporary connections if the cached one is busy' "
 
288
                        "SYNTAX OMsBoolean "
 
289
                        "SINGLE-VALUE )",
 
290
                NULL, NULL },
 
291
        { "conn-pool-max", "<n>", 2, 2, 0,
 
292
                ARG_MAGIC|ARG_INT|LDAP_BACK_CFG_CONNPOOLMAX,
 
293
                ldap_back_cf_gen, "( OLcfgDbAt:3.23 "
 
294
                        "NAME 'olcDbConnectionPoolMax' "
 
295
                        "DESC 'Max size of privileged connections pool' "
 
296
                        "SYNTAX OMsInteger "
 
297
                        "SINGLE-VALUE )",
 
298
                NULL, NULL },
 
299
#ifdef SLAP_CONTROL_X_SESSION_TRACKING
 
300
        { "session-tracking-request", "true|FALSE", 2, 2, 0,
 
301
                ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_ST_REQUEST,
 
302
                ldap_back_cf_gen, "( OLcfgDbAt:3.24 "
 
303
                        "NAME 'olcDbSessionTrackingRequest' "
 
304
                        "DESC 'Add session tracking control to proxied requests' "
 
305
                        "SYNTAX OMsBoolean "
 
306
                        "SINGLE-VALUE )",
 
307
                NULL, NULL },
 
308
#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
 
309
        { "suffixmassage", "[virtual]> <real", 2, 3, 0,
 
310
                ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
 
311
                ldap_back_cf_gen, NULL, NULL, NULL },
 
312
        { "map", "attribute|objectClass> [*|<local>] *|<remote", 3, 4, 0,
 
313
                ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
 
314
                ldap_back_cf_gen, NULL, NULL, NULL },
 
315
        { "rewrite", "<arglist>", 2, 4, STRLENOF( "rewrite" ),
 
316
                ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
 
317
                ldap_back_cf_gen, NULL, NULL, NULL },
 
318
        { NULL, NULL, 0, 0, 0, ARG_IGNORED,
 
319
                NULL, NULL, NULL, NULL }
 
320
};
 
321
 
 
322
static ConfigOCs ldapocs[] = {
 
323
        { "( OLcfgDbOc:3.1 "
 
324
                "NAME 'olcLDAPConfig' "
 
325
                "DESC 'LDAP backend configuration' "
 
326
                "SUP olcDatabaseConfig "
 
327
                "MAY ( olcDbURI "
 
328
                        "$ olcDbStartTLS "
 
329
                        "$ olcDbACLAuthcDn "
 
330
                        "$ olcDbACLPasswd "
 
331
                        "$ olcDbACLBind "
 
332
                        "$ olcDbIDAssertAuthcDn "
 
333
                        "$ olcDbIDAssertPasswd "
 
334
                        "$ olcDbIDAssertBind "
 
335
                        "$ olcDbIDAssertMode "
 
336
                        "$ olcDbIDAssertAuthzFrom "
 
337
                        "$ olcDbRebindAsUser "
 
338
                        "$ olcDbChaseReferrals "
 
339
                        "$ olcDbTFSupport "
 
340
                        "$ olcDbProxyWhoAmI "
 
341
                        "$ olcDbTimeout "
 
342
                        "$ olcDbIdleTimeout "
 
343
                        "$ olcDbSingleConn "
 
344
                        "$ olcDbCancel "
 
345
                        "$ olcDbQuarantine "
 
346
                        "$ olcDbUseTemporaryConn "
 
347
                        "$ olcDbConnectionPoolMax "
 
348
                ") )",
 
349
                        Cft_Database, ldapcfg},
 
350
        { NULL, 0, NULL }
 
351
};
 
352
 
 
353
static slap_verbmasks idassert_mode[] = {
 
354
        { BER_BVC("self"),              LDAP_BACK_IDASSERT_SELF },
 
355
        { BER_BVC("anonymous"),         LDAP_BACK_IDASSERT_ANONYMOUS },
 
356
        { BER_BVC("none"),              LDAP_BACK_IDASSERT_NOASSERT },
 
357
        { BER_BVC("legacy"),            LDAP_BACK_IDASSERT_LEGACY },
 
358
        { BER_BVNULL,                   0 }
 
359
};
 
360
 
 
361
static slap_verbmasks tls_mode[] = {
 
362
        { BER_BVC( "propagate" ),       LDAP_BACK_F_TLS_PROPAGATE_MASK },
 
363
        { BER_BVC( "try-propagate" ),   LDAP_BACK_F_PROPAGATE_TLS },
 
364
        { BER_BVC( "start" ),           LDAP_BACK_F_TLS_USE_MASK },
 
365
        { BER_BVC( "try-start" ),       LDAP_BACK_F_USE_TLS },
 
366
        { BER_BVC( "ldaps" ),           LDAP_BACK_F_TLS_LDAPS },
 
367
        { BER_BVC( "none" ),            LDAP_BACK_F_NONE },
 
368
        { BER_BVNULL,                   0 }
 
369
};
 
370
 
 
371
static slap_verbmasks t_f_mode[] = {
 
372
        { BER_BVC( "yes" ),             LDAP_BACK_F_T_F },
 
373
        { BER_BVC( "discover" ),        LDAP_BACK_F_T_F_DISCOVER },
 
374
        { BER_BVC( "no" ),              LDAP_BACK_F_NONE },
 
375
        { BER_BVNULL,                   0 }
 
376
};
 
377
 
 
378
static slap_verbmasks cancel_mode[] = {
 
379
        { BER_BVC( "ignore" ),          LDAP_BACK_F_CANCEL_IGNORE },
 
380
        { BER_BVC( "exop" ),            LDAP_BACK_F_CANCEL_EXOP },
 
381
        { BER_BVC( "exop-discover" ),   LDAP_BACK_F_CANCEL_EXOP_DISCOVER },
 
382
        { BER_BVC( "abandon" ),         LDAP_BACK_F_CANCEL_ABANDON },
 
383
        { BER_BVNULL,                   0 }
 
384
};
 
385
 
 
386
/* see enum in slap.h */
 
387
static slap_cf_aux_table timeout_table[] = {
 
388
        { BER_BVC("bind="),     SLAP_OP_BIND * sizeof( time_t ),        'u', 0, NULL },
 
389
        /* unbind makes no sense */
 
390
        { BER_BVC("add="),      SLAP_OP_ADD * sizeof( time_t ),         'u', 0, NULL },
 
391
        { BER_BVC("delete="),   SLAP_OP_DELETE * sizeof( time_t ),      'u', 0, NULL },
 
392
        { BER_BVC("modrdn="),   SLAP_OP_MODRDN * sizeof( time_t ),      'u', 0, NULL },
 
393
        { BER_BVC("modify="),   SLAP_OP_MODIFY * sizeof( time_t ),      'u', 0, NULL },
 
394
        { BER_BVC("compare="),  SLAP_OP_COMPARE * sizeof( time_t ),     'u', 0, NULL },
 
395
        { BER_BVC("search="),   SLAP_OP_SEARCH * sizeof( time_t ),      'u', 0, NULL },
 
396
        /* abandon makes little sense */
 
397
#if 0   /* not implemented yet */
 
398
        { BER_BVC("extended="), SLAP_OP_EXTENDED * sizeof( time_t ),    'u', 0, NULL },
 
399
#endif
 
400
        { BER_BVNULL, 0, 0, 0, NULL }
 
401
};
 
402
 
 
403
int
 
404
slap_retry_info_parse(
 
405
        char                    *in,
 
406
        slap_retry_info_t       *ri,
 
407
        char                    *buf,
 
408
        ber_len_t               buflen )
 
409
{
 
410
        char                    **retrylist = NULL;
 
411
        int                     rc = 0;
 
412
        int                     i;
 
413
 
 
414
        slap_str2clist( &retrylist, in, " ;" );
 
415
        if ( retrylist == NULL ) {
 
416
                return 1;
 
417
        }
 
418
 
 
419
        for ( i = 0; retrylist[ i ] != NULL; i++ )
 
420
                /* count */ ;
 
421
 
 
422
        ri->ri_interval = ch_calloc( sizeof( time_t ), i + 1 );
 
423
        ri->ri_num = ch_calloc( sizeof( int ), i + 1 );
 
424
 
 
425
        for ( i = 0; retrylist[ i ] != NULL; i++ ) {
 
426
                unsigned long   t;
 
427
                char            *sep = strchr( retrylist[ i ], ',' );
 
428
 
 
429
                if ( sep == NULL ) {
 
430
                        snprintf( buf, buflen,
 
431
                                "missing comma in retry pattern #%d \"%s\"",
 
432
                                i, retrylist[ i ] );
 
433
                        rc = 1;
 
434
                        goto done;
 
435
                }
 
436
 
 
437
                *sep++ = '\0';
 
438
 
 
439
                if ( lutil_parse_time( retrylist[ i ], &t ) ) {
 
440
                        snprintf( buf, buflen,
 
441
                                "unable to parse interval #%d \"%s\"",
 
442
                                i, retrylist[ i ] );
 
443
                        rc = 1;
 
444
                        goto done;
 
445
                }
 
446
                ri->ri_interval[ i ] = (time_t)t;
 
447
 
 
448
                if ( strcmp( sep, "+" ) == 0 ) {
 
449
                        if ( retrylist[ i + 1 ] != NULL ) {
 
450
                                snprintf( buf, buflen,
 
451
                                        "extra cruft after retry pattern "
 
452
                                        "#%d \"%s,+\" with \"forever\" mark",
 
453
                                        i, retrylist[ i ] );
 
454
                                rc = 1;
 
455
                                goto done;
 
456
                        }
 
457
                        ri->ri_num[ i ] = SLAP_RETRYNUM_FOREVER;
 
458
                        
 
459
                } else if ( lutil_atoi( &ri->ri_num[ i ], sep ) ) {
 
460
                        snprintf( buf, buflen,
 
461
                                "unable to parse retry num #%d \"%s\"",
 
462
                                i, sep );
 
463
                        rc = 1;
 
464
                        goto done;
 
465
                }
 
466
        }
 
467
 
 
468
        ri->ri_num[ i ] = SLAP_RETRYNUM_TAIL;
 
469
 
 
470
        ri->ri_idx = 0;
 
471
        ri->ri_count = 0;
 
472
        ri->ri_last = (time_t)(-1);
 
473
 
 
474
done:;
 
475
        ldap_charray_free( retrylist );
 
476
 
 
477
        if ( rc ) {
 
478
                slap_retry_info_destroy( ri );
 
479
        }
 
480
 
 
481
        return rc;
 
482
}
 
483
 
 
484
int
 
485
slap_retry_info_unparse(
 
486
        slap_retry_info_t       *ri,
 
487
        struct berval           *bvout )
 
488
{
 
489
        int             i;
 
490
        char            buf[ BUFSIZ * 2 ],
 
491
                        *ptr = buf;
 
492
        struct berval   bv = BER_BVNULL;
 
493
 
 
494
        assert( ri != NULL );
 
495
        assert( bvout != NULL );
 
496
 
 
497
        BER_BVZERO( bvout );
 
498
 
 
499
#define WHATSLEFT       ( sizeof( buf ) - ( ptr - buf ) )
 
500
 
 
501
        for ( i = 0; ri->ri_num[ i ] != SLAP_RETRYNUM_TAIL; i++ ) {
 
502
                if ( i > 0 ) {
 
503
                        if ( WHATSLEFT <= 1 ) {
 
504
                                return 1;
 
505
                        }
 
506
                        *ptr++ = ';';
 
507
                }
 
508
 
 
509
                if ( lutil_unparse_time( ptr, WHATSLEFT, (long)ri->ri_interval[i] ) ) {
 
510
                        return 1;
 
511
                }
 
512
                ptr += strlen( ptr );
 
513
 
 
514
                if ( WHATSLEFT <= 1 ) {
 
515
                        return 1;
 
516
                }
 
517
                *ptr++ = ',';
 
518
 
 
519
                if ( ri->ri_num[i] == SLAP_RETRYNUM_FOREVER ) {
 
520
                        if ( WHATSLEFT <= 1 ) {
 
521
                                return 1;
 
522
                        }
 
523
                        *ptr++ = '+';
 
524
 
 
525
                } else {
 
526
                        ptr += snprintf( ptr, WHATSLEFT, "%d", ri->ri_num[i] );
 
527
                        if ( WHATSLEFT <= 0 ) {
 
528
                                return 1;
 
529
                        }
 
530
                }
 
531
        }
 
532
 
 
533
        bv.bv_val = buf;
 
534
        bv.bv_len = ptr - buf;
 
535
 
 
536
        ber_dupbv( bvout, &bv );
 
537
 
 
538
        return 0;
 
539
}
 
540
 
 
541
void
 
542
slap_retry_info_destroy(
 
543
        slap_retry_info_t       *ri )
 
544
{
 
545
        assert( ri != NULL );
 
546
 
 
547
        assert( ri->ri_interval != NULL );
 
548
        ch_free( ri->ri_interval );
 
549
        ri->ri_interval = NULL;
 
550
 
 
551
        assert( ri->ri_num != NULL );
 
552
        ch_free( ri->ri_num );
 
553
        ri->ri_num = NULL;
 
554
}
 
555
 
 
556
static int
 
557
slap_idassert_authzfrom_parse( ConfigArgs *c, slap_idassert_t *si )
 
558
{
 
559
        struct berval   bv;
 
560
        struct berval   in;
 
561
        int             rc;
 
562
 
 
563
        if ( strcmp( c->argv[ 1 ], "*" ) == 0
 
564
                || strcmp( c->argv[ 1 ], "dn:*" ) == 0
 
565
                || strcasecmp( c->argv[ 1 ], "dn.regex:.*" ) == 0 )
 
566
        {
 
567
                if ( si->si_authz != NULL ) {
 
568
                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
569
                                "\"idassert-authzFrom <authz>\": "
 
570
                                "\"%s\" conflicts with existing authz rules",
 
571
                                c->argv[ 1 ] );
 
572
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
573
                        return 1;
 
574
                }
 
575
 
 
576
                si->si_flags |= LDAP_BACK_AUTH_AUTHZ_ALL;
 
577
 
 
578
                return 0;
 
579
 
 
580
        } else if ( ( si->si_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) {
 
581
                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
582
                        "\"idassert-authzFrom <authz>\": "
 
583
                        "\"<authz>\" conflicts with \"*\"" );
 
584
                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
585
                return 1;
 
586
        }
 
587
        
 
588
        ber_str2bv( c->argv[ 1 ], 0, 0, &in );
 
589
        rc = authzNormalize( 0, NULL, NULL, &in, &bv, NULL );
 
590
        if ( rc != LDAP_SUCCESS ) {
 
591
                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
592
                        "\"idassert-authzFrom <authz>\": "
 
593
                        "invalid syntax" );
 
594
                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
595
                return 1;
 
596
        }
 
597
  
 
598
        ber_bvarray_add( &si->si_authz, &bv );
 
599
 
 
600
        return 0;
 
601
}
 
602
 
 
603
static int
 
604
slap_idassert_parse( ConfigArgs *c, slap_idassert_t *si )
 
605
{
 
606
        int             i;
 
607
 
 
608
        for ( i = 1; i < c->argc; i++ ) {
 
609
                if ( strncasecmp( c->argv[ i ], "mode=", STRLENOF( "mode=" ) ) == 0 ) {
 
610
                        char    *argvi = c->argv[ i ] + STRLENOF( "mode=" );
 
611
                        int     j;
 
612
 
 
613
                        j = verb_to_mask( argvi, idassert_mode );
 
614
                        if ( BER_BVISNULL( &idassert_mode[ j ].word ) ) {
 
615
                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
616
                                        "\"idassert-bind <args>\": "
 
617
                                        "unknown mode \"%s\"",
 
618
                                        argvi );
 
619
                                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
620
                                return 1;
 
621
                        }
 
622
 
 
623
                        si->si_mode = idassert_mode[ j ].mask;
 
624
 
 
625
                } else if ( strncasecmp( c->argv[ i ], "authz=", STRLENOF( "authz=" ) ) == 0 ) {
 
626
                        char    *argvi = c->argv[ i ] + STRLENOF( "authz=" );
 
627
 
 
628
                        if ( strcasecmp( argvi, "native" ) == 0 ) {
 
629
                                if ( si->si_bc.sb_method != LDAP_AUTH_SASL ) {
 
630
                                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
631
                                                "\"idassert-bind <args>\": "
 
632
                                                "authz=\"native\" incompatible "
 
633
                                                "with auth method" );
 
634
                                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
635
                                        return 1;
 
636
                                }
 
637
                                si->si_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ;
 
638
 
 
639
                        } else if ( strcasecmp( argvi, "proxyAuthz" ) == 0 ) {
 
640
                                si->si_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;
 
641
 
 
642
                        } else {
 
643
                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
644
                                        "\"idassert-bind <args>\": "
 
645
                                        "unknown authz \"%s\"",
 
646
                                        argvi );
 
647
                                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
648
                                return 1;
 
649
                        }
 
650
 
 
651
                } else if ( strncasecmp( c->argv[ i ], "flags=", STRLENOF( "flags=" ) ) == 0 ) {
 
652
                        char    *argvi = c->argv[ i ] + STRLENOF( "flags=" );
 
653
                        char    **flags = ldap_str2charray( argvi, "," );
 
654
                        int     j, err = 0;
 
655
 
 
656
                        if ( flags == NULL ) {
 
657
                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
658
                                        "\"idassert-bind <args>\": "
 
659
                                        "unable to parse flags \"%s\"",
 
660
                                        argvi );
 
661
                                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
662
                                return 1;
 
663
                        }
 
664
 
 
665
                        for ( j = 0; flags[ j ] != NULL; j++ ) {
 
666
 
 
667
                                if ( strcasecmp( flags[ j ], "override" ) == 0 ) {
 
668
                                        si->si_flags |= LDAP_BACK_AUTH_OVERRIDE;
 
669
 
 
670
                                } else if ( strcasecmp( flags[ j ], "prescriptive" ) == 0 ) {
 
671
                                        si->si_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE;
 
672
 
 
673
                                } else if ( strcasecmp( flags[ j ], "non-prescriptive" ) == 0 ) {
 
674
                                        si->si_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE );
 
675
 
 
676
                                } else if ( strcasecmp( flags[ j ], "obsolete-proxy-authz" ) == 0 ) {
 
677
                                        if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) {
 
678
                                                Debug( LDAP_DEBUG_ANY,
 
679
                                                                "%s: \"obsolete-proxy-authz\" flag "
 
680
                                                                "in \"idassert-mode <args>\" "
 
681
                                                                "incompatible with previously issued \"obsolete-encoding-workaround\" flag.\n",
 
682
                                                                c->log, 0, 0 );
 
683
                                                err = 1;
 
684
                                                break;
 
685
 
 
686
                                        } else {
 
687
                                                si->si_flags |= LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ;
 
688
                                        }
 
689
 
 
690
                                } else if ( strcasecmp( flags[ j ], "obsolete-encoding-workaround" ) == 0 ) {
 
691
                                        if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) {
 
692
                                                Debug( LDAP_DEBUG_ANY,
 
693
                                                                "%s: \"obsolete-encoding-workaround\" flag "
 
694
                                                        "in \"idassert-mode <args>\" "
 
695
                                                        "incompatible with previously issued \"obsolete-proxy-authz\" flag.\n",
 
696
                                                        c->log, 0, 0 );
 
697
                                                err = 1;
 
698
                                                break;
 
699
 
 
700
                                        } else {
 
701
                                                si->si_flags |= LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND;
 
702
                                        }
 
703
 
 
704
                                } else {
 
705
                                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
706
                                                "\"idassert-bind <args>\": "
 
707
                                                "unknown flag \"%s\"",
 
708
                                                flags[ j ] );
 
709
                                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
710
                                        err = 1;
 
711
                                        break;
 
712
                                }
 
713
                        }
 
714
 
 
715
                        ldap_charray_free( flags );
 
716
                        if ( err ) {
 
717
                                return 1;
 
718
                        }
 
719
 
 
720
                } else if ( bindconf_parse( c->argv[ i ], &si->si_bc ) ) {
 
721
                        return 1;
 
722
                }
 
723
        }
 
724
        bindconf_tls_defaults( &si->si_bc );
 
725
 
 
726
        return 0;
 
727
}
 
728
 
 
729
/* NOTE: temporary, until back-meta is ported to back-config */
 
730
int
 
731
slap_idassert_authzfrom_parse_cf( const char *fname, int lineno, const char *arg, slap_idassert_t *si )
 
732
{
 
733
        ConfigArgs      c = { 0 };
 
734
        char            *argv[ 3 ];
 
735
 
 
736
        snprintf( c.log, sizeof( c.log ), "%s: line %d", fname, lineno );
 
737
        c.argc = 2;
 
738
        c.argv = argv;
 
739
        argv[ 0 ] = "idassert-authzFrom";
 
740
        argv[ 1 ] = (char *)arg;
 
741
        argv[ 2 ] = NULL;
 
742
 
 
743
        return slap_idassert_authzfrom_parse( &c, si );
 
744
}
 
745
 
 
746
int
 
747
slap_idassert_parse_cf( const char *fname, int lineno, int argc, char *argv[], slap_idassert_t *si )
 
748
{
 
749
        ConfigArgs      c = { 0 };
 
750
 
 
751
        snprintf( c.log, sizeof( c.log ), "%s: line %d", fname, lineno );
 
752
        c.argc = argc;
 
753
        c.argv = argv;
 
754
 
 
755
        return slap_idassert_parse( &c, si );
 
756
}
 
757
 
 
758
static int
 
759
ldap_back_cf_gen( ConfigArgs *c )
 
760
{
 
761
        ldapinfo_t      *li = ( ldapinfo_t * )c->be->be_private;
 
762
        int             rc = 0;
 
763
        int             i;
 
764
 
 
765
        if ( c->op == SLAP_CONFIG_EMIT ) {
 
766
                struct berval   bv = BER_BVNULL;
 
767
 
 
768
                if ( li == NULL ) {
 
769
                        return 1;
 
770
                }
 
771
 
 
772
                switch( c->type ) {
 
773
                case LDAP_BACK_CFG_URI:
 
774
                        if ( li->li_uri != NULL ) {
 
775
                                struct berval   bv, bv2;
 
776
 
 
777
                                ber_str2bv( li->li_uri, 0, 0, &bv );
 
778
                                bv2.bv_len = bv.bv_len + STRLENOF( "\"\"" );
 
779
                                bv2.bv_val = ch_malloc( bv2.bv_len + 1 );
 
780
                                snprintf( bv2.bv_val, bv2.bv_len + 1,
 
781
                                        "\"%s\"", bv.bv_val );
 
782
                                ber_bvarray_add( &c->rvalue_vals, &bv2 );
 
783
 
 
784
                        } else {
 
785
                                rc = 1;
 
786
                        }
 
787
                        break;
 
788
 
 
789
                case LDAP_BACK_CFG_TLS: {
 
790
                        struct berval bc = BER_BVNULL, bv2;
 
791
                        enum_to_verb( tls_mode, ( li->li_flags & LDAP_BACK_F_TLS_MASK ), &bv );
 
792
                        assert( !BER_BVISNULL( &bv ) );
 
793
                        bindconf_tls_unparse( &li->li_tls, &bc );
 
794
 
 
795
                        if ( !BER_BVISEMPTY( &bc )) {
 
796
                                bv2.bv_len = bv.bv_len + bc.bv_len + 1;
 
797
                                bv2.bv_val = ch_malloc( bv2.bv_len + 1 );
 
798
                                strcpy( bv2.bv_val, bv.bv_val );
 
799
                                bv2.bv_val[bv.bv_len] = ' ';
 
800
                                strcpy( &bv2.bv_val[bv.bv_len + 1], bc.bv_val );
 
801
                                ber_bvarray_add( &c->rvalue_vals, &bv2 );
 
802
 
 
803
                        } else {
 
804
                                value_add_one( &c->rvalue_vals, &bv );
 
805
                        }
 
806
                        ber_memfree( bc.bv_val );
 
807
                        }
 
808
                        break;
 
809
 
 
810
                case LDAP_BACK_CFG_ACL_AUTHCDN:
 
811
                case LDAP_BACK_CFG_ACL_PASSWD:
 
812
                case LDAP_BACK_CFG_ACL_METHOD:
 
813
                        /* handled by LDAP_BACK_CFG_ACL_BIND */
 
814
                        rc = 1;
 
815
                        break;
 
816
 
 
817
                case LDAP_BACK_CFG_ACL_BIND: {
 
818
                        int     i;
 
819
 
 
820
                        if ( li->li_acl_authmethod == LDAP_AUTH_NONE ) {
 
821
                                return 1;
 
822
                        }
 
823
 
 
824
                        bindconf_unparse( &li->li_acl, &bv );
 
825
 
 
826
                        for ( i = 0; isspace( (unsigned char) bv.bv_val[ i ] ); i++ )
 
827
                                /* count spaces */ ;
 
828
 
 
829
                        if ( i ) {
 
830
                                bv.bv_len -= i;
 
831
                                AC_MEMCPY( bv.bv_val, &bv.bv_val[ i ],
 
832
                                        bv.bv_len + 1 );
 
833
                        }
 
834
 
 
835
                        ber_bvarray_add( &c->rvalue_vals, &bv );
 
836
                        break;
 
837
                }
 
838
 
 
839
                case LDAP_BACK_CFG_IDASSERT_MODE:
 
840
                case LDAP_BACK_CFG_IDASSERT_AUTHCDN:
 
841
                case LDAP_BACK_CFG_IDASSERT_PASSWD:
 
842
                case LDAP_BACK_CFG_IDASSERT_METHOD:
 
843
                        /* handled by LDAP_BACK_CFG_IDASSERT_BIND */
 
844
                        rc = 1;
 
845
                        break;
 
846
 
 
847
                case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: {
 
848
                        int             i;
 
849
 
 
850
                        if ( li->li_idassert_authz == NULL ) {
 
851
                                if ( ( li->li_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) {
 
852
                                        BER_BVSTR( &bv, "*" );
 
853
                                        value_add_one( &c->rvalue_vals, &bv );
 
854
 
 
855
                                } else {
 
856
                                        rc = 1;
 
857
                                }
 
858
                                break;
 
859
                        }
 
860
 
 
861
                        for ( i = 0; !BER_BVISNULL( &li->li_idassert_authz[ i ] ); i++ )
 
862
                        {
 
863
                                value_add_one( &c->rvalue_vals, &li->li_idassert_authz[ i ] );
 
864
                        }
 
865
                        break;
 
866
                }
 
867
 
 
868
                case LDAP_BACK_CFG_IDASSERT_BIND: {
 
869
                        int             i;
 
870
                        struct berval   bc = BER_BVNULL;
 
871
                        char            *ptr;
 
872
 
 
873
                        if ( li->li_idassert_authmethod == LDAP_AUTH_NONE ) {
 
874
                                return 1;
 
875
                        }
 
876
 
 
877
                        if ( li->li_idassert_authmethod != LDAP_AUTH_NONE ) {
 
878
                                ber_len_t       len;
 
879
 
 
880
                                switch ( li->li_idassert_mode ) {
 
881
                                case LDAP_BACK_IDASSERT_OTHERID:
 
882
                                case LDAP_BACK_IDASSERT_OTHERDN:
 
883
                                        break;
 
884
 
 
885
                                default: {
 
886
                                        struct berval   mode = BER_BVNULL;
 
887
 
 
888
                                        enum_to_verb( idassert_mode, li->li_idassert_mode, &mode );
 
889
                                        if ( BER_BVISNULL( &mode ) ) {
 
890
                                                /* there's something wrong... */
 
891
                                                assert( 0 );
 
892
                                                rc = 1;
 
893
        
 
894
                                        } else {
 
895
                                                bv.bv_len = STRLENOF( "mode=" ) + mode.bv_len;
 
896
                                                bv.bv_val = ch_malloc( bv.bv_len + 1 );
 
897
 
 
898
                                                ptr = lutil_strcopy( bv.bv_val, "mode=" );
 
899
                                                ptr = lutil_strcopy( ptr, mode.bv_val );
 
900
                                        }
 
901
                                        break;
 
902
                                }
 
903
                                }
 
904
 
 
905
                                if ( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) {
 
906
                                        len = bv.bv_len + STRLENOF( "authz=native" );
 
907
 
 
908
                                        if ( !BER_BVISEMPTY( &bv ) ) {
 
909
                                                len += STRLENOF( " " );
 
910
                                        }
 
911
 
 
912
                                        bv.bv_val = ch_realloc( bv.bv_val, len + 1 );
 
913
 
 
914
                                        ptr = &bv.bv_val[ bv.bv_len ];
 
915
 
 
916
                                        if ( !BER_BVISEMPTY( &bv ) ) {
 
917
                                                ptr = lutil_strcopy( ptr, " " );
 
918
                                        }
 
919
 
 
920
                                        (void)lutil_strcopy( ptr, "authz=native" );
 
921
                                }
 
922
 
 
923
                                len = bv.bv_len + STRLENOF( "flags=non-prescriptive,override,obsolete-encoding-workaround" );
 
924
                                /* flags */
 
925
                                if ( !BER_BVISEMPTY( &bv ) ) {
 
926
                                        len += STRLENOF( " " );
 
927
                                }
 
928
 
 
929
                                bv.bv_val = ch_realloc( bv.bv_val, len + 1 );
 
930
 
 
931
                                ptr = &bv.bv_val[ bv.bv_len ];
 
932
 
 
933
                                if ( !BER_BVISEMPTY( &bv ) ) {
 
934
                                        ptr = lutil_strcopy( ptr, " " );
 
935
                                }
 
936
 
 
937
                                ptr = lutil_strcopy( ptr, "flags=" );
 
938
 
 
939
                                if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
 
940
                                        ptr = lutil_strcopy( ptr, "prescriptive" );
 
941
                                } else {
 
942
                                        ptr = lutil_strcopy( ptr, "non-prescriptive" );
 
943
                                }
 
944
 
 
945
                                if ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) {
 
946
                                        ptr = lutil_strcopy( ptr, ",override" );
 
947
                                }
 
948
 
 
949
                                if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) {
 
950
                                        ptr = lutil_strcopy( ptr, ",obsolete-proxy-authz" );
 
951
 
 
952
                                } else if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) {
 
953
                                        ptr = lutil_strcopy( ptr, ",obsolete-encoding-workaround" );
 
954
                                }
 
955
 
 
956
                                bv.bv_len = ( ptr - bv.bv_val );
 
957
                                /* end-of-flags */
 
958
                        }
 
959
 
 
960
                        bindconf_unparse( &li->li_idassert.si_bc, &bc );
 
961
 
 
962
                        if ( !BER_BVISNULL( &bv ) ) {
 
963
                                ber_len_t       len = bv.bv_len + bc.bv_len;
 
964
 
 
965
                                bv.bv_val = ch_realloc( bv.bv_val, len + 1 );
 
966
 
 
967
                                assert( bc.bv_val[ 0 ] == ' ' );
 
968
 
 
969
                                ptr = lutil_strcopy( &bv.bv_val[ bv.bv_len ], bc.bv_val );
 
970
                                free( bc.bv_val );
 
971
                                bv.bv_len = ptr - bv.bv_val;
 
972
 
 
973
                        } else {
 
974
                                for ( i = 0; isspace( (unsigned char) bc.bv_val[ i ] ); i++ )
 
975
                                        /* count spaces */ ;
 
976
 
 
977
                                if ( i ) {
 
978
                                        bc.bv_len -= i;
 
979
                                        AC_MEMCPY( bc.bv_val, &bc.bv_val[ i ], bc.bv_len + 1 );
 
980
                                }
 
981
 
 
982
                                bv = bc;
 
983
                        }
 
984
                        
 
985
                        ber_bvarray_add( &c->rvalue_vals, &bv );
 
986
 
 
987
                        break;
 
988
                }
 
989
 
 
990
                case LDAP_BACK_CFG_REBIND:
 
991
                        c->value_int = LDAP_BACK_SAVECRED( li );
 
992
                        break;
 
993
 
 
994
                case LDAP_BACK_CFG_CHASE:
 
995
                        c->value_int = LDAP_BACK_CHASE_REFERRALS( li );
 
996
                        break;
 
997
 
 
998
                case LDAP_BACK_CFG_T_F:
 
999
                        enum_to_verb( t_f_mode, (li->li_flags & LDAP_BACK_F_T_F_MASK2), &bv );
 
1000
                        if ( BER_BVISNULL( &bv ) ) {
 
1001
                                /* there's something wrong... */
 
1002
                                assert( 0 );
 
1003
                                rc = 1;
 
1004
 
 
1005
                        } else {
 
1006
                                value_add_one( &c->rvalue_vals, &bv );
 
1007
                        }
 
1008
                        break;
 
1009
 
 
1010
                case LDAP_BACK_CFG_WHOAMI:
 
1011
                        c->value_int = LDAP_BACK_PROXY_WHOAMI( li );
 
1012
                        break;
 
1013
 
 
1014
                case LDAP_BACK_CFG_TIMEOUT:
 
1015
                        BER_BVZERO( &bv );
 
1016
 
 
1017
                        for ( i = 0; i < SLAP_OP_LAST; i++ ) {
 
1018
                                if ( li->li_timeout[ i ] != 0 ) {
 
1019
                                        break;
 
1020
                                }
 
1021
                        }
 
1022
 
 
1023
                        if ( i == SLAP_OP_LAST ) {
 
1024
                                return 1;
 
1025
                        }
 
1026
 
 
1027
                        slap_cf_aux_table_unparse( li->li_timeout, &bv, timeout_table );
 
1028
 
 
1029
                        if ( BER_BVISNULL( &bv ) ) {
 
1030
                                return 1;
 
1031
                        }
 
1032
 
 
1033
                        for ( i = 0; isspace( (unsigned char) bv.bv_val[ i ] ); i++ )
 
1034
                                /* count spaces */ ;
 
1035
 
 
1036
                        if ( i ) {
 
1037
                                bv.bv_len -= i;
 
1038
                                AC_MEMCPY( bv.bv_val, &bv.bv_val[ i ],
 
1039
                                        bv.bv_len + 1 );
 
1040
                        }
 
1041
 
 
1042
                        ber_bvarray_add( &c->rvalue_vals, &bv );
 
1043
                        break;
 
1044
 
 
1045
                case LDAP_BACK_CFG_IDLE_TIMEOUT: {
 
1046
                        char    buf[ SLAP_TEXT_BUFLEN ];
 
1047
 
 
1048
                        if ( li->li_idle_timeout == 0 ) {
 
1049
                                return 1;
 
1050
                        }
 
1051
 
 
1052
                        lutil_unparse_time( buf, sizeof( buf ), li->li_idle_timeout );
 
1053
                        ber_str2bv( buf, 0, 0, &bv );
 
1054
                        value_add_one( &c->rvalue_vals, &bv );
 
1055
                        } break;
 
1056
 
 
1057
                case LDAP_BACK_CFG_CONN_TTL: {
 
1058
                        char    buf[ SLAP_TEXT_BUFLEN ];
 
1059
 
 
1060
                        if ( li->li_conn_ttl == 0 ) {
 
1061
                                return 1;
 
1062
                        }
 
1063
 
 
1064
                        lutil_unparse_time( buf, sizeof( buf ), li->li_conn_ttl );
 
1065
                        ber_str2bv( buf, 0, 0, &bv );
 
1066
                        value_add_one( &c->rvalue_vals, &bv );
 
1067
                        } break;
 
1068
 
 
1069
                case LDAP_BACK_CFG_NETWORK_TIMEOUT: {
 
1070
                        char    buf[ SLAP_TEXT_BUFLEN ];
 
1071
 
 
1072
                        if ( li->li_network_timeout == 0 ) {
 
1073
                                return 1;
 
1074
                        }
 
1075
 
 
1076
                        snprintf( buf, sizeof( buf ), "%ld",
 
1077
                                (long)li->li_network_timeout );
 
1078
                        ber_str2bv( buf, 0, 0, &bv );
 
1079
                        value_add_one( &c->rvalue_vals, &bv );
 
1080
                        } break;
 
1081
 
 
1082
                case LDAP_BACK_CFG_VERSION:
 
1083
                        if ( li->li_version == 0 ) {
 
1084
                                return 1;
 
1085
                        }
 
1086
 
 
1087
                        c->value_int = li->li_version;
 
1088
                        break;
 
1089
 
 
1090
                case LDAP_BACK_CFG_SINGLECONN:
 
1091
                        c->value_int = LDAP_BACK_SINGLECONN( li );
 
1092
                        break;
 
1093
 
 
1094
                case LDAP_BACK_CFG_USETEMP:
 
1095
                        c->value_int = LDAP_BACK_USE_TEMPORARIES( li );
 
1096
                        break;
 
1097
 
 
1098
                case LDAP_BACK_CFG_CONNPOOLMAX:
 
1099
                        c->value_int = li->li_conn_priv_max;
 
1100
                        break;
 
1101
 
 
1102
                case LDAP_BACK_CFG_CANCEL: {
 
1103
                        slap_mask_t     mask = LDAP_BACK_F_CANCEL_MASK2;
 
1104
 
 
1105
                        if ( LDAP_BACK_CANCEL_DISCOVER( li ) ) {
 
1106
                                mask &= ~LDAP_BACK_F_CANCEL_EXOP;
 
1107
                        }
 
1108
                        enum_to_verb( cancel_mode, (li->li_flags & mask), &bv );
 
1109
                        if ( BER_BVISNULL( &bv ) ) {
 
1110
                                /* there's something wrong... */
 
1111
                                assert( 0 );
 
1112
                                rc = 1;
 
1113
 
 
1114
                        } else {
 
1115
                                value_add_one( &c->rvalue_vals, &bv );
 
1116
                        }
 
1117
                        } break;
 
1118
 
 
1119
                case LDAP_BACK_CFG_QUARANTINE:
 
1120
                        if ( !LDAP_BACK_QUARANTINE( li ) ) {
 
1121
                                rc = 1;
 
1122
                                break;
 
1123
                        }
 
1124
 
 
1125
                        rc = slap_retry_info_unparse( &li->li_quarantine, &bv );
 
1126
                        if ( rc == 0 ) {
 
1127
                                ber_bvarray_add( &c->rvalue_vals, &bv );
 
1128
                        }
 
1129
                        break;
 
1130
 
 
1131
#ifdef SLAP_CONTROL_X_SESSION_TRACKING
 
1132
                case LDAP_BACK_CFG_ST_REQUEST:
 
1133
                        c->value_int = LDAP_BACK_ST_REQUEST( li );
 
1134
                        break;
 
1135
#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
 
1136
 
 
1137
                default:
 
1138
                        /* FIXME: we need to handle all... */
 
1139
                        assert( 0 );
 
1140
                        break;
 
1141
                }
 
1142
                return rc;
 
1143
 
 
1144
        } else if ( c->op == LDAP_MOD_DELETE ) {
 
1145
                switch( c->type ) {
 
1146
                case LDAP_BACK_CFG_URI:
 
1147
                        if ( li->li_uri != NULL ) {
 
1148
                                ch_free( li->li_uri );
 
1149
                                li->li_uri = NULL;
 
1150
 
 
1151
                                assert( li->li_bvuri != NULL );
 
1152
                                ber_bvarray_free( li->li_bvuri );
 
1153
                                li->li_bvuri = NULL;
 
1154
                        }
 
1155
 
 
1156
                        /* better cleanup the cached connections... */
 
1157
                        /* NOTE: don't worry about locking: if we got here,
 
1158
                         * other threads are suspended. */
 
1159
                        if ( li->li_conninfo.lai_tree != NULL ) {
 
1160
                                avl_free( li->li_conninfo.lai_tree, ldap_back_conn_free );
 
1161
                                li->li_conninfo.lai_tree = NULL;
 
1162
                        }
 
1163
                        
 
1164
                        break;
 
1165
 
 
1166
                case LDAP_BACK_CFG_TLS:
 
1167
                        rc = 1;
 
1168
                        break;
 
1169
 
 
1170
                case LDAP_BACK_CFG_ACL_AUTHCDN:
 
1171
                case LDAP_BACK_CFG_ACL_PASSWD:
 
1172
                case LDAP_BACK_CFG_ACL_METHOD:
 
1173
                        /* handled by LDAP_BACK_CFG_ACL_BIND */
 
1174
                        rc = 1;
 
1175
                        break;
 
1176
 
 
1177
                case LDAP_BACK_CFG_ACL_BIND:
 
1178
                        bindconf_free( &li->li_acl );
 
1179
                        break;
 
1180
 
 
1181
                case LDAP_BACK_CFG_IDASSERT_MODE:
 
1182
                case LDAP_BACK_CFG_IDASSERT_AUTHCDN:
 
1183
                case LDAP_BACK_CFG_IDASSERT_PASSWD:
 
1184
                case LDAP_BACK_CFG_IDASSERT_METHOD:
 
1185
                        /* handled by LDAP_BACK_CFG_IDASSERT_BIND */
 
1186
                        rc = 1;
 
1187
                        break;
 
1188
 
 
1189
                case LDAP_BACK_CFG_IDASSERT_AUTHZFROM:
 
1190
                        if ( li->li_idassert_authz != NULL ) {
 
1191
                                ber_bvarray_free( li->li_idassert_authz );
 
1192
                                li->li_idassert_authz = NULL;
 
1193
                        }
 
1194
                        break;
 
1195
 
 
1196
                case LDAP_BACK_CFG_IDASSERT_BIND:
 
1197
                        bindconf_free( &li->li_idassert.si_bc );
 
1198
                        break;
 
1199
 
 
1200
                case LDAP_BACK_CFG_REBIND:
 
1201
                case LDAP_BACK_CFG_CHASE:
 
1202
                case LDAP_BACK_CFG_T_F:
 
1203
                case LDAP_BACK_CFG_WHOAMI:
 
1204
                case LDAP_BACK_CFG_CANCEL:
 
1205
                        rc = 1;
 
1206
                        break;
 
1207
 
 
1208
                case LDAP_BACK_CFG_TIMEOUT:
 
1209
                        for ( i = 0; i < SLAP_OP_LAST; i++ ) {
 
1210
                                li->li_timeout[ i ] = 0;
 
1211
                        }
 
1212
                        break;
 
1213
 
 
1214
                case LDAP_BACK_CFG_IDLE_TIMEOUT:
 
1215
                        li->li_idle_timeout = 0;
 
1216
                        break;
 
1217
 
 
1218
                case LDAP_BACK_CFG_CONN_TTL:
 
1219
                        li->li_conn_ttl = 0;
 
1220
                        break;
 
1221
 
 
1222
                case LDAP_BACK_CFG_NETWORK_TIMEOUT:
 
1223
                        li->li_network_timeout = 0;
 
1224
                        break;
 
1225
 
 
1226
                case LDAP_BACK_CFG_VERSION:
 
1227
                        li->li_version = 0;
 
1228
                        break;
 
1229
 
 
1230
                case LDAP_BACK_CFG_SINGLECONN:
 
1231
                        li->li_flags &= ~LDAP_BACK_F_SINGLECONN;
 
1232
                        break;
 
1233
 
 
1234
                case LDAP_BACK_CFG_USETEMP:
 
1235
                        li->li_flags &= ~LDAP_BACK_F_USE_TEMPORARIES;
 
1236
                        break;
 
1237
 
 
1238
                case LDAP_BACK_CFG_CONNPOOLMAX:
 
1239
                        li->li_conn_priv_max = LDAP_BACK_CONN_PRIV_MIN;
 
1240
                        break;
 
1241
 
 
1242
                case LDAP_BACK_CFG_QUARANTINE:
 
1243
                        if ( !LDAP_BACK_QUARANTINE( li ) ) {
 
1244
                                break;
 
1245
                        }
 
1246
 
 
1247
                        slap_retry_info_destroy( &li->li_quarantine );
 
1248
                        ldap_pvt_thread_mutex_destroy( &li->li_quarantine_mutex );
 
1249
                        li->li_isquarantined = 0;
 
1250
                        li->li_flags &= ~LDAP_BACK_F_QUARANTINE;
 
1251
                        break;
 
1252
 
 
1253
#ifdef SLAP_CONTROL_X_SESSION_TRACKING
 
1254
                case LDAP_BACK_CFG_ST_REQUEST:
 
1255
                        li->li_flags &= ~LDAP_BACK_F_ST_REQUEST;
 
1256
                        break;
 
1257
#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
 
1258
 
 
1259
                default:
 
1260
                        /* FIXME: we need to handle all... */
 
1261
                        assert( 0 );
 
1262
                        break;
 
1263
                }
 
1264
                return rc;
 
1265
 
 
1266
        }
 
1267
 
 
1268
        switch( c->type ) {
 
1269
        case LDAP_BACK_CFG_URI: {
 
1270
                LDAPURLDesc     *tmpludp, *lud;
 
1271
                char            **urllist = NULL;
 
1272
                int             urlrc = LDAP_URL_SUCCESS, i;
 
1273
 
 
1274
                if ( li->li_uri != NULL ) {
 
1275
                        ch_free( li->li_uri );
 
1276
                        li->li_uri = NULL;
 
1277
 
 
1278
                        assert( li->li_bvuri != NULL );
 
1279
                        ber_bvarray_free( li->li_bvuri );
 
1280
                        li->li_bvuri = NULL;
 
1281
                }
 
1282
 
 
1283
                /* PARANOID: DN and more are not required nor allowed */
 
1284
                urlrc = ldap_url_parselist_ext( &lud, c->argv[ 1 ], ", \t", LDAP_PVT_URL_PARSE_NONE );
 
1285
                if ( urlrc != LDAP_URL_SUCCESS ) {
 
1286
                        char    *why;
 
1287
 
 
1288
                        switch ( urlrc ) {
 
1289
                        case LDAP_URL_ERR_MEM:
 
1290
                                why = "no memory";
 
1291
                                break;
 
1292
                        case LDAP_URL_ERR_PARAM:
 
1293
                                why = "parameter is bad";
 
1294
                                break;
 
1295
                        case LDAP_URL_ERR_BADSCHEME:
 
1296
                                why = "URL doesn't begin with \"[c]ldap[si]://\"";
 
1297
                                break;
 
1298
                        case LDAP_URL_ERR_BADENCLOSURE:
 
1299
                                why = "URL is missing trailing \">\"";
 
1300
                                break;
 
1301
                        case LDAP_URL_ERR_BADURL:
 
1302
                                why = "URL is bad";
 
1303
                                break;
 
1304
                        case LDAP_URL_ERR_BADHOST:
 
1305
                                why = "host/port is bad";
 
1306
                                break;
 
1307
                        case LDAP_URL_ERR_BADATTRS:
 
1308
                                why = "bad (or missing) attributes";
 
1309
                                break;
 
1310
                        case LDAP_URL_ERR_BADSCOPE:
 
1311
                                why = "scope string is invalid (or missing)";
 
1312
                                break;
 
1313
                        case LDAP_URL_ERR_BADFILTER:
 
1314
                                why = "bad or missing filter";
 
1315
                                break;
 
1316
                        case LDAP_URL_ERR_BADEXTS:
 
1317
                                why = "bad or missing extensions";
 
1318
                                break;
 
1319
                        default:
 
1320
                                why = "unknown reason";
 
1321
                                break;
 
1322
                        }
 
1323
                        snprintf( c->cr_msg, sizeof( c->cr_msg),
 
1324
                                        "unable to parse uri \"%s\" "
 
1325
                                        "in \"uri <uri>\" line: %s",
 
1326
                                        c->value_string, why );
 
1327
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1328
                        urlrc = 1;
 
1329
                        goto done_url;
 
1330
                }
 
1331
 
 
1332
                for ( i = 0, tmpludp = lud;
 
1333
                                tmpludp;
 
1334
                                i++, tmpludp = tmpludp->lud_next )
 
1335
                {
 
1336
                        if ( ( tmpludp->lud_dn != NULL
 
1337
                                                && tmpludp->lud_dn[0] != '\0' )
 
1338
                                        || tmpludp->lud_attrs != NULL
 
1339
                                        /* || tmpludp->lud_scope != LDAP_SCOPE_DEFAULT */
 
1340
                                        || tmpludp->lud_filter != NULL
 
1341
                                        || tmpludp->lud_exts != NULL )
 
1342
                        {
 
1343
                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
1344
                                                "warning, only protocol, "
 
1345
                                                "host and port allowed "
 
1346
                                                "in \"uri <uri>\" statement "
 
1347
                                                "for uri #%d of \"%s\"",
 
1348
                                                i, c->argv[ 1 ] );
 
1349
                                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1350
                        }
 
1351
                }
 
1352
 
 
1353
                for ( i = 0, tmpludp = lud;
 
1354
                                tmpludp;
 
1355
                                i++, tmpludp = tmpludp->lud_next )
 
1356
                        /* just count */
 
1357
                        ;
 
1358
                urllist = ch_calloc( sizeof( char * ), i + 1 );
 
1359
 
 
1360
                for ( i = 0, tmpludp = lud;
 
1361
                                tmpludp;
 
1362
                                i++, tmpludp = tmpludp->lud_next )
 
1363
                {
 
1364
                        LDAPURLDesc     tmplud;
 
1365
 
 
1366
                        tmplud = *tmpludp;
 
1367
                        tmplud.lud_dn = "";
 
1368
                        tmplud.lud_attrs = NULL;
 
1369
                        tmplud.lud_filter = NULL;
 
1370
                        if ( !ldap_is_ldapi_url( tmplud.lud_scheme ) ) {
 
1371
                                tmplud.lud_exts = NULL;
 
1372
                                tmplud.lud_crit_exts = 0;
 
1373
                        }
 
1374
 
 
1375
                        urllist[ i ]  = ldap_url_desc2str( &tmplud );
 
1376
 
 
1377
                        if ( urllist[ i ] == NULL ) {
 
1378
                                snprintf( c->cr_msg, sizeof( c->cr_msg),
 
1379
                                        "unable to rebuild uri "
 
1380
                                        "in \"uri <uri>\" statement "
 
1381
                                        "for \"%s\"",
 
1382
                                        c->argv[ 1 ] );
 
1383
                                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1384
                                urlrc = 1;
 
1385
                                goto done_url;
 
1386
                        }
 
1387
                }
 
1388
 
 
1389
                li->li_uri = ldap_charray2str( urllist, " " );
 
1390
                for ( i = 0; urllist[ i ] != NULL; i++ ) {
 
1391
                        struct berval   bv;
 
1392
 
 
1393
                        ber_str2bv( urllist[ i ], 0, 0, &bv );
 
1394
                        ber_bvarray_add( &li->li_bvuri, &bv );
 
1395
                        urllist[ i ] = NULL;
 
1396
                }
 
1397
                ldap_memfree( urllist );
 
1398
                urllist = NULL;
 
1399
 
 
1400
done_url:;
 
1401
                if ( urllist ) {
 
1402
                        ldap_charray_free( urllist );
 
1403
                }
 
1404
                if ( lud ) {
 
1405
                        ldap_free_urllist( lud );
 
1406
                }
 
1407
                if ( urlrc != LDAP_URL_SUCCESS ) {
 
1408
                        return 1;
 
1409
                }
 
1410
                break;
 
1411
        }
 
1412
 
 
1413
        case LDAP_BACK_CFG_TLS:
 
1414
                i = verb_to_mask( c->argv[1], tls_mode );
 
1415
                if ( BER_BVISNULL( &tls_mode[i].word ) ) {
 
1416
                        return 1;
 
1417
                }
 
1418
                li->li_flags &= ~LDAP_BACK_F_TLS_MASK;
 
1419
                li->li_flags |= tls_mode[i].mask;
 
1420
                if ( c->argc > 2 ) {
 
1421
                        for ( i=2; i<c->argc; i++ ) {
 
1422
                                if ( bindconf_tls_parse( c->argv[i], &li->li_tls ))
 
1423
                                        return 1;
 
1424
                        }
 
1425
                        bindconf_tls_defaults( &li->li_tls );
 
1426
                }
 
1427
                break;
 
1428
 
 
1429
        case LDAP_BACK_CFG_ACL_AUTHCDN:
 
1430
                switch ( li->li_acl_authmethod ) {
 
1431
                case LDAP_AUTH_NONE:
 
1432
                        li->li_acl_authmethod = LDAP_AUTH_SIMPLE;
 
1433
                        break;
 
1434
 
 
1435
                case LDAP_AUTH_SIMPLE:
 
1436
                        break;
 
1437
 
 
1438
                default:
 
1439
                        snprintf( c->cr_msg, sizeof( c->cr_msg),
 
1440
                                "\"acl-authcDN <DN>\" incompatible "
 
1441
                                "with auth method %d",
 
1442
                                li->li_acl_authmethod );
 
1443
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1444
                        return 1;
 
1445
                }
 
1446
                if ( !BER_BVISNULL( &li->li_acl_authcDN ) ) {
 
1447
                        free( li->li_acl_authcDN.bv_val );
 
1448
                }
 
1449
                ber_memfree_x( c->value_dn.bv_val, NULL );
 
1450
                li->li_acl_authcDN = c->value_ndn;
 
1451
                BER_BVZERO( &c->value_dn );
 
1452
                BER_BVZERO( &c->value_ndn );
 
1453
                break;
 
1454
 
 
1455
        case LDAP_BACK_CFG_ACL_PASSWD:
 
1456
                switch ( li->li_acl_authmethod ) {
 
1457
                case LDAP_AUTH_NONE:
 
1458
                        li->li_acl_authmethod = LDAP_AUTH_SIMPLE;
 
1459
                        break;
 
1460
 
 
1461
                case LDAP_AUTH_SIMPLE:
 
1462
                        break;
 
1463
 
 
1464
                default:
 
1465
                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
1466
                                "\"acl-passwd <cred>\" incompatible "
 
1467
                                "with auth method %d",
 
1468
                                li->li_acl_authmethod );
 
1469
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1470
                        return 1;
 
1471
                }
 
1472
                if ( !BER_BVISNULL( &li->li_acl_passwd ) ) {
 
1473
                        free( li->li_acl_passwd.bv_val );
 
1474
                }
 
1475
                ber_str2bv( c->argv[ 1 ], 0, 1, &li->li_acl_passwd );
 
1476
                break;
 
1477
 
 
1478
        case LDAP_BACK_CFG_ACL_METHOD:
 
1479
        case LDAP_BACK_CFG_ACL_BIND:
 
1480
                for ( i = 1; i < c->argc; i++ ) {
 
1481
                        if ( bindconf_parse( c->argv[ i ], &li->li_acl ) ) {
 
1482
                                return 1;
 
1483
                        }
 
1484
                }
 
1485
                bindconf_tls_defaults( &li->li_acl );
 
1486
                break;
 
1487
 
 
1488
        case LDAP_BACK_CFG_IDASSERT_MODE:
 
1489
                i = verb_to_mask( c->argv[1], idassert_mode );
 
1490
                if ( BER_BVISNULL( &idassert_mode[i].word ) ) {
 
1491
                        if ( strncasecmp( c->argv[1], "u:", STRLENOF( "u:" ) ) == 0 ) {
 
1492
                                li->li_idassert_mode = LDAP_BACK_IDASSERT_OTHERID;
 
1493
                                ber_str2bv( c->argv[1], 0, 1, &li->li_idassert_authzID );
 
1494
                                li->li_idassert_authzID.bv_val[ 0 ] = 'u';
 
1495
                                
 
1496
                        } else {
 
1497
                                struct berval   id, ndn;
 
1498
 
 
1499
                                ber_str2bv( c->argv[1], 0, 0, &id );
 
1500
 
 
1501
                                if ( strncasecmp( c->argv[1], "dn:", STRLENOF( "dn:" ) ) == 0 ) {
 
1502
                                        id.bv_val += STRLENOF( "dn:" );
 
1503
                                        id.bv_len -= STRLENOF( "dn:" );
 
1504
                                }
 
1505
 
 
1506
                                rc = dnNormalize( 0, NULL, NULL, &id, &ndn, NULL );
 
1507
                                if ( rc != LDAP_SUCCESS ) {
 
1508
                                        Debug( LDAP_DEBUG_ANY,
 
1509
                                                "%s: line %d: idassert ID \"%s\" is not a valid DN\n",
 
1510
                                                c->fname, c->lineno, c->argv[1] );
 
1511
                                        return 1;
 
1512
                                }
 
1513
 
 
1514
                                li->li_idassert_authzID.bv_len = STRLENOF( "dn:" ) + ndn.bv_len;
 
1515
                                li->li_idassert_authzID.bv_val = ch_malloc( li->li_idassert_authzID.bv_len + 1 );
 
1516
                                AC_MEMCPY( li->li_idassert_authzID.bv_val, "dn:", STRLENOF( "dn:" ) );
 
1517
                                AC_MEMCPY( &li->li_idassert_authzID.bv_val[ STRLENOF( "dn:" ) ], ndn.bv_val, ndn.bv_len + 1 );
 
1518
                                ch_free( ndn.bv_val );
 
1519
 
 
1520
                                li->li_idassert_mode = LDAP_BACK_IDASSERT_OTHERDN;
 
1521
                        }
 
1522
 
 
1523
                } else {
 
1524
                        li->li_idassert_mode = idassert_mode[i].mask;
 
1525
                }
 
1526
 
 
1527
                if ( c->argc > 2 ) {
 
1528
                        int     i;
 
1529
 
 
1530
                        for ( i = 2; i < c->argc; i++ ) {
 
1531
                                if ( strcasecmp( c->argv[ i ], "override" ) == 0 ) {
 
1532
                                        li->li_idassert_flags |= LDAP_BACK_AUTH_OVERRIDE;
 
1533
 
 
1534
                                } else if ( strcasecmp( c->argv[ i ], "prescriptive" ) == 0 ) {
 
1535
                                        li->li_idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE;
 
1536
 
 
1537
                                } else if ( strcasecmp( c->argv[ i ], "non-prescriptive" ) == 0 ) {
 
1538
                                        li->li_idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE );
 
1539
 
 
1540
                                } else if ( strcasecmp( c->argv[ i ], "obsolete-proxy-authz" ) == 0 ) {
 
1541
                                        if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) {
 
1542
                                                Debug( LDAP_DEBUG_ANY,
 
1543
                                                        "%s: line %d: \"obsolete-proxy-authz\" flag "
 
1544
                                                        "in \"idassert-mode <args>\" "
 
1545
                                                        "incompatible with previously issued \"obsolete-encoding-workaround\" flag.\n",
 
1546
                                                        c->fname, c->lineno, 0 );
 
1547
                                                return 1;
 
1548
                                        }
 
1549
                                        li->li_idassert_flags |= LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ;
 
1550
 
 
1551
                                } else if ( strcasecmp( c->argv[ i ], "obsolete-encoding-workaround" ) == 0 ) {
 
1552
                                        if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) {
 
1553
                                                Debug( LDAP_DEBUG_ANY,
 
1554
                                                        "%s: line %d: \"obsolete-encoding-workaround\" flag "
 
1555
                                                        "in \"idassert-mode <args>\" "
 
1556
                                                        "incompatible with previously issued \"obsolete-proxy-authz\" flag.\n",
 
1557
                                                        c->fname, c->lineno, 0 );
 
1558
                                                return 1;
 
1559
                                        }
 
1560
                                        li->li_idassert_flags |= LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND;
 
1561
 
 
1562
                                } else {
 
1563
                                        Debug( LDAP_DEBUG_ANY,
 
1564
                                                "%s: line %d: unknown flag #%d "
 
1565
                                                "in \"idassert-mode <args> "
 
1566
                                                "[<flags>]\" line.\n",
 
1567
                                                c->fname, c->lineno, i - 2 );
 
1568
                                        return 1;
 
1569
                                }
 
1570
                        }
 
1571
                }
 
1572
                break;
 
1573
 
 
1574
        case LDAP_BACK_CFG_IDASSERT_AUTHCDN:
 
1575
                switch ( li->li_idassert_authmethod ) {
 
1576
                case LDAP_AUTH_NONE:
 
1577
                        li->li_idassert_authmethod = LDAP_AUTH_SIMPLE;
 
1578
                        break;
 
1579
 
 
1580
                case LDAP_AUTH_SIMPLE:
 
1581
                        break;
 
1582
 
 
1583
                default:
 
1584
                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
1585
                                "\"idassert-authcDN <DN>\" incompatible "
 
1586
                                "with auth method %d",
 
1587
                                li->li_idassert_authmethod );
 
1588
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1589
                        return 1;
 
1590
                }
 
1591
                if ( !BER_BVISNULL( &li->li_idassert_authcDN ) ) {
 
1592
                        free( li->li_idassert_authcDN.bv_val );
 
1593
                }
 
1594
                ber_memfree_x( c->value_dn.bv_val, NULL );
 
1595
                li->li_idassert_authcDN = c->value_ndn;
 
1596
                BER_BVZERO( &c->value_dn );
 
1597
                BER_BVZERO( &c->value_ndn );
 
1598
                break;
 
1599
 
 
1600
        case LDAP_BACK_CFG_IDASSERT_PASSWD:
 
1601
                switch ( li->li_idassert_authmethod ) {
 
1602
                case LDAP_AUTH_NONE:
 
1603
                        li->li_idassert_authmethod = LDAP_AUTH_SIMPLE;
 
1604
                        break;
 
1605
 
 
1606
                case LDAP_AUTH_SIMPLE:
 
1607
                        break;
 
1608
 
 
1609
                default:
 
1610
                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
1611
                                "\"idassert-passwd <cred>\" incompatible "
 
1612
                                "with auth method %d",
 
1613
                                li->li_idassert_authmethod );
 
1614
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1615
                        return 1;
 
1616
                }
 
1617
                if ( !BER_BVISNULL( &li->li_idassert_passwd ) ) {
 
1618
                        free( li->li_idassert_passwd.bv_val );
 
1619
                }
 
1620
                ber_str2bv( c->argv[ 1 ], 0, 1, &li->li_idassert_passwd );
 
1621
                break;
 
1622
 
 
1623
        case LDAP_BACK_CFG_IDASSERT_AUTHZFROM:
 
1624
                rc = slap_idassert_authzfrom_parse( c, &li->li_idassert );
 
1625
                break;
 
1626
 
 
1627
        case LDAP_BACK_CFG_IDASSERT_METHOD:
 
1628
                /* no longer supported */
 
1629
                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
1630
                        "\"idassert-method <args>\": "
 
1631
                        "no longer supported; use \"idassert-bind\"" );
 
1632
                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1633
                return 1;
 
1634
 
 
1635
        case LDAP_BACK_CFG_IDASSERT_BIND:
 
1636
                rc = slap_idassert_parse( c, &li->li_idassert );
 
1637
                break;
 
1638
 
 
1639
        case LDAP_BACK_CFG_REBIND:
 
1640
                if ( c->argc == 1 || c->value_int ) {
 
1641
                        li->li_flags |= LDAP_BACK_F_SAVECRED;
 
1642
 
 
1643
                } else {
 
1644
                        li->li_flags &= ~LDAP_BACK_F_SAVECRED;
 
1645
                }
 
1646
                break;
 
1647
 
 
1648
        case LDAP_BACK_CFG_CHASE:
 
1649
                if ( c->argc == 1 || c->value_int ) {
 
1650
                        li->li_flags |= LDAP_BACK_F_CHASE_REFERRALS;
 
1651
 
 
1652
                } else {
 
1653
                        li->li_flags &= ~LDAP_BACK_F_CHASE_REFERRALS;
 
1654
                }
 
1655
                break;
 
1656
 
 
1657
        case LDAP_BACK_CFG_T_F: {
 
1658
                slap_mask_t             mask;
 
1659
 
 
1660
                i = verb_to_mask( c->argv[1], t_f_mode );
 
1661
                if ( BER_BVISNULL( &t_f_mode[i].word ) ) {
 
1662
                        return 1;
 
1663
                }
 
1664
 
 
1665
                mask = t_f_mode[i].mask;
 
1666
 
 
1667
                if ( LDAP_BACK_ISOPEN( li )
 
1668
                        && mask == LDAP_BACK_F_T_F_DISCOVER
 
1669
                        && !LDAP_BACK_T_F( li ) )
 
1670
                {
 
1671
                        slap_bindconf   sb = { BER_BVNULL };
 
1672
                        int             rc;
 
1673
 
 
1674
                        if ( li->li_uri == NULL ) {
 
1675
                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
1676
                                        "need URI to discover absolute filters support "
 
1677
                                        "in \"t-f-support discover\"" );
 
1678
                                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1679
                                return 1;
 
1680
                        }
 
1681
 
 
1682
                        ber_str2bv( li->li_uri, 0, 0, &sb.sb_uri );
 
1683
                        sb.sb_version = li->li_version;
 
1684
                        sb.sb_method = LDAP_AUTH_SIMPLE;
 
1685
                        BER_BVSTR( &sb.sb_binddn, "" );
 
1686
 
 
1687
                        rc = slap_discover_feature( &sb,
 
1688
                                        slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
 
1689
                                        LDAP_FEATURE_ABSOLUTE_FILTERS );
 
1690
                        if ( rc == LDAP_COMPARE_TRUE ) {
 
1691
                                mask |= LDAP_BACK_F_T_F;
 
1692
                        }
 
1693
                }
 
1694
 
 
1695
                li->li_flags &= ~LDAP_BACK_F_T_F_MASK2;
 
1696
                li->li_flags |= mask;
 
1697
                } break;
 
1698
 
 
1699
        case LDAP_BACK_CFG_WHOAMI:
 
1700
                if ( c->argc == 1 || c->value_int ) {
 
1701
                        li->li_flags |= LDAP_BACK_F_PROXY_WHOAMI;
 
1702
                        load_extop( (struct berval *)&slap_EXOP_WHOAMI,
 
1703
                                        0, ldap_back_exop_whoami );
 
1704
 
 
1705
                } else {
 
1706
                        li->li_flags &= ~LDAP_BACK_F_PROXY_WHOAMI;
 
1707
                }
 
1708
                break;
 
1709
 
 
1710
        case LDAP_BACK_CFG_TIMEOUT:
 
1711
                for ( i = 1; i < c->argc; i++ ) {
 
1712
                        if ( isdigit( (unsigned char) c->argv[ i ][ 0 ] ) ) {
 
1713
                                int             j;
 
1714
                                unsigned        u;
 
1715
 
 
1716
                                if ( lutil_atoux( &u, c->argv[ i ], 0 ) != 0 ) {
 
1717
                                        snprintf( c->cr_msg, sizeof( c->cr_msg),
 
1718
                                                "unable to parse timeout \"%s\"",
 
1719
                                                c->argv[ i ] );
 
1720
                                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1721
                                        return 1;
 
1722
                                }
 
1723
 
 
1724
                                for ( j = 0; j < SLAP_OP_LAST; j++ ) {
 
1725
                                        li->li_timeout[ j ] = u;
 
1726
                                }
 
1727
 
 
1728
                                continue;
 
1729
                        }
 
1730
 
 
1731
                        if ( slap_cf_aux_table_parse( c->argv[ i ], li->li_timeout, timeout_table, "slapd-ldap timeout" ) ) {
 
1732
                                snprintf( c->cr_msg, sizeof( c->cr_msg),
 
1733
                                        "unable to parse timeout \"%s\"",
 
1734
                                        c->argv[ i ] );
 
1735
                                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1736
                                return 1;
 
1737
                        }
 
1738
                }
 
1739
                break;
 
1740
 
 
1741
        case LDAP_BACK_CFG_IDLE_TIMEOUT: {
 
1742
                unsigned long   t;
 
1743
 
 
1744
                if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
 
1745
                        snprintf( c->cr_msg, sizeof( c->cr_msg),
 
1746
                                "unable to parse idle timeout \"%s\"",
 
1747
                                c->argv[ 1 ] );
 
1748
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1749
                        return 1;
 
1750
                }
 
1751
                li->li_idle_timeout = (time_t)t;
 
1752
                } break;
 
1753
 
 
1754
        case LDAP_BACK_CFG_CONN_TTL: {
 
1755
                unsigned long   t;
 
1756
 
 
1757
                if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
 
1758
                        snprintf( c->cr_msg, sizeof( c->cr_msg),
 
1759
                                "unable to parse conn ttl\"%s\"",
 
1760
                                c->argv[ 1 ] );
 
1761
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1762
                        return 1;
 
1763
                }
 
1764
                li->li_conn_ttl = (time_t)t;
 
1765
                } break;
 
1766
 
 
1767
        case LDAP_BACK_CFG_NETWORK_TIMEOUT: {
 
1768
                unsigned long   t;
 
1769
 
 
1770
                if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
 
1771
                        snprintf( c->cr_msg, sizeof( c->cr_msg),
 
1772
                                "unable to parse network timeout \"%s\"",
 
1773
                                c->argv[ 1 ] );
 
1774
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1775
                        return 1;
 
1776
                }
 
1777
                li->li_network_timeout = (time_t)t;
 
1778
                } break;
 
1779
 
 
1780
        case LDAP_BACK_CFG_VERSION:
 
1781
                if ( c->value_int != 0 && ( c->value_int < LDAP_VERSION_MIN || c->value_int > LDAP_VERSION_MAX ) ) {
 
1782
                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
1783
                                "unsupported version \"%s\" "
 
1784
                                "in \"protocol-version <version>\"",
 
1785
                                c->argv[ 1 ] );
 
1786
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1787
                        return 1;
 
1788
                }
 
1789
 
 
1790
                li->li_version = c->value_int;
 
1791
                break;
 
1792
 
 
1793
        case LDAP_BACK_CFG_SINGLECONN:
 
1794
                if ( c->value_int ) {
 
1795
                        li->li_flags |= LDAP_BACK_F_SINGLECONN;
 
1796
 
 
1797
                } else {
 
1798
                        li->li_flags &= ~LDAP_BACK_F_SINGLECONN;
 
1799
                }
 
1800
                break;
 
1801
 
 
1802
        case LDAP_BACK_CFG_USETEMP:
 
1803
                if ( c->value_int ) {
 
1804
                        li->li_flags |= LDAP_BACK_F_USE_TEMPORARIES;
 
1805
 
 
1806
                } else {
 
1807
                        li->li_flags &= ~LDAP_BACK_F_USE_TEMPORARIES;
 
1808
                }
 
1809
                break;
 
1810
 
 
1811
        case LDAP_BACK_CFG_CONNPOOLMAX:
 
1812
                if ( c->value_int < LDAP_BACK_CONN_PRIV_MIN
 
1813
                        || c->value_int > LDAP_BACK_CONN_PRIV_MAX )
 
1814
                {
 
1815
                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
1816
                                "invalid max size " "of privileged "
 
1817
                                "connections pool \"%s\" "
 
1818
                                "in \"conn-pool-max <n> "
 
1819
                                "(must be between %d and %d)\"",
 
1820
                                c->argv[ 1 ],
 
1821
                                LDAP_BACK_CONN_PRIV_MIN,
 
1822
                                LDAP_BACK_CONN_PRIV_MAX );
 
1823
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1824
                        return 1;
 
1825
                }
 
1826
                li->li_conn_priv_max = c->value_int;
 
1827
                break;
 
1828
 
 
1829
        case LDAP_BACK_CFG_CANCEL: {
 
1830
                slap_mask_t             mask;
 
1831
 
 
1832
                i = verb_to_mask( c->argv[1], cancel_mode );
 
1833
                if ( BER_BVISNULL( &cancel_mode[i].word ) ) {
 
1834
                        return 1;
 
1835
                }
 
1836
 
 
1837
                mask = cancel_mode[i].mask;
 
1838
 
 
1839
                if ( LDAP_BACK_ISOPEN( li )
 
1840
                        && mask == LDAP_BACK_F_CANCEL_EXOP_DISCOVER
 
1841
                        && !LDAP_BACK_CANCEL( li ) )
 
1842
                {
 
1843
                        slap_bindconf   sb = { BER_BVNULL };
 
1844
                        int             rc;
 
1845
 
 
1846
                        if ( li->li_uri == NULL ) {
 
1847
                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
1848
                                        "need URI to discover \"cancel\" support "
 
1849
                                        "in \"cancel exop-discover\"" );
 
1850
                                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1851
                                return 1;
 
1852
                        }
 
1853
 
 
1854
                        ber_str2bv( li->li_uri, 0, 0, &sb.sb_uri );
 
1855
                        sb.sb_version = li->li_version;
 
1856
                        sb.sb_method = LDAP_AUTH_SIMPLE;
 
1857
                        BER_BVSTR( &sb.sb_binddn, "" );
 
1858
 
 
1859
                        rc = slap_discover_feature( &sb,
 
1860
                                        slap_schema.si_ad_supportedExtension->ad_cname.bv_val,
 
1861
                                        LDAP_EXOP_CANCEL );
 
1862
                        if ( rc == LDAP_COMPARE_TRUE ) {
 
1863
                                mask |= LDAP_BACK_F_CANCEL_EXOP;
 
1864
                        }
 
1865
                }
 
1866
 
 
1867
                li->li_flags &= ~LDAP_BACK_F_CANCEL_MASK2;
 
1868
                li->li_flags |= mask;
 
1869
                } break;
 
1870
 
 
1871
        case LDAP_BACK_CFG_QUARANTINE:
 
1872
                if ( LDAP_BACK_QUARANTINE( li ) ) {
 
1873
                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
1874
                                "quarantine already defined" );
 
1875
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1876
                        return 1;
 
1877
                }
 
1878
                rc = slap_retry_info_parse( c->argv[1], &li->li_quarantine,
 
1879
                        c->cr_msg, sizeof( c->cr_msg ) );
 
1880
                if ( rc ) {
 
1881
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1882
 
 
1883
                } else {
 
1884
                        ldap_pvt_thread_mutex_init( &li->li_quarantine_mutex );
 
1885
                        /* give it a chance to retry if the pattern gets reset
 
1886
                         * via back-config */
 
1887
                        li->li_isquarantined = 0;
 
1888
                        li->li_flags |= LDAP_BACK_F_QUARANTINE;
 
1889
                }
 
1890
                break;
 
1891
 
 
1892
#ifdef SLAP_CONTROL_X_SESSION_TRACKING
 
1893
        case LDAP_BACK_CFG_ST_REQUEST:
 
1894
                if ( c->value_int ) {
 
1895
                        li->li_flags |= LDAP_BACK_F_ST_REQUEST;
 
1896
 
 
1897
                } else {
 
1898
                        li->li_flags &= ~LDAP_BACK_F_ST_REQUEST;
 
1899
                }
 
1900
                break;
 
1901
#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
 
1902
 
 
1903
        case LDAP_BACK_CFG_REWRITE:
 
1904
                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
1905
                        "rewrite/remap capabilities have been moved "
 
1906
                        "to the \"rwm\" overlay; see slapo-rwm(5) "
 
1907
                        "for details (hint: add \"overlay rwm\" "
 
1908
                        "and prefix all directives with \"rwm-\")" );
 
1909
                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
1910
                return 1;
 
1911
                
 
1912
        default:
 
1913
                /* FIXME: try to catch inconsistencies */
 
1914
                assert( 0 );
 
1915
                break;
 
1916
        }
 
1917
 
 
1918
        return rc;
 
1919
}
 
1920
 
 
1921
int
 
1922
ldap_back_init_cf( BackendInfo *bi )
 
1923
{
 
1924
        int                     rc;
 
1925
        AttributeDescription    *ad = NULL;
 
1926
        const char              *text;
 
1927
 
 
1928
        /* Make sure we don't exceed the bits reserved for userland */
 
1929
        config_check_userland( LDAP_BACK_CFG_LAST );
 
1930
 
 
1931
        bi->bi_cf_ocs = ldapocs;
 
1932
 
 
1933
        rc = config_register_schema( ldapcfg, ldapocs );
 
1934
        if ( rc ) {
 
1935
                return rc;
 
1936
        }
 
1937
 
 
1938
        /* setup olcDbAclPasswd and olcDbIDAssertPasswd 
 
1939
         * to be base64-encoded when written in LDIF form;
 
1940
         * basically, we don't care if it fails */
 
1941
        rc = slap_str2ad( "olcDbACLPasswd", &ad, &text );
 
1942
        if ( rc ) {
 
1943
                Debug( LDAP_DEBUG_ANY, "config_back_initialize: "
 
1944
                        "warning, unable to get \"olcDbACLPasswd\" "
 
1945
                        "attribute description: %d: %s\n",
 
1946
                        rc, text, 0 );
 
1947
        } else {
 
1948
                (void)ldif_must_b64_encode_register( ad->ad_cname.bv_val,
 
1949
                        ad->ad_type->sat_oid );
 
1950
        }
 
1951
 
 
1952
        ad = NULL;
 
1953
        rc = slap_str2ad( "olcDbIDAssertPasswd", &ad, &text );
 
1954
        if ( rc ) {
 
1955
                Debug( LDAP_DEBUG_ANY, "config_back_initialize: "
 
1956
                        "warning, unable to get \"olcDbIDAssertPasswd\" "
 
1957
                        "attribute description: %d: %s\n",
 
1958
                        rc, text, 0 );
 
1959
        } else {
 
1960
                (void)ldif_must_b64_encode_register( ad->ad_cname.bv_val,
 
1961
                        ad->ad_type->sat_oid );
 
1962
        }
 
1963
 
 
1964
        return 0;
 
1965
}
 
1966
 
 
1967
 
 
1968
static int
 
1969
ldap_back_exop_whoami(
 
1970
                Operation       *op,
 
1971
                SlapReply       *rs )
 
1972
{
 
1973
        struct berval *bv = NULL;
 
1974
 
 
1975
        if ( op->oq_extended.rs_reqdata != NULL ) {
 
1976
                /* no request data should be provided */
 
1977
                rs->sr_text = "no request data expected";
 
1978
                return rs->sr_err = LDAP_PROTOCOL_ERROR;
 
1979
        }
 
1980
 
 
1981
        Statslog( LDAP_DEBUG_STATS, "%s WHOAMI\n",
 
1982
            op->o_log_prefix, 0, 0, 0, 0 );
 
1983
 
 
1984
        rs->sr_err = backend_check_restrictions( op, rs, 
 
1985
                        (struct berval *)&slap_EXOP_WHOAMI );
 
1986
        if( rs->sr_err != LDAP_SUCCESS ) return rs->sr_err;
 
1987
 
 
1988
        /* if auth'd by back-ldap and request is proxied, forward it */
 
1989
        if ( op->o_conn->c_authz_backend
 
1990
                && !strcmp( op->o_conn->c_authz_backend->be_type, "ldap" )
 
1991
                && !dn_match( &op->o_ndn, &op->o_conn->c_ndn ) )
 
1992
        {
 
1993
                ldapconn_t      *lc = NULL;
 
1994
                LDAPControl c, *ctrls[2] = {NULL, NULL};
 
1995
                LDAPMessage *res;
 
1996
                Operation op2 = *op;
 
1997
                ber_int_t msgid;
 
1998
                int doretry = 1;
 
1999
                char *ptr;
 
2000
 
 
2001
                ctrls[0] = &c;
 
2002
                op2.o_ndn = op->o_conn->c_ndn;
 
2003
                if ( !ldap_back_dobind( &lc, &op2, rs, LDAP_BACK_SENDERR ) ) {
 
2004
                        return -1;
 
2005
                }
 
2006
                c.ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
 
2007
                c.ldctl_iscritical = 1;
 
2008
                c.ldctl_value.bv_val = op->o_tmpalloc(
 
2009
                        op->o_ndn.bv_len + STRLENOF( "dn:" ) + 1,
 
2010
                        op->o_tmpmemctx );
 
2011
                c.ldctl_value.bv_len = op->o_ndn.bv_len + 3;
 
2012
                ptr = c.ldctl_value.bv_val;
 
2013
                ptr = lutil_strcopy( ptr, "dn:" );
 
2014
                ptr = lutil_strncopy( ptr, op->o_ndn.bv_val, op->o_ndn.bv_len );
 
2015
                ptr[ 0 ] = '\0';
 
2016
 
 
2017
retry:
 
2018
                rs->sr_err = ldap_whoami( lc->lc_ld, ctrls, NULL, &msgid );
 
2019
                if ( rs->sr_err == LDAP_SUCCESS ) {
 
2020
                        if ( ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, NULL, &res ) == -1 ) {
 
2021
                                ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER,
 
2022
                                        &rs->sr_err );
 
2023
                                if ( rs->sr_err == LDAP_SERVER_DOWN && doretry ) {
 
2024
                                        doretry = 0;
 
2025
                                        if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
 
2026
                                                goto retry;
 
2027
                                        }
 
2028
                                }
 
2029
 
 
2030
                        } else {
 
2031
                                /* NOTE: are we sure "bv" will be malloc'ed
 
2032
                                 * with the appropriate memory? */
 
2033
                                rs->sr_err = ldap_parse_whoami( lc->lc_ld, res, &bv );
 
2034
                                ldap_msgfree(res);
 
2035
                        }
 
2036
                }
 
2037
                op->o_tmpfree( c.ldctl_value.bv_val, op->o_tmpmemctx );
 
2038
                if ( rs->sr_err != LDAP_SUCCESS ) {
 
2039
                        rs->sr_err = slap_map_api2result( rs );
 
2040
                }
 
2041
 
 
2042
                if ( lc != NULL ) {
 
2043
                        ldap_back_release_conn( (ldapinfo_t *)op2.o_bd->be_private, lc );
 
2044
                }
 
2045
 
 
2046
        } else {
 
2047
                /* else just do the same as before */
 
2048
                bv = (struct berval *) ch_malloc( sizeof( struct berval ) );
 
2049
                if ( !BER_BVISEMPTY( &op->o_dn ) ) {
 
2050
                        bv->bv_len = op->o_dn.bv_len + STRLENOF( "dn:" );
 
2051
                        bv->bv_val = ch_malloc( bv->bv_len + 1 );
 
2052
                        AC_MEMCPY( bv->bv_val, "dn:", STRLENOF( "dn:" ) );
 
2053
                        AC_MEMCPY( &bv->bv_val[ STRLENOF( "dn:" ) ], op->o_dn.bv_val,
 
2054
                                op->o_dn.bv_len );
 
2055
                        bv->bv_val[ bv->bv_len ] = '\0';
 
2056
 
 
2057
                } else {
 
2058
                        bv->bv_len = 0;
 
2059
                        bv->bv_val = NULL;
 
2060
                }
 
2061
        }
 
2062
 
 
2063
        rs->sr_rspdata = bv;
 
2064
        return rs->sr_err;
 
2065
}
 
2066
 
 
2067