]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldap/config.c
streamline back-ldap/slapo-chain configuration; add the possibility to cache non...
[openldap] / servers / slapd / back-ldap / config.c
1 /* config.c - ldap backend configuration file routine */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2003-2005 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_REWRITE
64 };
65
66 static ConfigTable ldapcfg[] = {
67         { "uri", "uri", 2, 2, 0,
68                 ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_URI,
69                 ldap_back_cf_gen, "( OLcfgDbAt:0.14 "
70                         "NAME 'olcDbURI' "
71                         "DESC 'URI (list) for remote DSA' "
72                         "SYNTAX OMsDirectoryString "
73                         "SINGLE-VALUE )",
74                 NULL, NULL },
75         { "tls", "what", 2, 2, 0,
76                 ARG_MAGIC|LDAP_BACK_CFG_TLS,
77                 ldap_back_cf_gen, "( OLcfgDbAt:3.1 "
78                         "NAME 'olcDbStartTLS' "
79                         "DESC 'StartTLS' "
80                         "SYNTAX OMsDirectoryString "
81                         "SINGLE-VALUE )",
82                 NULL, NULL },
83         { "acl-authcDN", "DN", 2, 2, 0,
84                 ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_ACL_AUTHCDN,
85                 ldap_back_cf_gen, "( OLcfgDbAt:3.2 "
86                         "NAME 'olcDbACLAuthcDn' "
87                         "DESC 'Remote ACL administrative identity' "
88                         "OBSOLETE "
89                         "SYNTAX OMsDN "
90                         "SINGLE-VALUE )",
91                 NULL, NULL },
92         /* deprecated, will be removed; aliases "acl-authcDN" */
93         { "binddn", "DN", 2, 2, 0,
94                 ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_ACL_AUTHCDN,
95                 ldap_back_cf_gen, NULL, NULL, NULL },
96         { "acl-passwd", "cred", 2, 2, 0,
97                 ARG_MAGIC|LDAP_BACK_CFG_ACL_PASSWD,
98                 ldap_back_cf_gen, "( OLcfgDbAt:3.3 "
99                         "NAME 'olcDbACLPasswd' "
100                         "DESC 'Remote ACL administrative identity credentials' "
101                         "OBSOLETE "
102                         "SYNTAX OMsDirectoryString "
103                         "SINGLE-VALUE )",
104                 NULL, NULL },
105         /* deprecated, will be removed; aliases "acl-passwd" */
106         { "bindpw", "cred", 2, 2, 0,
107                 ARG_MAGIC|LDAP_BACK_CFG_ACL_PASSWD,
108                 ldap_back_cf_gen, NULL, NULL, NULL },
109         /* deprecated, will be removed; aliases "acl-bind" */
110         { "acl-method", "args", 2, 0, 0,
111                 ARG_MAGIC|LDAP_BACK_CFG_ACL_METHOD,
112                 ldap_back_cf_gen, NULL, NULL, NULL },
113         { "acl-bind", "args", 2, 0, 0,
114                 ARG_MAGIC|LDAP_BACK_CFG_ACL_BIND,
115                 ldap_back_cf_gen, "( OLcfgDbAt:3.4 "
116                         "NAME 'olcDbACLBind' "
117                         "DESC 'Remote ACL administrative identity auth bind configuration' "
118                         "SYNTAX OMsDirectoryString "
119                         "SINGLE-VALUE )",
120                 NULL, NULL },
121         { "idassert-authcDN", "DN", 2, 2, 0,
122                 ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_AUTHCDN,
123                 ldap_back_cf_gen, "( OLcfgDbAt:3.5 "
124                         "NAME 'olcDbIDAssertAuthcDn' "
125                         "DESC 'Remote Identity Assertion administrative identity' "
126                         "OBSOLETE "
127                         "SYNTAX OMsDN "
128                         "SINGLE-VALUE )",
129                 NULL, NULL },
130         /* deprecated, will be removed; partially aliases "idassert-authcDN" */
131         { "proxyauthzdn", "DN", 2, 2, 0,
132                 ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_AUTHCDN,
133                 ldap_back_cf_gen, NULL, NULL, NULL },
134         { "idassert-passwd", "cred", 2, 2, 0,
135                 ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_PASSWD,
136                 ldap_back_cf_gen, "( OLcfgDbAt:3.6 "
137                         "NAME 'olcDbIDAssertPasswd' "
138                         "DESC 'Remote Identity Assertion administrative identity credentials' "
139                         "OBSOLETE "
140                         "SYNTAX OMsDirectoryString "
141                         "SINGLE-VALUE )",
142                 NULL, NULL },
143         /* deprecated, will be removed; partially aliases "idassert-passwd" */
144         { "proxyauthzpw", "cred", 2, 2, 0,
145                 ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_PASSWD,
146                 ldap_back_cf_gen, NULL, NULL, NULL },
147         { "idassert-bind", "args", 2, 0, 0,
148                 ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_BIND,
149                 ldap_back_cf_gen, "( OLcfgDbAt:3.7 "
150                         "NAME 'olcDbIDAssertBind' "
151                         "DESC 'Remote Identity Assertion administrative identity auth bind configuration' "
152                         "SYNTAX OMsDirectoryString "
153                         "SINGLE-VALUE )",
154                 NULL, NULL },
155         { "idassert-method", "args", 2, 0, 0,
156                 ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_METHOD,
157                 ldap_back_cf_gen, NULL, NULL, NULL },
158         { "idassert-mode", "mode>|u:<user>|[dn:]<DN", 2, 0, 0,
159                 ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_MODE,
160                 ldap_back_cf_gen, "( OLcfgDbAt:3.8 "
161                         "NAME 'olcDbIDAssertMode' "
162                         "DESC 'Remote Identity Assertion mode' "
163                         "OBSOLETE "
164                         "SYNTAX OMsDirectoryString "
165                         "SINGLE-VALUE)",
166                 NULL, NULL },
167         { "idassert-authzFrom", "authzRule", 2, 2, 0,
168                 ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_AUTHZFROM,
169                 ldap_back_cf_gen, "( OLcfgDbAt:3.9 "
170                         "NAME 'olcDbIDAssertAuthzFrom' "
171                         "DESC 'Remote Identity Assertion authz rules' "
172                         "SYNTAX OMsDirectoryString "
173                         "X-ORDERED 'VALUES' )",
174                 NULL, NULL },
175         { "rebind-as-user", "NO|yes", 1, 2, 0,
176                 ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_REBIND,
177                 ldap_back_cf_gen, "( OLcfgDbAt:3.10 "
178                         "NAME 'olcDbRebindAsUser' "
179                         "DESC 'Rebind as user' "
180                         "SYNTAX OMsBoolean "
181                         "SINGLE-VALUE )",
182                 NULL, NULL },
183         { "chase-referrals", "YES|no", 2, 2, 0,
184                 ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_CHASE,
185                 ldap_back_cf_gen, "( OLcfgDbAt:3.11 "
186                         "NAME 'olcDbChaseReferrals' "
187                         "DESC 'Chase referrals' "
188                         "SYNTAX OMsBoolean "
189                         "SINGLE-VALUE )",
190                 NULL, NULL },
191         { "t-f-support", "NO|yes|discover", 2, 2, 0,
192                 ARG_MAGIC|LDAP_BACK_CFG_T_F,
193                 ldap_back_cf_gen, "( OLcfgDbAt:3.12 "
194                         "NAME 'olcDbTFSupport' "
195                         "DESC 'Absolute filters support' "
196                         "SYNTAX OMsDirectoryString "
197                         "SINGLE-VALUE )",
198                 NULL, NULL },
199         { "proxy-whoami", "NO|yes", 1, 2, 0,
200                 ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_WHOAMI,
201                 ldap_back_cf_gen, "( OLcfgDbAt:3.13 "
202                         "NAME 'olcDbProxyWhoAmI' "
203                         "DESC 'Proxy whoAmI exop' "
204                         "SYNTAX OMsBoolean "
205                         "SINGLE-VALUE )",
206                 NULL, NULL },
207         { "timeout", "timeout", 0, 2, 0,
208                 ARG_MAGIC|LDAP_BACK_CFG_TIMEOUT,
209                 ldap_back_cf_gen, "( OLcfgDbAt:3.14 "
210                         "NAME 'olcDbTimeout' "
211                         "DESC 'Per-operation timeouts' "
212                         "SYNTAX OMsDirectoryString "
213                         "SINGLE-VALUE )",
214                 NULL, NULL },
215         { "suffixmassage", "[virtual]> <real", 2, 3, 0,
216                 ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
217                 ldap_back_cf_gen, NULL, NULL, NULL },
218         { "map", "attribute|objectClass> [*|<local>] *|<remote", 3, 4, 0,
219                 ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
220                 ldap_back_cf_gen, NULL, NULL, NULL },
221         { "rewrite", "<arglist>", 2, 4, STRLENOF( "rewrite" ),
222                 ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
223                 ldap_back_cf_gen, NULL, NULL, NULL },
224         { NULL, NULL, 0, 0, 0, ARG_IGNORED,
225                 NULL, NULL, NULL, NULL }
226 };
227
228 static ConfigOCs ldapocs[] = {
229         { "( OLcfgDbOc:3.1 "
230                 "NAME 'olcLDAPConfig' "
231                 "DESC 'LDAP backend configuration' "
232                 "SUP olcDatabaseConfig "
233                 "MUST olcDbURI "
234                 "MAY ( olcDbStartTLS "
235                         "$ olcDbACLAuthcDn "
236                         "$ olcDbACLPasswd "
237                         "$ olcDbACLBind "
238                         "$ olcDbIDAssertAuthcDn "
239                         "$ olcDbIDAssertPasswd "
240                         "$ olcDbIDAssertBind "
241                         "$ olcDbIDAssertMode "
242                         "$ olcDbIDAssertAuthzFrom "
243                         "$ olcDbRebindAsUser "
244                         "$ olcDbChaseReferrals "
245                         "$ olcDbTFSupport "
246                         "$ olcDbProxyWhoAmI "
247                         "$ olcDbTimeout "
248                 ") )",
249                         Cft_Database, ldapcfg},
250         { NULL, 0, NULL }
251 };
252
253 static slap_verbmasks idassert_mode[] = {
254         { BER_BVC("self"),              LDAP_BACK_IDASSERT_SELF },
255         { BER_BVC("anonymous"),         LDAP_BACK_IDASSERT_ANONYMOUS },
256         { BER_BVC("none"),              LDAP_BACK_IDASSERT_NOASSERT },
257         { BER_BVC("legacy"),            LDAP_BACK_IDASSERT_LEGACY },
258         { BER_BVNULL,                   0 }
259 };
260
261 static slap_verbmasks tls_mode[] = {
262         { BER_BVC( "propagate" ),       LDAP_BACK_F_TLS_PROPAGATE_MASK },
263         { BER_BVC( "try-propagate" ),   LDAP_BACK_F_PROPAGATE_TLS },
264         { BER_BVC( "start" ),           LDAP_BACK_F_TLS_USE_MASK },
265         { BER_BVC( "try-start" ),       LDAP_BACK_F_USE_TLS },
266         { BER_BVC( "none" ),            LDAP_BACK_F_NONE },
267         { BER_BVNULL,                   0 }
268 };
269
270 static slap_verbmasks t_f_mode[] = {
271         { BER_BVC( "yes" ),             LDAP_BACK_F_SUPPORT_T_F },
272         { BER_BVC( "discover" ),        LDAP_BACK_F_SUPPORT_T_F_DISCOVER },
273         { BER_BVC( "no" ),              LDAP_BACK_F_NONE },
274         { BER_BVNULL,                   0 }
275 };
276
277 static slap_cf_aux_table timeout_table[] = {
278         { BER_BVC("add="), 0 * sizeof( time_t ), 'u', 0, NULL },
279         { BER_BVC("delete="), 1 * sizeof( time_t ), 'u', 0, NULL },
280         { BER_BVC("modify="), 2 * sizeof( time_t ), 'u', 0, NULL },
281         { BER_BVC("modrdn="), 3 * sizeof( time_t ), 'u', 0, NULL },
282         { BER_BVNULL, 0, 0, 0, NULL }
283 };
284
285 static int
286 ldap_back_cf_gen( ConfigArgs *c )
287 {
288         ldapinfo_t      *li = ( ldapinfo_t * )c->be->be_private;
289         int             rc;
290         int             i;
291
292         if ( c->op == SLAP_CONFIG_EMIT ) {
293                 struct berval   bv = BER_BVNULL;
294                 rc = 0;
295
296                 switch( c->type ) {
297                 case LDAP_BACK_CFG_URI:
298                         if ( li->li_uri != NULL ) {
299                                 c->value_string = ch_strdup( li->li_uri );
300
301                         } else {
302                                 rc = 1;
303                         }
304                         break;
305
306                 case LDAP_BACK_CFG_TLS:
307                         enum_to_verb( tls_mode, ( li->li_flags & LDAP_BACK_F_TLS_MASK ), &bv );
308                         if ( BER_BVISNULL( &bv ) ) {
309                                 /* there's something wrong... */
310                                 assert( 0 );
311                                 rc = 1;
312
313                         } else {
314                                 value_add_one( &c->rvalue_vals, &bv );
315                         }
316                         break;
317
318                 case LDAP_BACK_CFG_ACL_AUTHCDN:
319                 case LDAP_BACK_CFG_ACL_PASSWD:
320                 case LDAP_BACK_CFG_ACL_METHOD:
321                         /* handled by LDAP_BACK_CFG_ACL_BIND */
322                         rc = 1;
323                         break;
324
325                 case LDAP_BACK_CFG_ACL_BIND: {
326                         int     i;
327
328                         bindconf_unparse( &li->li_acl, &bv );
329
330                         for ( i = 0; isspace( bv.bv_val[ i ] ); i++ )
331                                 /* count spaces */ ;
332
333                         if ( i ) {
334                                 bv.bv_len -= i;
335                                 AC_MEMCPY( bv.bv_val, &bv.bv_val[ i ],
336                                         bv.bv_len + 1 );
337                         }
338
339                         ber_bvarray_add( &c->rvalue_vals, &bv );
340                         break;
341                 }
342
343                 case LDAP_BACK_CFG_IDASSERT_MODE:
344                 case LDAP_BACK_CFG_IDASSERT_AUTHCDN:
345                 case LDAP_BACK_CFG_IDASSERT_PASSWD:
346                 case LDAP_BACK_CFG_IDASSERT_METHOD:
347                         /* handled by LDAP_BACK_CFG_IDASSERT_BIND */
348                         rc = 1;
349                         break;
350
351                 case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: {
352                         int             i;
353
354                         if ( li->li_idassert_authz == NULL ) {
355                                 rc = 1;
356                                 break;
357                         }
358
359                         for ( i = 0; !BER_BVISNULL( &li->li_idassert_authz[ i ] ); i++ )
360                         {
361                                 value_add_one( &c->rvalue_vals, &li->li_idassert_authz[ i ] );
362                         }
363                         break;
364                 }
365
366                 case LDAP_BACK_CFG_IDASSERT_BIND: {
367                         int             i;
368                         struct berval   bc = BER_BVNULL;
369                         char            *ptr;
370
371                         if ( li->li_idassert_authmethod != LDAP_AUTH_NONE ) {
372                                 ber_len_t       len;
373
374                                 switch ( li->li_idassert_mode ) {
375                                 case LDAP_BACK_IDASSERT_OTHERID:
376                                 case LDAP_BACK_IDASSERT_OTHERDN:
377                                         break;
378
379                                 default: {
380                                         struct berval   mode = BER_BVNULL;
381
382                                         enum_to_verb( idassert_mode, li->li_idassert_mode, &mode );
383                                         if ( BER_BVISNULL( &mode ) ) {
384                                                 /* there's something wrong... */
385                                                 assert( 0 );
386                                                 rc = 1;
387         
388                                         } else {
389                                                 bv.bv_len = STRLENOF( "mode=" ) + mode.bv_len;
390                                                 bv.bv_val = ch_malloc( bv.bv_len + 1 );
391
392                                                 ptr = lutil_strcopy( bv.bv_val, "mode=" );
393                                                 ptr = lutil_strcopy( ptr, mode.bv_val );
394                                         }
395                                         break;
396                                 }
397                                 }
398
399                                 if ( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) {
400                                         len = bv.bv_len + STRLENOF( "authz=native" );
401
402                                         if ( !BER_BVISEMPTY( &bv ) ) {
403                                                 len += STRLENOF( " " );
404                                         }
405
406                                         bv.bv_val = ch_realloc( bv.bv_val, len + 1 );
407
408                                         ptr = &bv.bv_val[ bv.bv_len ];
409
410                                         if ( !BER_BVISEMPTY( &bv ) ) {
411                                                 ptr = lutil_strcopy( ptr, " " );
412                                         }
413
414                                         (void)lutil_strcopy( ptr, "authz=native" );
415                                 }
416
417                                 len = bv.bv_len + STRLENOF( "flags=non-prescriptive,override" );
418                                 /* flags */
419                                 if ( !BER_BVISEMPTY( &bv ) ) {
420                                         len += STRLENOF( " " );
421                                 }
422
423                                 bv.bv_val = ch_realloc( bv.bv_val, len + 1 );
424
425                                 ptr = &bv.bv_val[ bv.bv_len ];
426
427                                 if ( !BER_BVISEMPTY( &bv ) ) {
428                                         ptr = lutil_strcopy( ptr, " " );
429                                 }
430
431                                 ptr = lutil_strcopy( ptr, "flags=" );
432
433                                 if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
434                                         ptr = lutil_strcopy( ptr, "prescriptive" );
435                                 } else {
436                                         ptr = lutil_strcopy( ptr, "non-prescriptive" );
437                                 }
438
439                                 if ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) {
440                                         ptr = lutil_strcopy( ptr, ",override" );
441                                 }
442
443                                 bv.bv_len = ( ptr - bv.bv_val );
444                                 /* end-of-flags */
445                         }
446
447                         bindconf_unparse( &li->li_idassert, &bc );
448
449                         if ( !BER_BVISNULL( &bv ) ) {
450                                 ber_len_t       len = bv.bv_len + bc.bv_len;
451
452                                 bv.bv_val = ch_realloc( bv.bv_val, len + 1 );
453
454                                 assert( bc.bv_val[ 0 ] == ' ' );
455
456                                 ptr = lutil_strcopy( &bv.bv_val[ bv.bv_len ], bc.bv_val );
457                                 free( bc.bv_val );
458                                 bv.bv_len = ptr - bv.bv_val;
459
460                         } else {
461                                 for ( i = 0; isspace( bc.bv_val[ i ] ); i++ )
462                                         /* count spaces */ ;
463
464                                 if ( i ) {
465                                         bc.bv_len -= i;
466                                         AC_MEMCPY( bc.bv_val, &bc.bv_val[ i ], bc.bv_len + 1 );
467                                 }
468
469                                 bv = bc;
470                         }
471                         
472                         ber_bvarray_add( &c->rvalue_vals, &bv );
473
474                         break;
475                 }
476
477                 case LDAP_BACK_CFG_REBIND:
478                         c->value_int = LDAP_BACK_SAVECRED( li );
479                         break;
480
481                 case LDAP_BACK_CFG_CHASE:
482                         c->value_int = LDAP_BACK_CHASE_REFERRALS( li );
483                         break;
484
485                 case LDAP_BACK_CFG_T_F:
486                         enum_to_verb( t_f_mode, (li->li_flags & LDAP_BACK_F_SUPPORT_T_F_MASK), &bv );
487                         if ( BER_BVISNULL( &bv ) ) {
488                                 /* there's something wrong... */
489                                 assert( 0 );
490                                 rc = 1;
491
492                         } else {
493                                 value_add_one( &c->rvalue_vals, &bv );
494                         }
495                         break;
496
497                 case LDAP_BACK_CFG_WHOAMI:
498                         c->value_int = LDAP_BACK_PROXY_WHOAMI( li );
499                         break;
500
501                 case LDAP_BACK_CFG_TIMEOUT:
502                         BER_BVZERO( &bv );
503
504                         slap_cf_aux_table_unparse( li->li_timeout, &bv, timeout_table );
505
506                         if ( !BER_BVISNULL( &bv ) ) {   
507                                 for ( i = 0; isspace( bv.bv_val[ i ] ); i++ )
508                                         /* count spaces */ ;
509
510                                 if ( i ) {
511                                         bv.bv_len -= i;
512                                         AC_MEMCPY( bv.bv_val, &bv.bv_val[ i ],
513                                                 bv.bv_len + 1 );
514                                 }
515
516                                 ber_bvarray_add( &c->rvalue_vals, &bv );
517                         }
518                         break;
519
520                 default:
521                         /* FIXME: we need to handle all... */
522                         assert( 0 );
523                         break;
524                 }
525                 return rc;
526
527         } else if ( c->op == LDAP_MOD_DELETE ) {
528                 rc = 0;
529                 switch( c->type ) {
530                 case LDAP_BACK_CFG_URI:
531                         if ( li->li_uri != NULL ) {
532                                 ch_free( li->li_uri );
533                                 li->li_uri = NULL;
534
535                                 assert( li->li_bvuri != NULL );
536                                 ber_bvarray_free( li->li_bvuri );
537                                 li->li_bvuri = NULL;
538                         }
539
540                         /* better cleanup the cached connections... */
541                         /* NOTE: don't worry about locking: if we got here,
542                          * other threads are suspended. */
543                         if ( li->li_conninfo.lai_tree != NULL ) {
544                                 avl_free( li->li_conninfo.lai_tree, ldap_back_conn_free );
545                                 li->li_conninfo.lai_tree = NULL;
546                         }
547                         
548                         break;
549
550                 case LDAP_BACK_CFG_TLS:
551                         rc = 1;
552                         break;
553
554                 case LDAP_BACK_CFG_ACL_AUTHCDN:
555                 case LDAP_BACK_CFG_ACL_PASSWD:
556                 case LDAP_BACK_CFG_ACL_METHOD:
557                         /* handled by LDAP_BACK_CFG_ACL_BIND */
558                         rc = 1;
559                         break;
560
561                 case LDAP_BACK_CFG_ACL_BIND:
562                         bindconf_free( &li->li_acl );
563                         break;
564
565                 case LDAP_BACK_CFG_IDASSERT_MODE:
566                 case LDAP_BACK_CFG_IDASSERT_AUTHCDN:
567                 case LDAP_BACK_CFG_IDASSERT_PASSWD:
568                 case LDAP_BACK_CFG_IDASSERT_METHOD:
569                         /* handled by LDAP_BACK_CFG_IDASSERT_BIND */
570                         rc = 1;
571                         break;
572
573                 case LDAP_BACK_CFG_IDASSERT_AUTHZFROM:
574                         if ( li->li_idassert_authz != NULL ) {
575                                 ber_bvarray_free( li->li_idassert_authz );
576                                 li->li_idassert_authz = NULL;
577                         }
578                         break;
579
580                 case LDAP_BACK_CFG_IDASSERT_BIND:
581                         bindconf_free( &li->li_idassert );
582                         break;
583
584                 case LDAP_BACK_CFG_REBIND:
585                 case LDAP_BACK_CFG_CHASE:
586                 case LDAP_BACK_CFG_T_F:
587                 case LDAP_BACK_CFG_WHOAMI:
588                         rc = 1;
589                         break;
590
591                 case LDAP_BACK_CFG_TIMEOUT:
592                         for ( i = 0; i < LDAP_BACK_OP_LAST; i++ ) {
593                                 li->li_timeout[ i ] = 0;
594                         }
595                         break;
596
597                 default:
598                         /* FIXME: we need to handle all... */
599                         assert( 0 );
600                         break;
601                 }
602                 return rc;
603
604         }
605
606         switch( c->type ) {
607         case LDAP_BACK_CFG_URI: {
608                 LDAPURLDesc     *tmpludp, *lud;
609                 char            **urllist = NULL;
610                 int             urlrc = LDAP_URL_SUCCESS, i;
611
612                 if ( c->argc != 2 ) {
613                         fprintf( stderr, "%s: line %d: "
614                                         "missing uri "
615                                         "in \"uri <uri>\" line\n",
616                                         c->fname, c->lineno );
617                         return 1;
618                 }
619
620                 if ( li->li_uri != NULL ) {
621                         ch_free( li->li_uri );
622                         li->li_uri = NULL;
623
624                         assert( li->li_bvuri != NULL );
625                         ber_bvarray_free( li->li_bvuri );
626                         li->li_bvuri = NULL;
627                 }
628
629                 /* PARANOID: DN and more are not required nor allowed */
630                 urlrc = ldap_url_parselist_ext( &lud, c->value_string, ", \t" );
631                 if ( urlrc != LDAP_URL_SUCCESS ) {
632                         char    *why;
633
634                         switch ( urlrc ) {
635                         case LDAP_URL_ERR_MEM:
636                                 why = "no memory";
637                                 break;
638                         case LDAP_URL_ERR_PARAM:
639                                 why = "parameter is bad";
640                                 break;
641                         case LDAP_URL_ERR_BADSCHEME:
642                                 why = "URL doesn't begin with \"[c]ldap[si]://\"";
643                                 break;
644                         case LDAP_URL_ERR_BADENCLOSURE:
645                                 why = "URL is missing trailing \">\"";
646                                 break;
647                         case LDAP_URL_ERR_BADURL:
648                                 why = "URL is bad";
649                                 break;
650                         case LDAP_URL_ERR_BADHOST:
651                                 why = "host/port is bad";
652                                 break;
653                         case LDAP_URL_ERR_BADATTRS:
654                                 why = "bad (or missing) attributes";
655                                 break;
656                         case LDAP_URL_ERR_BADSCOPE:
657                                 why = "scope string is invalid (or missing)";
658                                 break;
659                         case LDAP_URL_ERR_BADFILTER:
660                                 why = "bad or missing filter";
661                                 break;
662                         case LDAP_URL_ERR_BADEXTS:
663                                 why = "bad or missing extensions";
664                                 break;
665                         default:
666                                 why = "unknown reason";
667                                 break;
668                         }
669                         fprintf( stderr, "%s: line %d: "
670                                         "unable to parse uri \"%s\" "
671                                         "in \"uri <uri>\" line: %s\n",
672                                         c->fname, c->lineno, c->value_string, why );
673                         urlrc = 1;
674                         goto done_url;
675                 }
676
677                 for ( i = 0, tmpludp = lud;
678                                 tmpludp;
679                                 i++, tmpludp = tmpludp->lud_next )
680                 {
681                         if ( ( tmpludp->lud_dn != NULL
682                                                 && tmpludp->lud_dn[0] != '\0' )
683                                         || tmpludp->lud_attrs != NULL
684                                         /* || tmpludp->lud_scope != LDAP_SCOPE_DEFAULT */
685                                         || tmpludp->lud_filter != NULL
686                                         || tmpludp->lud_exts != NULL )
687                         {
688                                 fprintf( stderr, "%s: line %d: "
689                                                 "warning, only protocol, "
690                                                 "host and port allowed "
691                                                 "in \"uri <uri>\" statement "
692                                                 "for uri #%d of \"%s\"\n",
693                                                 c->fname, c->lineno, i, c->value_string );
694                         }
695                 }
696
697                 for ( i = 0, tmpludp = lud;
698                                 tmpludp;
699                                 i++, tmpludp = tmpludp->lud_next )
700                         /* just count */
701                         ;
702                 urllist = ch_calloc( sizeof( char * ), i + 1 );
703
704                 for ( i = 0, tmpludp = lud;
705                                 tmpludp;
706                                 i++, tmpludp = tmpludp->lud_next )
707                 {
708                         LDAPURLDesc     tmplud;
709
710                         tmplud = *tmpludp;
711                         tmplud.lud_dn = "";
712                         tmplud.lud_attrs = NULL;
713                         tmplud.lud_filter = NULL;
714                         if ( !ldap_is_ldapi_url( tmplud.lud_scheme ) ) {
715                                 tmplud.lud_exts = NULL;
716                                 tmplud.lud_crit_exts = 0;
717                         }
718
719                         urllist[ i ]  = ldap_url_desc2str( &tmplud );
720
721                         if ( urllist[ i ] == NULL ) {
722                                 fprintf( stderr, "%s: line %d: "
723                                         "unable to rebuild uri "
724                                         "in \"uri <uri>\" statement "
725                                         "for \"%s\"\n",
726                                         c->fname, c->lineno, c->argv[ 1 ] );
727                                 urlrc = 1;
728                                 goto done_url;
729                         }
730                 }
731
732                 li->li_uri = ldap_charray2str( urllist, " " );
733                 for ( i = 0; urllist[ i ] != NULL; i++ ) {
734                         struct berval   bv;
735
736                         ber_str2bv( urllist[ i ], 0, 0, &bv );
737                         ber_bvarray_add( &li->li_bvuri, &bv );
738                         urllist[ i ] = NULL;
739                 }
740                 ldap_memfree( urllist );
741                 urllist = NULL;
742
743 done_url:;
744                 if ( urllist ) {
745                         ldap_charray_free( urllist );
746                 }
747                 if ( lud ) {
748                         ldap_free_urllist( lud );
749                 }
750                 if ( urlrc != LDAP_URL_SUCCESS ) {
751                         return 1;
752                 }
753                 break;
754         }
755
756         case LDAP_BACK_CFG_TLS:
757                 i = verb_to_mask( c->argv[1], tls_mode );
758                 if ( BER_BVISNULL( &tls_mode[i].word ) ) {
759                         return 1;
760                 }
761                 li->li_flags &= ~LDAP_BACK_F_TLS_MASK;
762                 li->li_flags |= tls_mode[i].mask;
763                 break;
764
765         case LDAP_BACK_CFG_ACL_AUTHCDN:
766                 switch ( li->li_acl_authmethod ) {
767                 case LDAP_AUTH_NONE:
768                         li->li_acl_authmethod = LDAP_AUTH_SIMPLE;
769                         break;
770
771                 case LDAP_AUTH_SIMPLE:
772                         break;
773
774                 default:
775                         fprintf( stderr, "%s: line %d: "
776                                 "\"acl-authcDN <DN>\" incompatible "
777                                 "with auth method %d.",
778                                 c->fname, c->lineno, li->li_acl_authmethod );
779                         return 1;
780                 }
781                 if ( !BER_BVISNULL( &li->li_acl_authcDN ) ) {
782                         free( li->li_acl_authcDN.bv_val );
783                 }
784                 ber_memfree_x( c->value_dn.bv_val, NULL );
785                 li->li_acl_authcDN = c->value_ndn;
786                 BER_BVZERO( &c->value_dn );
787                 BER_BVZERO( &c->value_ndn );
788                 break;
789
790         case LDAP_BACK_CFG_ACL_PASSWD:
791                 switch ( li->li_acl_authmethod ) {
792                 case LDAP_AUTH_NONE:
793                         li->li_acl_authmethod = LDAP_AUTH_SIMPLE;
794                         break;
795
796                 case LDAP_AUTH_SIMPLE:
797                         break;
798
799                 default:
800                         fprintf( stderr, "%s: line %d: "
801                                 "\"acl-passwd <cred>\" incompatible "
802                                 "with auth method %d.",
803                                 c->fname, c->lineno, li->li_acl_authmethod );
804                         return 1;
805                 }
806                 if ( !BER_BVISNULL( &li->li_acl_passwd ) ) {
807                         free( li->li_acl_passwd.bv_val );
808                 }
809                 ber_str2bv( c->argv[ 1 ], 0, 1, &li->li_acl_passwd );
810                 break;
811
812         case LDAP_BACK_CFG_ACL_METHOD:
813         case LDAP_BACK_CFG_ACL_BIND:
814                 for ( i = 1; i < c->argc; i++ ) {
815                         if ( bindconf_parse( c->argv[ i ], &li->li_acl ) ) {
816                                 return 1;
817                         }
818                 }
819                 break;
820
821         case LDAP_BACK_CFG_IDASSERT_MODE:
822                 i = verb_to_mask( c->argv[1], idassert_mode );
823                 if ( BER_BVISNULL( &idassert_mode[i].word ) ) {
824                         if ( strncasecmp( c->argv[1], "u:", STRLENOF( "u:" ) ) == 0 ) {
825                                 li->li_idassert_mode = LDAP_BACK_IDASSERT_OTHERID;
826                                 ber_str2bv( c->argv[1], 0, 1, &li->li_idassert_authzID );
827                                 li->li_idassert_authzID.bv_val[ 0 ] = 'u';
828                                 
829                         } else {
830                                 struct berval   id, ndn;
831
832                                 ber_str2bv( c->argv[1], 0, 0, &id );
833
834                                 if ( strncasecmp( c->argv[1], "dn:", STRLENOF( "dn:" ) ) == 0 ) {
835                                         id.bv_val += STRLENOF( "dn:" );
836                                         id.bv_len -= STRLENOF( "dn:" );
837                                 }
838
839                                 rc = dnNormalize( 0, NULL, NULL, &id, &ndn, NULL );
840                                 if ( rc != LDAP_SUCCESS ) {
841                                         Debug( LDAP_DEBUG_ANY,
842                                                 "%s: line %d: idassert ID \"%s\" is not a valid DN\n",
843                                                 c->fname, c->lineno, c->argv[1] );
844                                         return 1;
845                                 }
846
847                                 li->li_idassert_authzID.bv_len = STRLENOF( "dn:" ) + ndn.bv_len;
848                                 li->li_idassert_authzID.bv_val = ch_malloc( li->li_idassert_authzID.bv_len + 1 );
849                                 AC_MEMCPY( li->li_idassert_authzID.bv_val, "dn:", STRLENOF( "dn:" ) );
850                                 AC_MEMCPY( &li->li_idassert_authzID.bv_val[ STRLENOF( "dn:" ) ], ndn.bv_val, ndn.bv_len + 1 );
851                                 ch_free( ndn.bv_val );
852
853                                 li->li_idassert_mode = LDAP_BACK_IDASSERT_OTHERDN;
854                         }
855
856                 } else {
857                         li->li_idassert_mode = idassert_mode[i].mask;
858                 }
859
860                 if ( c->argc > 2 ) {
861                         int     i;
862
863                         for ( i = 2; i < c->argc; i++ ) {
864                                 if ( strcasecmp( c->argv[ i ], "override" ) == 0 ) {
865                                         li->li_idassert_flags |= LDAP_BACK_AUTH_OVERRIDE;
866
867                                 } else if ( strcasecmp( c->argv[ i ], "prescriptive" ) == 0 ) {
868                                         li->li_idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE;
869
870                                 } else if ( strcasecmp( c->argv[ i ], "non-prescriptive" ) == 0 ) {
871                                         li->li_idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE );
872
873                                 } else {
874                                         Debug( LDAP_DEBUG_ANY,
875                                                 "%s: line %d: unknown flag #%d "
876                                                 "in \"idassert-mode <args> "
877                                                 "[<flags>]\" line.\n",
878                                                 c->fname, c->lineno, i - 2 );
879                                         return 1;
880                                 }
881                         }
882                 }
883                 break;
884
885         case LDAP_BACK_CFG_IDASSERT_AUTHCDN:
886                 switch ( li->li_idassert_authmethod ) {
887                 case LDAP_AUTH_NONE:
888                         li->li_idassert_authmethod = LDAP_AUTH_SIMPLE;
889                         break;
890
891                 case LDAP_AUTH_SIMPLE:
892                         break;
893
894                 default:
895                         fprintf( stderr, "%s: line %d: "
896                                 "\"idassert-authcDN <DN>\" incompatible "
897                                 "with auth method %d.",
898                                 c->fname, c->lineno, li->li_idassert_authmethod );
899                         return 1;
900                 }
901                 if ( !BER_BVISNULL( &li->li_idassert_authcDN ) ) {
902                         free( li->li_idassert_authcDN.bv_val );
903                 }
904                 ber_memfree_x( c->value_dn.bv_val, NULL );
905                 li->li_idassert_authcDN = c->value_ndn;
906                 BER_BVZERO( &c->value_dn );
907                 BER_BVZERO( &c->value_ndn );
908                 break;
909
910         case LDAP_BACK_CFG_IDASSERT_PASSWD:
911                 switch ( li->li_idassert_authmethod ) {
912                 case LDAP_AUTH_NONE:
913                         li->li_idassert_authmethod = LDAP_AUTH_SIMPLE;
914                         break;
915
916                 case LDAP_AUTH_SIMPLE:
917                         break;
918
919                 default:
920                         fprintf( stderr, "%s: line %d: "
921                                 "\"idassert-passwd <cred>\" incompatible "
922                                 "with auth method %d.",
923                                 c->fname, c->lineno, li->li_idassert_authmethod );
924                         return 1;
925                 }
926                 if ( !BER_BVISNULL( &li->li_idassert_passwd ) ) {
927                         free( li->li_idassert_passwd.bv_val );
928                 }
929                 ber_str2bv( c->argv[ 1 ], 0, 1, &li->li_idassert_passwd );
930                 break;
931
932         case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: {
933                 struct berval   bv;
934 #ifdef SLAP_AUTHZ_SYNTAX
935                 struct berval   in;
936                 int             rc;
937
938                 ber_str2bv( c->argv[ 1 ], 0, 0, &in );
939                 rc = authzNormalize( 0, NULL, NULL, &in, &bv, NULL );
940                 if ( rc != LDAP_SUCCESS ) {
941                         fprintf( stderr, "%s: %d: "
942                                 "\"idassert-authzFrom <authz>\": "
943                                 "invalid syntax.\n",
944                                 c->fname, c->lineno );
945                         return 1;
946                 }
947 #else /* !SLAP_AUTHZ_SYNTAX */
948                 ber_str2bv( c->argv[ 1 ], 0, 1, &bv );
949 #endif /* !SLAP_AUTHZ_SYNTAX */
950                 ber_bvarray_add( &li->li_idassert_authz, &bv );
951                 } break;
952
953         case LDAP_BACK_CFG_IDASSERT_METHOD:
954                 /* no longer supported */
955                 fprintf( stderr, "%s: %d: "
956                         "\"idassert-method <args>\": "
957                         "no longer supported; use \"idassert-bind\".\n",
958                         c->fname, c->lineno );
959                 return 1;
960
961         case LDAP_BACK_CFG_IDASSERT_BIND:
962                 for ( i = 1; i < c->argc; i++ ) {
963                         if ( strncasecmp( c->argv[ i ], "mode=", STRLENOF( "mode=" ) ) == 0 ) {
964                                 char    *argvi = c->argv[ i ] + STRLENOF( "mode=" );
965                                 int     j;
966
967                                 j = verb_to_mask( argvi, idassert_mode );
968                                 if ( BER_BVISNULL( &idassert_mode[ j ].word ) ) {
969                                         fprintf( stderr, "%s: %d: "
970                                                 "\"idassert-bind <args>\": "
971                                                 "unknown mode \"%s\".\n",
972                                                 c->fname, c->lineno, argvi );
973                                         return 1;
974                                 }
975
976                                 li->li_idassert_mode = idassert_mode[ j ].mask;
977
978                         } else if ( strncasecmp( c->argv[ i ], "authz=", STRLENOF( "authz=" ) ) == 0 ) {
979                                 char    *argvi = c->argv[ i ] + STRLENOF( "authz=" );
980
981                                 if ( strcasecmp( argvi, "native" ) == 0 ) {
982                                         if ( li->li_idassert_authmethod != LDAP_AUTH_SASL ) {
983                                                 fprintf( stderr, "%s: %d: "
984                                                         "\"idassert-bind <args>\": "
985                                                         "authz=\"native\" incompatible "
986                                                         "with auth method.\n",
987                                                         c->fname, c->lineno );
988                                                 return 1;
989                                         }
990                                         li->li_idassert_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ;
991
992                                 } else if ( strcasecmp( argvi, "proxyAuthz" ) == 0 ) {
993                                         li->li_idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;
994
995                                 } else {
996                                         fprintf( stderr, "%s: %d: "
997                                                 "\"idassert-bind <args>\": "
998                                                 "unknown authz \"%s\".\n",
999                                                 c->fname, c->lineno, argvi );
1000                                         return 1;
1001                                 }
1002
1003                         } else if ( strncasecmp( c->argv[ i ], "flags=", STRLENOF( "flags=" ) ) == 0 ) {
1004                                 char    *argvi = c->argv[ i ] + STRLENOF( "flags=" );
1005                                 char    **flags = ldap_str2charray( argvi, "," );
1006                                 int     j;
1007
1008                                 if ( flags == NULL ) {
1009                                         fprintf( stderr, "%s: %d: "
1010                                                 "\"idassert-bind <args>\": "
1011                                                 "unable to parse flags \"%s\".\n",
1012                                                 c->fname, c->lineno, argvi );
1013                                         return 1;
1014                                 }
1015
1016                                 for ( j = 0; flags[ j ] != NULL; j++ ) {
1017                                         if ( strcasecmp( flags[ j ], "override" ) == 0 ) {
1018                                                 li->li_idassert_flags |= LDAP_BACK_AUTH_OVERRIDE;
1019
1020                                         } else if ( strcasecmp( flags[ j ], "prescriptive" ) == 0 ) {
1021                                                 li->li_idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE;
1022
1023                                         } else if ( strcasecmp( flags[ j ], "non-prescriptive" ) == 0 ) {
1024                                                 li->li_idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE );
1025
1026                                         } else {
1027                                                 fprintf( stderr, "%s: %d: "
1028                                                         "\"idassert-bind <args>\": "
1029                                                         "unknown flag \"%s\".\n",
1030                                                         c->fname, c->lineno, flags[ j ] );
1031                                                 return 1;
1032                                         }
1033                                 }
1034
1035                                 ldap_charray_free( flags );
1036
1037                         } else if ( bindconf_parse( c->argv[ i ], &li->li_idassert ) ) {
1038                                 return 1;
1039                         }
1040                 }
1041                 break;
1042
1043         case LDAP_BACK_CFG_REBIND:
1044                 if ( c->argc == 1 || c->value_int ) {
1045                         li->li_flags |= LDAP_BACK_F_SAVECRED;
1046
1047                 } else {
1048                         li->li_flags &= ~LDAP_BACK_F_SAVECRED;
1049                 }
1050                 break;
1051
1052         case LDAP_BACK_CFG_CHASE:
1053                 if ( c->argc == 1 || c->value_int ) {
1054                         li->li_flags |= LDAP_BACK_F_CHASE_REFERRALS;
1055
1056                 } else {
1057                         li->li_flags &= ~LDAP_BACK_F_CHASE_REFERRALS;
1058                 }
1059                 break;
1060
1061         case LDAP_BACK_CFG_T_F:
1062                 i = verb_to_mask( c->argv[1], t_f_mode );
1063                 if ( BER_BVISNULL( &t_f_mode[i].word ) ) {
1064                         return 1;
1065                 }
1066                 li->li_flags &= ~LDAP_BACK_F_SUPPORT_T_F_MASK;
1067                 li->li_flags |= t_f_mode[i].mask;
1068                 break;
1069
1070         case LDAP_BACK_CFG_WHOAMI:
1071                 if ( c->argc == 1 || c->value_int ) {
1072                         li->li_flags |= LDAP_BACK_F_PROXY_WHOAMI;
1073                         load_extop( (struct berval *)&slap_EXOP_WHOAMI,
1074                                         0, ldap_back_exop_whoami );
1075
1076                 } else {
1077                         li->li_flags &= ~LDAP_BACK_F_PROXY_WHOAMI;
1078                 }
1079                 break;
1080
1081         case LDAP_BACK_CFG_TIMEOUT:
1082                 if ( c->argc < 2 ) {
1083                         return 1;
1084                 }
1085
1086                 for ( i = 1; i < c->argc; i++ ) {
1087                         if ( isdigit( c->argv[ i ][ 0 ] ) ) {
1088                                 char            *next;
1089                                 int             j;
1090                                 unsigned        u;
1091
1092                                 u = strtoul( c->argv[ i ], &next, 0 );
1093                                 if ( next == c->argv[ i ] || next[ 0 ] != '\0' ) {
1094                                         return 1;
1095                                 }
1096
1097                                 for ( j = 0; j < LDAP_BACK_OP_LAST; j++ ) {
1098                                         li->li_timeout[ j ] = u;
1099                                 }
1100
1101                                 continue;
1102                         }
1103
1104                         if ( slap_cf_aux_table_parse( c->argv[ i ], li->li_timeout, timeout_table, "slapd-ldap timeout" ) ) {
1105                                 return 1;
1106                         }
1107                 }
1108                 break;
1109
1110         case LDAP_BACK_CFG_REWRITE:
1111                 fprintf( stderr, "%s: line %d: "
1112                         "rewrite/remap capabilities have been moved "
1113                         "to the \"rwm\" overlay; see slapo-rwm(5) "
1114                         "for details (hint: add \"overlay rwm\" "
1115                         "and prefix all directives with \"rwm-\").\n",
1116                         c->fname, c->lineno );
1117                 return 1;
1118                 
1119         default:
1120                 /* FIXME: try to catch inconsistencies */
1121                 assert( 0 );
1122                 break;
1123         }
1124
1125         return 0;
1126 }
1127
1128 int
1129 ldap_back_init_cf( BackendInfo *bi )
1130 {
1131         int                     rc;
1132         AttributeDescription    *ad = NULL;
1133         const char              *text;
1134
1135         bi->bi_cf_ocs = ldapocs;
1136
1137         rc = config_register_schema( ldapcfg, ldapocs );
1138         if ( rc ) {
1139                 return rc;
1140         }
1141
1142         /* setup olcDbAclPasswd and olcDbIDAssertPasswd 
1143          * to be base64-encoded when written in LDIF form;
1144          * basically, we don't care if it fails */
1145         rc = slap_str2ad( "olcDbACLPasswd", &ad, &text );
1146         if ( rc ) {
1147                 Debug( LDAP_DEBUG_ANY, "config_back_initialize: "
1148                         "warning, unable to get \"olcDbACLPasswd\" "
1149                         "attribute description: %d: %s\n",
1150                         rc, text, 0 );
1151         } else {
1152                 (void)ldif_must_b64_encode_register( ad->ad_cname.bv_val,
1153                         ad->ad_type->sat_oid );
1154         }
1155
1156         ad = NULL;
1157         rc = slap_str2ad( "olcDbIDAssertPasswd", &ad, &text );
1158         if ( rc ) {
1159                 Debug( LDAP_DEBUG_ANY, "config_back_initialize: "
1160                         "warning, unable to get \"olcDbIDAssertPasswd\" "
1161                         "attribute description: %d: %s\n",
1162                         rc, text, 0 );
1163         } else {
1164                 (void)ldif_must_b64_encode_register( ad->ad_cname.bv_val,
1165                         ad->ad_type->sat_oid );
1166         }
1167
1168         return 0;
1169 }
1170
1171
1172 static int
1173 ldap_back_exop_whoami(
1174                 Operation       *op,
1175                 SlapReply       *rs )
1176 {
1177         struct berval *bv = NULL;
1178
1179         if ( op->oq_extended.rs_reqdata != NULL ) {
1180                 /* no request data should be provided */
1181                 rs->sr_text = "no request data expected";
1182                 return rs->sr_err = LDAP_PROTOCOL_ERROR;
1183         }
1184
1185         Statslog( LDAP_DEBUG_STATS, "%s WHOAMI\n",
1186             op->o_log_prefix, 0, 0, 0, 0 );
1187
1188         rs->sr_err = backend_check_restrictions( op, rs, 
1189                         (struct berval *)&slap_EXOP_WHOAMI );
1190         if( rs->sr_err != LDAP_SUCCESS ) return rs->sr_err;
1191
1192         /* if auth'd by back-ldap and request is proxied, forward it */
1193         if ( op->o_conn->c_authz_backend && !strcmp(op->o_conn->c_authz_backend->be_type, "ldap" ) && !dn_match(&op->o_ndn, &op->o_conn->c_ndn)) {
1194                 ldapconn_t      *lc;
1195
1196                 LDAPControl c, *ctrls[2] = {NULL, NULL};
1197                 LDAPMessage *res;
1198                 Operation op2 = *op;
1199                 ber_int_t msgid;
1200                 int doretry = 1;
1201
1202                 ctrls[0] = &c;
1203                 op2.o_ndn = op->o_conn->c_ndn;
1204                 lc = ldap_back_getconn(&op2, rs, LDAP_BACK_SENDERR);
1205                 if (!lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR )) {
1206                         return -1;
1207                 }
1208                 c.ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
1209                 c.ldctl_iscritical = 1;
1210                 c.ldctl_value.bv_val = ch_malloc(op->o_ndn.bv_len+4);
1211                 c.ldctl_value.bv_len = op->o_ndn.bv_len + 3;
1212                 strcpy(c.ldctl_value.bv_val, "dn:");
1213                 strcpy(c.ldctl_value.bv_val+3, op->o_ndn.bv_val);
1214
1215 retry:
1216                 rs->sr_err = ldap_whoami(lc->lc_ld, ctrls, NULL, &msgid);
1217                 if (rs->sr_err == LDAP_SUCCESS) {
1218                         if (ldap_result(lc->lc_ld, msgid, 1, NULL, &res) == -1) {
1219                                 ldap_get_option(lc->lc_ld, LDAP_OPT_ERROR_NUMBER,
1220                                         &rs->sr_err);
1221                                 if ( rs->sr_err == LDAP_SERVER_DOWN && doretry ) {
1222                                         doretry = 0;
1223                                         if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) )
1224                                                 goto retry;
1225                                 }
1226                                 ldap_back_freeconn( op, lc, 1 );
1227                                 lc = NULL;
1228
1229                         } else {
1230                                 rs->sr_err = ldap_parse_whoami(lc->lc_ld, res, &bv);
1231                                 ldap_msgfree(res);
1232                         }
1233                 }
1234                 ch_free(c.ldctl_value.bv_val);
1235                 if (rs->sr_err != LDAP_SUCCESS) {
1236                         rs->sr_err = slap_map_api2result( rs );
1237                 }
1238
1239                 if ( lc != NULL ) {
1240                         ldap_back_release_conn( &op2, rs, lc );
1241                 }
1242
1243         } else {
1244         /* else just do the same as before */
1245                 bv = (struct berval *) ch_malloc( sizeof(struct berval) );
1246                 if ( !BER_BVISEMPTY( &op->o_dn ) ) {
1247                         bv->bv_len = op->o_dn.bv_len + STRLENOF("dn:");
1248                         bv->bv_val = ch_malloc( bv->bv_len + 1 );
1249                         AC_MEMCPY( bv->bv_val, "dn:", STRLENOF("dn:") );
1250                         AC_MEMCPY( &bv->bv_val[STRLENOF("dn:")], op->o_dn.bv_val,
1251                                 op->o_dn.bv_len );
1252                         bv->bv_val[bv->bv_len] = '\0';
1253                 } else {
1254                         bv->bv_len = 0;
1255                         bv->bv_val = NULL;
1256                 }
1257         }
1258
1259         rs->sr_rspdata = bv;
1260         return rs->sr_err;
1261 }
1262
1263