]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldap/config.c
0a2df2379d7d66f9030c331f395b9b453678abaf
[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-2004 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/socket.h>
30
31 #include "slap.h"
32 #include "back-ldap.h"
33 #include "lutil.h"
34
35 static SLAP_EXTOP_MAIN_FN ldap_back_exop_whoami;
36
37 static int
38 parse_idassert( BackendDB *be, const char *fname, int lineno,
39                 int argc, char **argv );
40
41 int
42 ldap_back_db_config(
43     BackendDB   *be,
44     const char  *fname,
45     int         lineno,
46     int         argc,
47     char        **argv
48 )
49 {
50         struct ldapinfo *li = (struct ldapinfo *) be->be_private;
51
52         if ( li == NULL ) {
53                 fprintf( stderr, "%s: line %d: ldap backend info is null!\n",
54                     fname, lineno );
55                 return( 1 );
56         }
57
58         /* server address to query (depricated, use "uri" directive) */
59         if ( strcasecmp( argv[0], "server" ) == 0 ) {
60                 if (argc != 2) {
61                         fprintf( stderr,
62         "%s: line %d: missing address in \"server <address>\" line\n",
63                             fname, lineno );
64                         return( 1 );
65                 }
66                 if (li->url != NULL)
67                         ch_free(li->url);
68                 li->url = ch_calloc(strlen(argv[1]) + 9, sizeof(char));
69                 if (li->url != NULL) {
70                         strcpy(li->url, "ldap://");
71                         strcat(li->url, argv[1]);
72                         strcat(li->url, "/");
73                 }
74
75         /* URI of server to query (preferred over "server" directive) */
76         } else if ( strcasecmp( argv[0], "uri" ) == 0 ) {
77                 LDAPURLDesc     tmplud;
78
79                 if (argc != 2) {
80                         fprintf( stderr, "%s: line %d: "
81                                 "missing uri "
82                                 "in \"uri <uri>\" line\n",
83                                 fname, lineno );
84                         return( 1 );
85                 }
86                 if ( li->url != NULL ) {
87                         ch_free( li->url );
88                 }
89                 if ( li->lud != NULL ) {
90                         ldap_free_urldesc( li->lud );
91                 }
92
93                 if ( ldap_url_parse( argv[ 1 ], &li->lud ) != LDAP_URL_SUCCESS ) {
94                         fprintf( stderr, "%s: line %d: "
95                                 "unable to parse uri \"%s\" "
96                                 "in \"uri <uri>\" line\n",
97                                 fname, lineno, argv[ 1 ] );
98                         return 1;
99                 }
100
101                 if ( ( li->lud->lud_dn != NULL && li->lud->lud_dn[0] != '\0' )
102                                 || li->lud->lud_attrs != NULL
103                                 || li->lud->lud_filter != NULL
104                                 || li->lud->lud_exts != NULL )
105                 {
106                         fprintf( stderr, "%s: line %d: "
107                                 "warning, only protocol, "
108                                 "host and port allowed "
109                                 "in \"uri <uri>\" line\n",
110                                 fname, lineno );
111                 }
112
113 #if 0
114                 tmplud = *lud;
115                 tmplud.lud_dn = "";
116                 tmplud.lud_attrs = NULL;
117                 tmplud.lud_filter = NULL;
118                 if ( !ldap_is_ldapi_url( argv[ 1 ] ) ) {
119                         tmplud.lud_exts = NULL;
120                         tmplud.lud_crit_exts = 0;
121                 }
122                 
123                 li->url = ldap_url_desc2str( &tmplud );
124                 if ( li->url == NULL ) {
125                         fprintf( stderr, "%s: line %d: "
126                                 "unable to rebuild uri \"%s\" "
127                                 "in \"uri <uri>\" line\n",
128                                 fname, lineno, argv[ 1 ] );
129                         return 1;
130                 }
131 #else
132                 li->url = ch_strdup( argv[ 1 ] );
133 #endif
134
135         /* name to use for ldap_back_group */
136         } else if ( strcasecmp( argv[0], "binddn" ) == 0 ) {
137                 if (argc != 2) {
138                         fprintf( stderr,
139         "%s: line %d: missing name in \"binddn <name>\" line\n",
140                             fname, lineno );
141                         return( 1 );
142                 }
143                 ber_str2bv( argv[1], 0, 1, &li->binddn );
144
145         /* password to use for ldap_back_group */
146         } else if ( strcasecmp( argv[0], "bindpw" ) == 0 ) {
147                 if (argc != 2) {
148                         fprintf( stderr,
149         "%s: line %d: missing password in \"bindpw <password>\" line\n",
150                             fname, lineno );
151                         return( 1 );
152                 }
153                 ber_str2bv( argv[1], 0, 1, &li->bindpw );
154
155 #ifdef LDAP_BACK_PROXY_AUTHZ
156         /* name to use for proxyAuthz propagation */
157         } else if ( strcasecmp( argv[0], "proxyauthzdn" ) == 0 ) {
158                 if (argc != 2) {
159                         fprintf( stderr,
160         "%s: line %d: missing name in \"proxyauthzdn <name>\" line\n",
161                             fname, lineno );
162                         return( 1 );
163                 }
164                 ber_str2bv( argv[1], 0, 1, &li->proxyauthzdn );
165
166         /* password to use for proxyAuthz propagation */
167         } else if ( strcasecmp( argv[0], "proxyauthzpw" ) == 0 ) {
168                 if (argc != 2) {
169                         fprintf( stderr,
170         "%s: line %d: missing password in \"proxyauthzpw <password>\" line\n",
171                             fname, lineno );
172                         return( 1 );
173                 }
174                 ber_str2bv( argv[1], 0, 1, &li->proxyauthzpw );
175
176         /* identity assertion stuff... */
177         } else if ( strncasecmp( argv[0], "idassert-", STRLENOF( "idassert-" ) ) == 0 ) {
178                 return parse_idassert( be, fname, lineno, argc, argv );
179 #endif /* LDAP_BACK_PROXY_AUTHZ */
180
181         /* save bind creds for referral rebinds? */
182         } else if ( strcasecmp( argv[0], "rebind-as-user" ) == 0 ) {
183                 if (argc != 1) {
184                         fprintf( stderr,
185         "%s: line %d: rebind-as-user takes no arguments\n",
186                             fname, lineno );
187                         return( 1 );
188                 }
189                 li->savecred = 1;
190         
191         /* intercept exop_who_am_i? */
192         } else if ( strcasecmp( argv[0], "proxy-whoami" ) == 0 ) {
193                 if (argc != 1) {
194                         fprintf( stderr,
195         "%s: line %d: proxy-whoami takes no arguments\n",
196                             fname, lineno );
197                         return( 1 );
198                 }
199                 load_extop( (struct berval *)&slap_EXOP_WHOAMI,
200                         0, ldap_back_exop_whoami );
201         
202         /* dn massaging */
203         } else if ( strcasecmp( argv[0], "suffixmassage" ) == 0 ) {
204                 BackendDB *tmp_be;
205                 struct berval bvnc, nvnc, pvnc, brnc, nrnc, prnc;
206 #ifdef ENABLE_REWRITE
207                 int rc;
208 #endif /* ENABLE_REWRITE */
209                 
210                 /*
211                  * syntax:
212                  * 
213                  *      suffixmassage <suffix> <massaged suffix>
214                  *
215                  * the <suffix> field must be defined as a valid suffix
216                  * (or suffixAlias?) for the current database;
217                  * the <massaged suffix> shouldn't have already been
218                  * defined as a valid suffix or suffixAlias for the 
219                  * current server
220                  */
221                 if ( argc != 3 ) {
222                         fprintf( stderr, "%s: line %d: syntax is"
223                                        " \"suffixMassage <suffix>"
224                                        " <massaged suffix>\"\n",
225                                 fname, lineno );
226                         return( 1 );
227                 }
228                 
229                 ber_str2bv( argv[1], 0, 0, &bvnc );
230                 if ( dnPrettyNormal( NULL, &bvnc, &pvnc, &nvnc, NULL ) != LDAP_SUCCESS ) {
231                         fprintf( stderr, "%s: line %d: suffix DN %s is invalid\n",
232                                 fname, lineno, bvnc.bv_val );
233                         return( 1 );
234                 }
235                 tmp_be = select_backend( &nvnc, 0, 0 );
236                 if ( tmp_be != NULL && tmp_be != be ) {
237                         fprintf( stderr, "%s: line %d: suffix already in use"
238                                        " by another backend in"
239                                        " \"suffixMassage <suffix>"
240                                        " <massaged suffix>\"\n",
241                                 fname, lineno );
242                         free( nvnc.bv_val );
243                         free( pvnc.bv_val );
244                         return( 1 );
245                 }
246
247                 ber_str2bv( argv[2], 0, 0, &brnc );
248                 if ( dnPrettyNormal( NULL, &brnc, &prnc, &nrnc, NULL ) != LDAP_SUCCESS ) {
249                         fprintf( stderr, "%s: line %d: suffix DN %s is invalid\n",
250                                 fname, lineno, brnc.bv_val );
251                         free( nvnc.bv_val );
252                         free( pvnc.bv_val );
253                         return( 1 );
254                 }
255
256 #if 0
257                 tmp_be = select_backend( &nrnc, 0, 0 );
258                 if ( tmp_be != NULL ) {
259                         fprintf( stderr, "%s: line %d: massaged suffix"
260                                        " already in use by another backend in" 
261                                        " \"suffixMassage <suffix>"
262                                        " <massaged suffix>\"\n",
263                                 fname, lineno );
264                         free( nvnc.bv_val );
265                         free( pvnc.bv_val );
266                         free( nrnc.bv_val );
267                         free( prnc.bv_val );
268                         return( 1 );
269                 }
270 #endif
271
272 #ifdef ENABLE_REWRITE
273                 /*
274                  * The suffix massaging is emulated by means of the
275                  * rewrite capabilities
276                  * FIXME: no extra rewrite capabilities should be added
277                  * to the database
278                  */
279                 rc = suffix_massage_config( li->rwmap.rwm_rw,
280                                 &pvnc, &nvnc, &prnc, &nrnc );
281                 free( nvnc.bv_val );
282                 free( pvnc.bv_val );
283                 free( nrnc.bv_val );
284                 free( prnc.bv_val );
285
286                 return( rc );
287
288 #else /* !ENABLE_REWRITE */
289                 ber_bvarray_add( &li->rwmap.rwm_suffix_massage, &pvnc );
290                 ber_bvarray_add( &li->rwmap.rwm_suffix_massage, &nvnc );
291                 
292                 ber_bvarray_add( &li->rwmap.rwm_suffix_massage, &prnc );
293                 ber_bvarray_add( &li->rwmap.rwm_suffix_massage, &nrnc );
294 #endif /* !ENABLE_REWRITE */
295
296         /* rewrite stuff ... */
297         } else if ( strncasecmp( argv[0], "rewrite", 7 ) == 0 ) {
298 #ifdef ENABLE_REWRITE
299                 return rewrite_parse( li->rwmap.rwm_rw,
300                                 fname, lineno, argc, argv );
301
302 #else /* !ENABLE_REWRITE */
303                 fprintf( stderr, "%s: line %d: rewrite capabilities "
304                                 "are not enabled\n", fname, lineno );
305 #endif /* !ENABLE_REWRITE */
306                 
307         /* objectclass/attribute mapping */
308         } else if ( strcasecmp( argv[0], "map" ) == 0 ) {
309                 return ldap_back_map_config( &li->rwmap.rwm_oc,
310                                 &li->rwmap.rwm_at,
311                                 fname, lineno, argc, argv );
312
313         /* anything else */
314         } else {
315                 return SLAP_CONF_UNKNOWN;
316         }
317         return 0;
318 }
319
320 int
321 ldap_back_map_config(
322                 struct ldapmap  *oc_map,
323                 struct ldapmap  *at_map,
324                 const char      *fname,
325                 int             lineno,
326                 int             argc,
327                 char            **argv )
328 {
329         struct ldapmap          *map;
330         struct ldapmapping      *mapping;
331         char                    *src, *dst;
332         int                     is_oc = 0;
333
334         if ( argc < 3 || argc > 4 ) {
335                 fprintf( stderr,
336         "%s: line %d: syntax is \"map {objectclass | attribute} [<local> | *] {<foreign> | *}\"\n",
337                         fname, lineno );
338                 return 1;
339         }
340
341         if ( strcasecmp( argv[1], "objectclass" ) == 0 ) {
342                 map = oc_map;
343                 is_oc = 1;
344
345         } else if ( strcasecmp( argv[1], "attribute" ) == 0 ) {
346                 map = at_map;
347
348         } else {
349                 fprintf( stderr, "%s: line %d: syntax is "
350                         "\"map {objectclass | attribute} [<local> | *] "
351                         "{<foreign> | *}\"\n",
352                         fname, lineno );
353                 return 1;
354         }
355
356         if ( strcmp( argv[2], "*" ) == 0 ) {
357                 if ( argc < 4 || strcmp( argv[3], "*" ) == 0 ) {
358                         map->drop_missing = ( argc < 4 );
359                         return 0;
360                 }
361                 src = dst = argv[3];
362
363         } else if ( argc < 4 ) {
364                 src = "";
365                 dst = argv[2];
366
367         } else {
368                 src = argv[2];
369                 dst = ( strcmp( argv[3], "*" ) == 0 ? src : argv[3] );
370         }
371
372         if ( ( map == at_map )
373                         && ( strcasecmp( src, "objectclass" ) == 0
374                         || strcasecmp( dst, "objectclass" ) == 0 ) )
375         {
376                 fprintf( stderr,
377                         "%s: line %d: objectclass attribute cannot be mapped\n",
378                         fname, lineno );
379         }
380
381         mapping = (struct ldapmapping *)ch_calloc( 2,
382                 sizeof(struct ldapmapping) );
383         if ( mapping == NULL ) {
384                 fprintf( stderr,
385                         "%s: line %d: out of memory\n",
386                         fname, lineno );
387                 return 1;
388         }
389         ber_str2bv( src, 0, 1, &mapping->src );
390         ber_str2bv( dst, 0, 1, &mapping->dst );
391         mapping[1].src = mapping->dst;
392         mapping[1].dst = mapping->src;
393
394         /*
395          * schema check
396          */
397         if ( is_oc ) {
398                 if ( src[0] != '\0' ) {
399                         if ( oc_bvfind( &mapping->src ) == NULL ) {
400                                 fprintf( stderr,
401         "%s: line %d: warning, source objectClass '%s' "
402         "should be defined in schema\n",
403                                         fname, lineno, src );
404
405                                 /*
406                                  * FIXME: this should become an err
407                                  */
408                                 goto error_return;
409                         }
410                 }
411
412                 if ( oc_bvfind( &mapping->dst ) == NULL ) {
413                         fprintf( stderr,
414         "%s: line %d: warning, destination objectClass '%s' "
415         "is not defined in schema\n",
416                                 fname, lineno, dst );
417                 }
418         } else {
419                 int                     rc;
420                 const char              *text = NULL;
421                 AttributeDescription    *ad = NULL;
422
423                 if ( src[0] != '\0' ) {
424                         rc = slap_bv2ad( &mapping->src, &ad, &text );
425                         if ( rc != LDAP_SUCCESS ) {
426                                 fprintf( stderr,
427         "%s: line %d: warning, source attributeType '%s' "
428         "should be defined in schema\n",
429                                         fname, lineno, src );
430
431                                 /*
432                                  * FIXME: this should become an err
433                                  */
434                                 goto error_return;
435                         }
436
437                         ad = NULL;
438                 }
439
440                 rc = slap_bv2ad( &mapping->dst, &ad, &text );
441                 if ( rc != LDAP_SUCCESS ) {
442                         fprintf( stderr,
443         "%s: line %d: warning, destination attributeType '%s' "
444         "is not defined in schema\n",
445                                 fname, lineno, dst );
446                 }
447         }
448
449         if ( (src[0] != '\0' && avl_find( map->map, (caddr_t)mapping, mapping_cmp ) != NULL)
450                         || avl_find( map->remap, (caddr_t)&mapping[1], mapping_cmp ) != NULL)
451         {
452                 fprintf( stderr,
453                         "%s: line %d: duplicate mapping found (ignored)\n",
454                         fname, lineno );
455                 goto error_return;
456         }
457
458         if ( src[0] != '\0' ) {
459                 avl_insert( &map->map, (caddr_t)mapping,
460                                         mapping_cmp, mapping_dup );
461         }
462         avl_insert( &map->remap, (caddr_t)&mapping[1],
463                                 mapping_cmp, mapping_dup );
464
465         return 0;
466
467 error_return:;
468         if ( mapping ) {
469                 ch_free( mapping->src.bv_val );
470                 ch_free( mapping->dst.bv_val );
471                 ch_free( mapping );
472         }
473
474         return 1;
475 }
476
477 static int
478 ldap_back_exop_whoami(
479         Operation *op,
480         SlapReply *rs )
481 {
482         struct berval *bv = NULL;
483
484         if ( op->oq_extended.rs_reqdata != NULL ) {
485                 /* no request data should be provided */
486                 rs->sr_text = "no request data expected";
487                 return rs->sr_err = LDAP_PROTOCOL_ERROR;
488         }
489
490         rs->sr_err = backend_check_restrictions( op, rs, 
491                         (struct berval *)&slap_EXOP_WHOAMI );
492         if( rs->sr_err != LDAP_SUCCESS ) return rs->sr_err;
493
494         /* if auth'd by back-ldap and request is proxied, forward it */
495         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)) {
496                 struct ldapconn *lc;
497
498                 LDAPControl c, *ctrls[2] = {NULL, NULL};
499                 LDAPMessage *res;
500                 Operation op2 = *op;
501                 ber_int_t msgid;
502
503                 ctrls[0] = &c;
504                 op2.o_ndn = op->o_conn->c_ndn;
505                 lc = ldap_back_getconn(&op2, rs);
506                 if (!lc || !ldap_back_dobind( lc, op, rs )) {
507                         return -1;
508                 }
509                 c.ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
510                 c.ldctl_iscritical = 1;
511                 c.ldctl_value.bv_val = ch_malloc(op->o_ndn.bv_len+4);
512                 c.ldctl_value.bv_len = op->o_ndn.bv_len + 3;
513                 strcpy(c.ldctl_value.bv_val, "dn:");
514                 strcpy(c.ldctl_value.bv_val+3, op->o_ndn.bv_val);
515
516                 rs->sr_err = ldap_whoami(lc->ld, ctrls, NULL, &msgid);
517                 if (rs->sr_err == LDAP_SUCCESS) {
518                         if (ldap_result(lc->ld, msgid, 1, NULL, &res) == -1) {
519                                 ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER,
520                                         &rs->sr_err);
521                         } else {
522                                 rs->sr_err = ldap_parse_whoami(lc->ld, res, &bv);
523                                 ldap_msgfree(res);
524                         }
525                 }
526                 ch_free(c.ldctl_value.bv_val);
527                 if (rs->sr_err != LDAP_SUCCESS) {
528                         rs->sr_err = slap_map_api2result( rs );
529                 }
530         } else {
531         /* else just do the same as before */
532                 bv = (struct berval *) ch_malloc( sizeof(struct berval) );
533                 if( op->o_dn.bv_len ) {
534                         bv->bv_len = op->o_dn.bv_len + sizeof("dn:") - 1;
535                         bv->bv_val = ch_malloc( bv->bv_len + 1 );
536                         AC_MEMCPY( bv->bv_val, "dn:", sizeof("dn:") - 1 );
537                         AC_MEMCPY( &bv->bv_val[sizeof("dn:") - 1], op->o_dn.bv_val,
538                                 op->o_dn.bv_len );
539                         bv->bv_val[bv->bv_len] = '\0';
540                 } else {
541                         bv->bv_len = 0;
542                         bv->bv_val = NULL;
543                 }
544         }
545
546         rs->sr_rspdata = bv;
547         return rs->sr_err;
548 }
549
550
551 #ifdef ENABLE_REWRITE
552 static char *
553 suffix_massage_regexize( const char *s )
554 {
555         char *res, *ptr;
556         const char *p, *r;
557         int i;
558
559         for ( i = 0, p = s; 
560                         ( r = strchr( p, ',' ) ) != NULL; 
561                         p = r + 1, i++ )
562                 ;
563
564         res = ch_calloc( sizeof( char ), strlen( s ) + 4 + 4*i + 1 );
565
566         ptr = lutil_strcopy( res, "(.*)" );
567         for ( i = 0, p = s;
568                         ( r = strchr( p, ',' ) ) != NULL;
569                         p = r + 1 , i++ ) {
570                 ptr = lutil_strncopy( ptr, p, r - p + 1 );
571                 ptr = lutil_strcopy( ptr, "[ ]?" );
572
573                 if ( r[ 1 ] == ' ' ) {
574                         r++;
575                 }
576         }
577         lutil_strcopy( ptr, p );
578
579         return res;
580 }
581
582 static char *
583 suffix_massage_patternize( const char *s )
584 {
585         ber_len_t       len;
586         char            *res;
587
588         len = strlen( s );
589
590         res = ch_calloc( sizeof( char ), len + sizeof( "%1" ) );
591         if ( res == NULL ) {
592                 return NULL;
593         }
594
595         strcpy( res, "%1" );
596         strcpy( res + sizeof( "%1" ) - 1, s );
597
598         return res;
599 }
600
601 int
602 suffix_massage_config( 
603                 struct rewrite_info *info,
604                 struct berval *pvnc,
605                 struct berval *nvnc,
606                 struct berval *prnc,
607                 struct berval *nrnc
608 )
609 {
610         char *rargv[ 5 ];
611         int line = 0;
612
613         rargv[ 0 ] = "rewriteEngine";
614         rargv[ 1 ] = "on";
615         rargv[ 2 ] = NULL;
616         rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
617
618         rargv[ 0 ] = "rewriteContext";
619         rargv[ 1 ] = "default";
620         rargv[ 2 ] = NULL;
621         rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
622
623         rargv[ 0 ] = "rewriteRule";
624         rargv[ 1 ] = suffix_massage_regexize( pvnc->bv_val );
625         rargv[ 2 ] = suffix_massage_patternize( prnc->bv_val );
626         rargv[ 3 ] = ":";
627         rargv[ 4 ] = NULL;
628         rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
629         ch_free( rargv[ 1 ] );
630         ch_free( rargv[ 2 ] );
631         
632         rargv[ 0 ] = "rewriteContext";
633         rargv[ 1 ] = "searchResult";
634         rargv[ 2 ] = NULL;
635         rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
636         
637         rargv[ 0 ] = "rewriteRule";
638         rargv[ 1 ] = suffix_massage_regexize( prnc->bv_val );
639         rargv[ 2 ] = suffix_massage_patternize( pvnc->bv_val );
640         rargv[ 3 ] = ":";
641         rargv[ 4 ] = NULL;
642         rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
643         ch_free( rargv[ 1 ] );
644         ch_free( rargv[ 2 ] );
645
646         rargv[ 0 ] = "rewriteContext";
647         rargv[ 1 ] = "matchedDN";
648         rargv[ 2 ] = "alias";
649         rargv[ 3 ] = "searchResult";
650         rargv[ 4 ] = NULL;
651         rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
652
653         rargv[ 0 ] = "rewriteContext";
654         rargv[ 1 ] = "searchAttrDN";
655         rargv[ 2 ] = "alias";
656         rargv[ 3 ] = "searchResult";
657         rargv[ 4 ] = NULL;
658         rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
659
660         return 0;
661 }
662 #endif /* ENABLE_REWRITE */
663
664 #ifdef LDAP_BACK_PROXY_AUTHZ
665 static int
666 parse_idassert(
667     BackendDB   *be,
668     const char  *fname,
669     int         lineno,
670     int         argc,
671     char        **argv
672 )
673 {
674         struct ldapinfo *li = (struct ldapinfo *) be->be_private;
675
676         if ( strcasecmp( argv[0], "idassert-mode" ) == 0 ) {
677                 if ( argc != 2 ) {
678 #ifdef NEW_LOGGING
679                         LDAP_LOG( CONFIG, CRIT, 
680                                 "%s: line %d: illegal args number %d in \"idassert-mode <args>\" line.\n",
681                                 fname, lineno, argc );
682 #else
683                         Debug( LDAP_DEBUG_ANY,
684                                 "%s: line %d: illegal args number %d in \"idassert-mode <args>\" line.\n",
685                                 fname, lineno, argc );
686 #endif
687                         return 1;
688                 }
689
690                 if ( strcasecmp( argv[1], "self" ) == 0 ) {
691                         /* will proxyAuthz as (rewritten) client's identity */
692                         li->idassert_mode = LDAP_BACK_IDASSERT_SELF;
693
694                 } else if ( strcasecmp( argv[1], "anonymous" ) == 0 ) {
695                         /* will proxyAuthz as anonymous */
696                         li->idassert_mode = LDAP_BACK_IDASSERT_ANONYMOUS;
697
698                 } else if ( strcasecmp( argv[1], "proxyid" ) == 0 ) {
699                         /* will not proxyAuthz */
700                         li->idassert_mode = LDAP_BACK_IDASSERT_PROXYID;
701
702                 } else {
703                         struct berval   dn;
704                         int             rc;
705
706                         /* will proxyAuthz as argv[1] */
707                         li->idassert_mode = LDAP_BACK_IDASSERT_OTHER;
708                         
709                         ber_str2bv( argv[1], 0, 0, &dn );
710
711                         rc = dnNormalize( 0, NULL, NULL, &dn, &li->idassert_dn, NULL );
712                         if ( rc != LDAP_SUCCESS ) {
713 #ifdef NEW_LOGGING
714                                 LDAP_LOG( CONFIG, CRIT, 
715                                         "%s: line %d: idassert DN \"%s\" is invalid.\n",
716                                         fname, lineno, argv[1] );
717 #else
718                                 Debug( LDAP_DEBUG_ANY,
719                                         "%s: line %d: idassert DN \"%s\" is invalid\n",
720                                         fname, lineno, argv[1] );
721 #endif
722                                 return 1;
723                         }
724                 }
725
726         } else if ( strcasecmp( argv[0], "idassert-authz" ) == 0 ) {
727                 struct berval   rule;
728
729                 ber_str2bv( argv[1], 0, 1, &rule );
730
731                 ber_bvarray_add( &li->idassert_authz, &rule );
732
733         } else {
734                 return SLAP_CONF_UNKNOWN;
735         }
736
737         return 0;
738 }
739 #endif /* LDAP_BACK_PROXY_AUTHZ */