2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2005 The OpenLDAP Foundation.
5 * Portions Copyright 2001-2003 Pierangelo Masarati.
6 * Portions Copyright 1999-2003 Howard Chu.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
18 * This work was initially developed by the Howard Chu for inclusion
19 * in OpenLDAP Software and subsequently enhanced by Pierangelo
27 #include <ac/string.h>
28 #include <ac/socket.h>
32 #include "../back-ldap/back-ldap.h"
33 #undef ldap_debug /* silence a warning in ldap-int.h */
34 #include "../../../libraries/libldap/ldap-int.h"
35 #include "back-meta.h"
41 struct ldapmapping *mapping;
44 memset( mt, 0, sizeof( metatarget_t ) );
46 mt->mt_rwmap.rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
47 if ( mt->mt_rwmap.rwm_rw == NULL ) {
53 * the filter rewrite as a string must be disabled
54 * by default; it can be re-enabled by adding rules;
55 * this creates an empty rewriteContext
57 rargv[ 0 ] = "rewriteContext";
58 rargv[ 1 ] = "searchFilter";
60 rewrite_parse( mt->mt_rwmap.rwm_rw, "<suffix massage>", 1, 2, rargv );
62 rargv[ 0 ] = "rewriteContext";
63 rargv[ 1 ] = "default";
65 rewrite_parse( mt->mt_rwmap.rwm_rw, "<suffix massage>", 1, 2, rargv );
67 ldap_back_map_init( &mt->mt_rwmap.rwm_at, &mapping );
81 metainfo_t *mi = ( metainfo_t * )be->be_private;
85 "%s: line %d: meta backend info is null!\n",
90 /* URI of server to query */
91 if ( strcasecmp( argv[ 0 ], "uri" ) == 0 ) {
92 int i = mi->mi_ntargets;
95 #endif /* uncomment if uri MUST be a branch of suffix */
96 LDAPURLDesc *ludp, *tmpludp;
103 "%s: line %d: missing address"
104 " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
111 mi->mi_targets = ( metatarget_t * )ch_realloc( mi->mi_targets,
112 sizeof( metatarget_t ) * mi->mi_ntargets );
113 if ( mi->mi_targets == NULL ) {
115 "%s: line %d: out of memory while storing server name"
116 " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
121 if ( new_target( &mi->mi_targets[ i ] ) != 0 ) {
123 "%s: line %d: unable to init server"
124 " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
129 mi->mi_targets[ i ].mt_nretries = mi->mi_nretries;
130 mi->mi_targets[ i ].mt_flags = mi->flags;
131 mi->mi_targets[ i ].mt_version = mi->mi_version;
133 for ( c = 0; c < META_OP_LAST; c++ ) {
134 mi->mi_targets[ i ].mt_timeout[ c ] = mi->mi_timeout[ c ];
140 if ( ldap_url_parselist_ext( &ludp, argv[ 1 ], "\t" ) != LDAP_SUCCESS ) {
142 "%s: line %d: unable to parse URI"
143 " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
149 * uri MUST have the <dn> part!
151 if ( ludp->lud_dn == NULL || ludp->lud_dn[ 0 ] == '\0' ) {
153 "%s: line %d: missing <naming context> "
154 " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
160 * copies and stores uri and suffix
162 dn.bv_val = ludp->lud_dn;
163 dn.bv_len = strlen( ludp->lud_dn );
165 rc = dnPrettyNormal( NULL, &dn, &mi->mi_targets[ i ].mt_psuffix,
166 &mi->mi_targets[ i ].mt_nsuffix, NULL );
167 if( rc != LDAP_SUCCESS ) {
168 fprintf( stderr, "%s: line %d: "
169 "target '%s' DN is invalid\n",
170 fname, lineno, argv[ 1 ] );
174 ludp->lud_dn[ 0 ] = '\0';
176 /* check all, to apply the scope check on the first one */
177 for ( tmpludp = ludp; tmpludp; tmpludp = tmpludp->lud_next ) {
178 if ( tmpludp->lud_dn != NULL && tmpludp->lud_dn[ 0 ] != '\0' ) {
179 fprintf( stderr, "%s: line %d: "
180 "multiple URIs must have "
187 if ( tmpludp->lud_scope == LDAP_SCOPE_BASE ) {
188 tmpludp->lud_scope = LDAP_SCOPE_DEFAULT;
192 mi->mi_targets[ i ].mt_uri = ldap_url_list2urls( ludp );
193 ldap_free_urllist( ludp );
194 if ( mi->mi_targets[ i ].mt_uri == NULL) {
195 fprintf( stderr, "%s: line %d: no memory?\n",
201 * uri MUST be a branch of suffix!
203 #if 0 /* too strict a constraint */
204 if ( select_backend( &mi->mi_targets[ i ].suffix, 0, 0 ) != be ) {
206 "%s: line %d: <naming context> of URI does not refer to current backend"
207 " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
213 * uri MUST be a branch of a suffix!
215 if ( select_backend( &mi->mi_targets[ i ].mt_nsuffix, 0, 0 ) == NULL ) {
217 "%s: line %d: <naming context> of URI does not resolve to a backend"
218 " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
224 /* default target directive */
225 } else if ( strcasecmp( argv[ 0 ], "default-target" ) == 0 ) {
226 int i = mi->mi_ntargets - 1;
231 "%s: line %d: \"default-target\" alone need be"
232 " inside a \"uri\" directive\n",
236 mi->mi_defaulttarget = i;
238 if ( strcasecmp( argv[ 1 ], "none" ) == 0 ) {
241 "%s: line %d: \"default-target none\""
242 " should go before uri definitions\n",
245 mi->mi_defaulttarget = META_DEFAULT_TARGET_NONE;
249 int n = strtol( argv[ 1 ], &next, 10 );
250 if ( n < 0 || n >= i - 1 ) {
252 "%s: line %d: illegal target number %d\n",
256 mi->mi_defaulttarget = n;
260 /* ttl of dn cache */
261 } else if ( strcasecmp( argv[ 0 ], "dncache-ttl" ) == 0 ) {
264 "%s: line %d: missing ttl in \"dncache-ttl <ttl>\" line\n",
269 if ( strcasecmp( argv[ 1 ], "forever" ) == 0 ) {
270 mi->mi_cache.ttl = META_DNCACHE_FOREVER;
271 } else if ( strcasecmp( argv[ 1 ], "disabled" ) == 0 ) {
272 mi->mi_cache.ttl = META_DNCACHE_DISABLED;
274 mi->mi_cache.ttl = atol( argv[ 1 ] );
277 /* network timeout when connecting to ldap servers */
278 } else if ( strcasecmp( argv[ 0 ], "network-timeout" ) == 0 ) {
281 "%s: line %d: missing network timeout in \"network-timeout <seconds>\" line\n",
285 mi->mi_network_timeout = atol(argv[ 1 ]);
287 /* name to use for meta_back_group */
288 } else if ( strcasecmp( argv[ 0 ], "acl-authcDN" ) == 0
289 || strcasecmp( argv[ 0 ], "binddn" ) == 0 )
291 int i = mi->mi_ntargets - 1;
296 "%s: line %d: need \"uri\" directive first\n",
303 "%s: line %d: missing name in \"binddn <name>\" line\n",
308 if ( strcasecmp( argv[ 0 ], "binddn" ) == 0 ) {
309 fprintf( stderr, "%s: line %d: "
310 "\"binddn\" statement is deprecated; "
311 "use \"acl-authcDN\" instead\n",
313 /* FIXME: some day we'll need to throw an error */
316 dn.bv_val = argv[ 1 ];
317 dn.bv_len = strlen( argv[ 1 ] );
318 if ( dnNormalize( 0, NULL, NULL, &dn, &mi->mi_targets[ i ].mt_binddn,
319 NULL ) != LDAP_SUCCESS )
321 fprintf( stderr, "%s: line %d: "
322 "bind DN '%s' is invalid\n",
323 fname, lineno, argv[ 1 ] );
327 /* password to use for meta_back_group */
328 } else if ( strcasecmp( argv[ 0 ], "acl-passwd" ) == 0
329 || strcasecmp( argv[ 0 ], "bindpw" ) == 0 )
331 int i = mi->mi_ntargets - 1;
335 "%s: line %d: need \"uri\" directive first\n",
342 "%s: line %d: missing password in \"bindpw <password>\" line\n",
347 if ( strcasecmp( argv[ 0 ], "bindpw" ) == 0 ) {
348 fprintf( stderr, "%s: line %d: "
349 "\"bindpw\" statement is deprecated; "
350 "use \"acl-passwd\" instead\n",
352 /* FIXME: some day we'll need to throw an error */
355 ber_str2bv( argv[ 1 ], 0L, 1, &mi->mi_targets[ i ].mt_bindpw );
357 /* save bind creds for referral rebinds? */
358 } else if ( strcasecmp( argv[ 0 ], "rebind-as-user" ) == 0 ) {
361 "%s: line %d: \"rebind-as-user {NO|yes}\" takes 1 argument.\n",
368 "%s: line %d: deprecated use of \"rebind-as-user {NO|yes}\" with no arguments.\n",
370 mi->flags |= LDAP_BACK_F_SAVECRED;
373 if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
374 mi->flags &= ~LDAP_BACK_F_SAVECRED;
376 } else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
377 mi->flags |= LDAP_BACK_F_SAVECRED;
381 "%s: line %d: \"rebind-as-user {NO|yes}\" unknown argument \"%s\".\n",
382 fname, lineno, argv[ 1 ] );
387 } else if ( strcasecmp( argv[ 0 ], "chase-referrals" ) == 0 ) {
388 unsigned *flagsp = mi->mi_ntargets ?
389 &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags
394 "%s: line %d: \"chase-referrals\" needs 1 argument.\n",
399 /* this is the default; we add it because the default might change... */
400 if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
401 *flagsp |= LDAP_BACK_F_CHASE_REFERRALS;
403 } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
404 *flagsp &= ~LDAP_BACK_F_CHASE_REFERRALS;
408 "%s: line %d: \"chase-referrals {YES|no}\": unknown argument \"%s\".\n",
409 fname, lineno, argv[ 1 ] );
413 } else if ( strcasecmp( argv[ 0 ], "tls" ) == 0 ) {
414 unsigned *flagsp = mi->mi_ntargets ?
415 &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags
420 "%s: line %d: \"tls <what>\" needs 1 argument.\n",
426 if ( strcasecmp( argv[ 1 ], "start" ) == 0 ) {
427 *flagsp |= ( LDAP_BACK_F_USE_TLS | LDAP_BACK_F_TLS_CRITICAL );
430 } else if ( strcasecmp( argv[ 1 ], "try-start" ) == 0 ) {
431 *flagsp &= ~LDAP_BACK_F_TLS_CRITICAL;
432 *flagsp |= LDAP_BACK_F_USE_TLS;
434 /* propagate start tls */
435 } else if ( strcasecmp( argv[ 1 ], "propagate" ) == 0 ) {
436 *flagsp |= ( LDAP_BACK_F_PROPAGATE_TLS | LDAP_BACK_F_TLS_CRITICAL );
439 } else if ( strcasecmp( argv[ 1 ], "try-propagate" ) == 0 ) {
440 *flagsp &= ~LDAP_BACK_F_TLS_CRITICAL;
441 *flagsp |= LDAP_BACK_F_PROPAGATE_TLS;
445 "%s: line %d: \"tls <what>\": unknown argument \"%s\".\n",
446 fname, lineno, argv[ 1 ] );
450 } else if ( strcasecmp( argv[ 0 ], "t-f-support" ) == 0 ) {
451 unsigned *flagsp = mi->mi_ntargets ?
452 &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags
457 "%s: line %d: \"t-f-support {NO|yes|discover}\" needs 1 argument.\n",
462 if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
463 *flagsp &= ~(LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER);
465 } else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
466 *flagsp |= LDAP_BACK_F_SUPPORT_T_F;
468 } else if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) {
469 *flagsp |= LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
473 "%s: line %d: unknown value \"%s\" for \"t-f-support {no|yes|discover}\".\n",
474 fname, lineno, argv[ 1 ] );
479 } else if ( strcasecmp( argv[ 0 ], "onerr" ) == 0 ) {
482 "%s: line %d: \"onerr {CONTINUE|stop}\" takes 1 argument\n",
487 if ( strcasecmp( argv[ 1 ], "continue" ) == 0 ) {
488 mi->flags &= ~META_BACK_F_ONERR_STOP;
490 } else if ( strcasecmp( argv[ 1 ], "stop" ) == 0 ) {
491 mi->flags |= META_BACK_F_ONERR_STOP;
495 "%s: line %d: \"onerr {CONTINUE|stop}\": invalid arg \"%s\".\n",
496 fname, lineno, argv[ 1 ] );
500 } else if ( strcasecmp( argv[ 0 ], "timeout" ) == 0 ) {
502 time_t *tv = mi->mi_ntargets ?
503 mi->mi_targets[ mi->mi_ntargets - 1 ].mt_timeout
509 "%s: line %d: \"timeout [{add|delete|modify|modrdn}=]<val> [...]\" takes at least 1 argument\n",
514 for ( c = 1; c < argc; c++ ) {
515 time_t *t = NULL, val;
517 sep = strchr( argv[ c ], '=' );
519 size_t len = sep - argv[ c ];
521 if ( strncasecmp( argv[ c ], "add", len ) == 0 ) {
522 t = &tv[ META_OP_ADD ];
523 } else if ( strncasecmp( argv[ c ], "delete", len ) == 0 ) {
524 t = &tv[ META_OP_DELETE ];
525 } else if ( strncasecmp( argv[ c ], "modify", len ) == 0 ) {
526 t = &tv[ META_OP_MODIFY ];
527 } else if ( strncasecmp( argv[ c ], "modrdn", len ) == 0 ) {
528 t = &tv[ META_OP_MODRDN ];
531 "%s: line %d: unknown operation \"%s\" for timeout #%d.\n",
532 fname, lineno, argv[ c ], c );
541 val = strtoul( sep, &next, 10 );
542 if ( next == sep || next[ 0 ] != '\0' ) {
544 "%s: line %d: unable to parse value \"%s\" for timeout.\n",
545 fname, lineno, sep );
555 for ( i = 0; i < META_OP_LAST; i++ ) {
561 /* name to use as pseudo-root dn */
562 } else if ( strcasecmp( argv[ 0 ], "pseudorootdn" ) == 0 ) {
563 int i = mi->mi_ntargets - 1;
568 "%s: line %d: need \"uri\" directive first\n",
575 "%s: line %d: missing name in \"pseudorootdn <name>\" line\n",
580 dn.bv_val = argv[ 1 ];
581 dn.bv_len = strlen( argv[ 1 ] );
582 if ( dnNormalize( 0, NULL, NULL, &dn,
583 &mi->mi_targets[ i ].mt_pseudorootdn, NULL ) != LDAP_SUCCESS )
585 fprintf( stderr, "%s: line %d: "
586 "pseudoroot DN '%s' is invalid\n",
587 fname, lineno, argv[ 1 ] );
591 /* password to use as pseudo-root */
592 } else if ( strcasecmp( argv[ 0 ], "pseudorootpw" ) == 0 ) {
593 int i = mi->mi_ntargets - 1;
597 "%s: line %d: need \"uri\" directive first\n",
604 "%s: line %d: missing password in \"pseudorootpw <password>\" line\n",
608 ber_str2bv( argv[ 1 ], 0L, 1, &mi->mi_targets[ i ].mt_pseudorootpw );
611 } else if ( strcasecmp( argv[ 0 ], "suffixmassage" ) == 0 ) {
613 int i = mi->mi_ntargets - 1;
614 struct berval dn, nvnc, pvnc, nrnc, prnc;
618 "%s: line %d: need \"uri\" directive first\n",
626 * suffixmassage <suffix> <massaged suffix>
628 * the <suffix> field must be defined as a valid suffix
629 * (or suffixAlias?) for the current database;
630 * the <massaged suffix> shouldn't have already been
631 * defined as a valid suffix or suffixAlias for the
636 "%s: line %d: syntax is \"suffixMassage <suffix> <massaged suffix>\"\n",
641 dn.bv_val = argv[ 1 ];
642 dn.bv_len = strlen( argv[ 1 ] );
643 if ( dnPrettyNormal( NULL, &dn, &pvnc, &nvnc, NULL ) != LDAP_SUCCESS ) {
644 fprintf( stderr, "%s: line %d: "
645 "suffix '%s' is invalid\n",
646 fname, lineno, argv[ 1 ] );
650 tmp_be = select_backend( &nvnc, 0, 0 );
651 if ( tmp_be != NULL && tmp_be != be ) {
653 "%s: line %d: suffix already in use by another backend in"
654 " \"suffixMassage <suffix> <massaged suffix>\"\n",
661 dn.bv_val = argv[ 2 ];
662 dn.bv_len = strlen( argv[ 2 ] );
663 if ( dnPrettyNormal( NULL, &dn, &prnc, &nrnc, NULL ) != LDAP_SUCCESS ) {
664 fprintf( stderr, "%s: line %d: "
665 "massaged suffix '%s' is invalid\n",
666 fname, lineno, argv[ 2 ] );
673 tmp_be = select_backend( &nrnc, 0, 0 );
674 if ( tmp_be != NULL ) {
676 "%s: line %d: massaged suffix already in use by another backend in"
677 " \"suffixMassage <suffix> <massaged suffix>\"\n",
688 * The suffix massaging is emulated by means of the
689 * rewrite capabilities
690 * FIXME: no extra rewrite capabilities should be added
693 return suffix_massage_config( mi->mi_targets[ i ].mt_rwmap.rwm_rw,
694 &pvnc, &nvnc, &prnc, &nrnc );
696 /* rewrite stuff ... */
697 } else if ( strncasecmp( argv[ 0 ], "rewrite", 7 ) == 0 ) {
698 int i = mi->mi_ntargets - 1;
701 fprintf( stderr, "%s: line %d: \"rewrite\" "
702 "statement outside target definition.\n",
707 return rewrite_parse( mi->mi_targets[ i ].mt_rwmap.rwm_rw,
708 fname, lineno, argc, argv );
710 /* objectclass/attribute mapping */
711 } else if ( strcasecmp( argv[ 0 ], "map" ) == 0 ) {
712 int i = mi->mi_ntargets - 1;
716 "%s: line %d: need \"uri\" directive first\n",
721 return ldap_back_map_config( &mi->mi_targets[ i ].mt_rwmap.rwm_oc,
722 &mi->mi_targets[ i ].mt_rwmap.rwm_at,
723 fname, lineno, argc, argv );
725 } else if ( strcasecmp( argv[ 0 ], "nretries" ) == 0 ) {
726 int i = mi->mi_ntargets - 1;
727 int nretries = META_RETRY_UNDEFINED;
731 "%s: line %d: need value in \"nretries <value>\"\n",
736 if ( strcasecmp( argv[ 1 ], "forever" ) == 0 ) {
737 nretries = META_RETRY_FOREVER;
739 } else if ( strcasecmp( argv[ 1 ], "never" ) == 0 ) {
740 nretries = META_RETRY_NEVER;
745 nretries = strtol( argv[ 1 ], &next, 10 );
746 if ( next == argv[ 1 ] || next[ 0 ] != '\0' ) {
748 "%s: line %d: unable to parse value \"%s\" in \"nretries <value>\"\n",
749 fname, lineno, argv[ 1 ] );
755 mi->mi_nretries = nretries;
758 mi->mi_targets[ i ].mt_nretries = nretries;
763 return SLAP_CONF_UNKNOWN;
769 ldap_back_map_config(
770 struct ldapmap *oc_map,
771 struct ldapmap *at_map,
778 struct ldapmapping *mapping;
782 if ( argc < 3 || argc > 4 ) {
784 "%s: line %d: syntax is \"map {objectclass | attribute} [<local> | *] {<foreign> | *}\"\n",
789 if ( strcasecmp( argv[ 1 ], "objectclass" ) == 0 ) {
793 } else if ( strcasecmp( argv[ 1 ], "attribute" ) == 0 ) {
797 fprintf( stderr, "%s: line %d: syntax is "
798 "\"map {objectclass | attribute} [<local> | *] "
799 "{<foreign> | *}\"\n",
804 if ( strcmp( argv[ 2 ], "*" ) == 0 ) {
805 if ( argc < 4 || strcmp( argv[ 3 ], "*" ) == 0 ) {
806 map->drop_missing = ( argc < 4 );
809 src = dst = argv[ 3 ];
811 } else if ( argc < 4 ) {
817 dst = ( strcmp( argv[ 3 ], "*" ) == 0 ? src : argv[ 3 ] );
820 if ( ( map == at_map )
821 && ( strcasecmp( src, "objectclass" ) == 0
822 || strcasecmp( dst, "objectclass" ) == 0 ) )
825 "%s: line %d: objectclass attribute cannot be mapped\n",
829 mapping = (struct ldapmapping *)ch_calloc( 2,
830 sizeof(struct ldapmapping) );
831 if ( mapping == NULL ) {
833 "%s: line %d: out of memory\n",
837 ber_str2bv( src, 0, 1, &mapping->src );
838 ber_str2bv( dst, 0, 1, &mapping->dst );
839 mapping[ 1 ].src = mapping->dst;
840 mapping[ 1 ].dst = mapping->src;
846 if ( src[ 0 ] != '\0' ) {
847 if ( oc_bvfind( &mapping->src ) == NULL ) {
849 "%s: line %d: warning, source objectClass '%s' "
850 "should be defined in schema\n",
851 fname, lineno, src );
854 * FIXME: this should become an err
860 if ( oc_bvfind( &mapping->dst ) == NULL ) {
862 "%s: line %d: warning, destination objectClass '%s' "
863 "is not defined in schema\n",
864 fname, lineno, dst );
868 const char *text = NULL;
869 AttributeDescription *ad = NULL;
871 if ( src[ 0 ] != '\0' ) {
872 rc = slap_bv2ad( &mapping->src, &ad, &text );
873 if ( rc != LDAP_SUCCESS ) {
875 "%s: line %d: warning, source attributeType '%s' "
876 "should be defined in schema\n",
877 fname, lineno, src );
880 * FIXME: this should become an err
888 rc = slap_bv2ad( &mapping->dst, &ad, &text );
889 if ( rc != LDAP_SUCCESS ) {
891 "%s: line %d: warning, destination attributeType '%s' "
892 "is not defined in schema\n",
893 fname, lineno, dst );
897 if ( (src[ 0 ] != '\0' && avl_find( map->map, (caddr_t)mapping, mapping_cmp ) != NULL)
898 || avl_find( map->remap, (caddr_t)&mapping[ 1 ], mapping_cmp ) != NULL)
901 "%s: line %d: duplicate mapping found" SLAPD_CONF_UNKNOWN_IGNORED ".\n",
906 if ( src[ 0 ] != '\0' ) {
907 avl_insert( &map->map, (caddr_t)mapping,
908 mapping_cmp, mapping_dup );
910 avl_insert( &map->remap, (caddr_t)&mapping[ 1 ],
911 mapping_cmp, mapping_dup );
917 ch_free( mapping->src.bv_val );
918 ch_free( mapping->dst.bv_val );
926 #ifdef ENABLE_REWRITE
928 suffix_massage_regexize( const char *s )
935 ( r = strchr( p, ',' ) ) != NULL;
939 res = ch_calloc( sizeof( char ),
941 + STRLENOF( "(.+,)?" )
942 + STRLENOF( "[ ]?" ) * i + 1 );
944 ptr = lutil_strcopy( res, "(.+,)?" );
946 ( r = strchr( p, ',' ) ) != NULL;
948 ptr = lutil_strncopy( ptr, p, r - p + 1 );
949 ptr = lutil_strcopy( ptr, "[ ]?" );
951 if ( r[ 1 ] == ' ' ) {
955 lutil_strcopy( ptr, p );
961 suffix_massage_patternize( const char *s )
968 res = ch_calloc( sizeof( char ), len + STRLENOF( "%1" ) + 1 );
974 strcpy( &res[ STRLENOF( "%1" ) ], s );
980 suffix_massage_config(
981 struct rewrite_info *info,
991 rargv[ 0 ] = "rewriteEngine";
994 rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
996 rargv[ 0 ] = "rewriteContext";
997 rargv[ 1 ] = "default";
999 rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
1001 rargv[ 0 ] = "rewriteRule";
1002 rargv[ 1 ] = suffix_massage_regexize( pvnc->bv_val );
1003 rargv[ 2 ] = suffix_massage_patternize( prnc->bv_val );
1006 rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
1007 ch_free( rargv[ 1 ] );
1008 ch_free( rargv[ 2 ] );
1010 rargv[ 0 ] = "rewriteContext";
1011 rargv[ 1 ] = "searchEntryDN";
1013 rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
1015 rargv[ 0 ] = "rewriteRule";
1016 rargv[ 1 ] = suffix_massage_regexize( prnc->bv_val );
1017 rargv[ 2 ] = suffix_massage_patternize( pvnc->bv_val );
1020 rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
1021 ch_free( rargv[ 1 ] );
1022 ch_free( rargv[ 2 ] );
1024 /* backward compatibility */
1025 rargv[ 0 ] = "rewriteContext";
1026 rargv[ 1 ] = "searchResult";
1027 rargv[ 2 ] = "alias";
1028 rargv[ 3 ] = "searchEntryDN";
1030 rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
1032 rargv[ 0 ] = "rewriteContext";
1033 rargv[ 1 ] = "matchedDN";
1034 rargv[ 2 ] = "alias";
1035 rargv[ 3 ] = "searchEntryDN";
1037 rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
1039 rargv[ 0 ] = "rewriteContext";
1040 rargv[ 1 ] = "searchAttrDN";
1041 rargv[ 2 ] = "alias";
1042 rargv[ 3 ] = "searchEntryDN";
1044 rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
1046 /* NOTE: this corresponds to #undef'ining RWM_REFERRAL_REWRITE;
1047 * see servers/slapd/overlays/rwm.h for details */
1048 rargv[ 0 ] = "rewriteContext";
1049 rargv[ 1 ] = "referralAttrDN";
1051 rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
1053 rargv[ 0 ] = "rewriteContext";
1054 rargv[ 1 ] = "referralDN";
1056 rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
1060 #endif /* ENABLE_REWRITE */