1 /* rwmconf.c - rewrite/map configuration file routines */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/rwmconf.c,v 1.25.2.3 2008/02/11 23:26:48 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1999-2008 The OpenLDAP Foundation.
6 * Portions Copyright 1999-2003 Howard Chu.
7 * Portions Copyright 2000-2003 Pierangelo Masarati.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted only as authorized by the OpenLDAP
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>.
19 * This work was initially developed by the Howard Chu for inclusion
20 * in OpenLDAP Software and subsequently enhanced by Pierangelo
30 #include <ac/string.h>
31 #include <ac/socket.h>
39 struct ldapmap
*oc_map
,
40 struct ldapmap
*at_map
,
47 struct ldapmapping
*mapping
;
52 if ( argc
< 3 || argc
> 4 ) {
54 "%s: line %d: syntax is \"map {objectclass | attribute} [<local> | *] {<foreign> | *}\"\n",
59 if ( strcasecmp( argv
[1], "objectclass" ) == 0 ) {
63 } else if ( strcasecmp( argv
[1], "attribute" ) == 0 ) {
67 fprintf( stderr
, "%s: line %d: syntax is "
68 "\"map {objectclass | attribute} [<local> | *] "
69 "{<foreign> | *}\"\n",
74 if ( strcmp( argv
[2], "*" ) == 0 ) {
75 if ( argc
< 4 || strcmp( argv
[3], "*" ) == 0 ) {
76 map
->drop_missing
= ( argc
< 4 );
81 } else if ( argc
< 4 ) {
87 dst
= ( strcmp( argv
[3], "*" ) == 0 ? src
: argv
[3] );
90 if ( ( map
== at_map
)
91 && ( strcasecmp( src
, "objectclass" ) == 0
92 || strcasecmp( dst
, "objectclass" ) == 0 ) )
95 "%s: line %d: objectclass attribute cannot be mapped\n",
100 mapping
= (struct ldapmapping
*)ch_calloc( 2,
101 sizeof(struct ldapmapping
) );
102 if ( mapping
== NULL
) {
104 "%s: line %d: out of memory\n",
108 ber_str2bv( src
, 0, 1, &mapping
[0].m_src
);
109 ber_str2bv( dst
, 0, 1, &mapping
[0].m_dst
);
110 mapping
[1].m_src
= mapping
[0].m_dst
;
111 mapping
[1].m_dst
= mapping
[0].m_src
;
113 mapping
[0].m_flags
= RWMMAP_F_NONE
;
114 mapping
[1].m_flags
= RWMMAP_F_NONE
;
120 if ( src
[0] != '\0' ) {
121 mapping
[0].m_src_oc
= oc_bvfind( &mapping
[0].m_src
);
122 if ( mapping
[0].m_src_oc
== NULL
) {
124 "%s: line %d: warning, source objectClass '%s' "
125 "should be defined in schema\n",
126 fname
, lineno
, src
);
129 * FIXME: this should become an err
131 mapping
[0].m_src_oc
= ch_malloc( sizeof( ObjectClass
) );
132 memset( mapping
[0].m_src_oc
, 0, sizeof( ObjectClass
) );
133 mapping
[0].m_src_oc
->soc_cname
= mapping
[0].m_src
;
134 mapping
[0].m_flags
|= RWMMAP_F_FREE_SRC
;
136 mapping
[1].m_dst_oc
= mapping
[0].m_src_oc
;
139 mapping
[0].m_dst_oc
= oc_bvfind( &mapping
[0].m_dst
);
140 if ( mapping
[0].m_dst_oc
== NULL
) {
142 "%s: line %d: warning, destination objectClass '%s' "
143 "is not defined in schema\n",
144 fname
, lineno
, dst
);
146 mapping
[0].m_dst_oc
= oc_bvfind_undef( &mapping
[0].m_dst
);
147 if ( mapping
[0].m_dst_oc
== NULL
) {
148 fprintf( stderr
, "%s: line %d: unable to mimic destination objectClass '%s'\n",
149 fname
, lineno
, dst
);
153 mapping
[1].m_src_oc
= mapping
[0].m_dst_oc
;
155 mapping
[0].m_flags
|= RWMMAP_F_IS_OC
;
156 mapping
[1].m_flags
|= RWMMAP_F_IS_OC
;
160 const char *text
= NULL
;
162 if ( src
[0] != '\0' ) {
163 rc
= slap_bv2ad( &mapping
[0].m_src
,
164 &mapping
[0].m_src_ad
, &text
);
165 if ( rc
!= LDAP_SUCCESS
) {
167 "%s: line %d: warning, source attributeType '%s' "
168 "should be defined in schema\n",
169 fname
, lineno
, src
);
172 * we create a fake "proxied" ad
176 rc
= slap_bv2undef_ad( &mapping
[0].m_src
,
177 &mapping
[0].m_src_ad
, &text
,
179 if ( rc
!= LDAP_SUCCESS
) {
181 "%s: line %d: source attributeType '%s': %d (%s)\n",
182 fname
, lineno
, src
, rc
, text
? text
: "null" );
187 mapping
[1].m_dst_ad
= mapping
[0].m_src_ad
;
190 rc
= slap_bv2ad( &mapping
[0].m_dst
, &mapping
[0].m_dst_ad
, &text
);
191 if ( rc
!= LDAP_SUCCESS
) {
193 "%s: line %d: warning, destination attributeType '%s' "
194 "is not defined in schema\n",
195 fname
, lineno
, dst
);
197 rc
= slap_bv2undef_ad( &mapping
[0].m_dst
,
198 &mapping
[0].m_dst_ad
, &text
,
200 if ( rc
!= LDAP_SUCCESS
) {
202 "%s: line %d: destination attributeType '%s': %d (%s)\n",
203 fname
, lineno
, dst
, rc
, text
? text
: "null" );
207 mapping
[1].m_src_ad
= mapping
[0].m_dst_ad
;
210 if ( ( src
[0] != '\0' && avl_find( map
->map
, (caddr_t
)mapping
, rwm_mapping_cmp
) != NULL
)
211 || avl_find( map
->remap
, (caddr_t
)&mapping
[1], rwm_mapping_cmp
) != NULL
)
214 "%s: line %d: duplicate mapping found.\n",
216 /* FIXME: free stuff */
220 if ( src
[0] != '\0' ) {
221 avl_insert( &map
->map
, (caddr_t
)&mapping
[0],
222 rwm_mapping_cmp
, rwm_mapping_dup
);
224 avl_insert( &map
->remap
, (caddr_t
)&mapping
[1],
225 rwm_mapping_cmp
, rwm_mapping_dup
);
228 if ( !is_oc
&& map
->map
== NULL
) {
229 /* only init if required */
230 rc
= rwm_map_init( map
, &mapping
) != LDAP_SUCCESS
;
237 rwm_mapping_free( mapping
);
244 rwm_suffix_massage_regexize( const char *s
)
250 if ( s
[0] == '\0' ) {
251 return ch_strdup( "^(.+)$" );
255 ( r
= strchr( p
, ',' ) ) != NULL
;
259 res
= ch_calloc( sizeof( char ), strlen( s
)
260 + STRLENOF( "((.+),)?" )
261 + STRLENOF( "[ ]?" ) * i
262 + STRLENOF( "$" ) + 1 );
264 ptr
= lutil_strcopy( res
, "((.+),)?" );
266 ( r
= strchr( p
, ',' ) ) != NULL
;
268 ptr
= lutil_strncopy( ptr
, p
, r
- p
+ 1 );
269 ptr
= lutil_strcopy( ptr
, "[ ]?" );
271 if ( r
[ 1 ] == ' ' ) {
275 ptr
= lutil_strcopy( ptr
, p
);
283 rwm_suffix_massage_patternize( const char *s
, const char *p
)
290 if ( s
[ 0 ] == '\0' ) {
294 res
= ch_calloc( sizeof( char ), len
+ STRLENOF( "%1" ) + 1 );
299 ptr
= lutil_strcopy( res
, ( p
[0] == '\0' ? "%2" : "%1" ) );
300 if ( s
[ 0 ] == '\0' ) {
304 lutil_strcopy( ptr
, p
);
310 rwm_suffix_massage_config(
311 struct rewrite_info
*info
,
321 rargv
[ 0 ] = "rewriteEngine";
324 rewrite_parse( info
, "<suffix massage>", ++line
, 2, rargv
);
326 rargv
[ 0 ] = "rewriteContext";
327 rargv
[ 1 ] = "default";
329 rewrite_parse( info
, "<suffix massage>", ++line
, 2, rargv
);
331 rargv
[ 0 ] = "rewriteRule";
332 rargv
[ 1 ] = rwm_suffix_massage_regexize( pvnc
->bv_val
);
333 rargv
[ 2 ] = rwm_suffix_massage_patternize( pvnc
->bv_val
, prnc
->bv_val
);
336 rewrite_parse( info
, "<suffix massage>", ++line
, 4, rargv
);
337 ch_free( rargv
[ 1 ] );
338 ch_free( rargv
[ 2 ] );
340 if ( BER_BVISEMPTY( pvnc
) ) {
341 rargv
[ 0 ] = "rewriteRule";
343 rargv
[ 2 ] = prnc
->bv_val
;
346 rewrite_parse( info
, "<suffix massage>", ++line
, 4, rargv
);
349 rargv
[ 0 ] = "rewriteContext";
350 rargv
[ 1 ] = "searchEntryDN";
352 rewrite_parse( info
, "<suffix massage>", ++line
, 2, rargv
);
354 rargv
[ 0 ] = "rewriteRule";
355 rargv
[ 1 ] = rwm_suffix_massage_regexize( prnc
->bv_val
);
356 rargv
[ 2 ] = rwm_suffix_massage_patternize( prnc
->bv_val
, pvnc
->bv_val
);
359 rewrite_parse( info
, "<suffix massage>", ++line
, 4, rargv
);
360 ch_free( rargv
[ 1 ] );
361 ch_free( rargv
[ 2 ] );
363 if ( BER_BVISEMPTY( prnc
) ) {
364 rargv
[ 0 ] = "rewriteRule";
366 rargv
[ 2 ] = pvnc
->bv_val
;
369 rewrite_parse( info
, "<suffix massage>", ++line
, 4, rargv
);
372 rargv
[ 0 ] = "rewriteContext";
373 rargv
[ 1 ] = "matchedDN";
374 rargv
[ 2 ] = "alias";
375 rargv
[ 3 ] = "searchEntryDN";
377 rewrite_parse( info
, "<suffix massage>", ++line
, 4, rargv
);
379 #ifdef RWM_REFERRAL_REWRITE
380 /* FIXME: we don't want this on by default, do we? */
381 rargv
[ 0 ] = "rewriteContext";
382 rargv
[ 1 ] = "referralDN";
383 rargv
[ 2 ] = "alias";
384 rargv
[ 3 ] = "searchEntryDN";
386 rewrite_parse( info
, "<suffix massage>", ++line
, 4, rargv
);
387 #else /* ! RWM_REFERRAL_REWRITE */
388 rargv
[ 0 ] = "rewriteContext";
389 rargv
[ 1 ] = "referralAttrDN";
391 rewrite_parse( info
, "<suffix massage>", ++line
, 2, rargv
);
393 rargv
[ 0 ] = "rewriteContext";
394 rargv
[ 1 ] = "referralDN";
396 rewrite_parse( info
, "<suffix massage>", ++line
, 2, rargv
);
397 #endif /* ! RWM_REFERRAL_REWRITE */
399 rargv
[ 0 ] = "rewriteContext";
400 rargv
[ 1 ] = "searchAttrDN";
401 rargv
[ 2 ] = "alias";
402 rargv
[ 3 ] = "searchEntryDN";
404 rewrite_parse( info
, "<suffix massage>", ++line
, 4, rargv
);
409 #endif /* SLAPD_OVER_RWM */