]> git.sur5r.net Git - openldap/blob - servers/slapd/overlays/rwmconf.c
6f5812e69ac019179d3890f11032b9cc81c1b169
[openldap] / servers / slapd / overlays / rwmconf.c
1 /* rwmconf.c - rewrite/map configuration file routines */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1999-2003 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 "rwm.h"
33 #include "lutil.h"
34
35 int
36 rwm_map_config(
37                 struct ldapmap  *oc_map,
38                 struct ldapmap  *at_map,
39                 const char      *fname,
40                 int             lineno,
41                 int             argc,
42                 char            **argv )
43 {
44         struct ldapmap          *map;
45         struct ldapmapping      *mapping;
46         char                    *src, *dst;
47         int                     is_oc = 0;
48
49         if ( argc < 3 || argc > 4 ) {
50                 fprintf( stderr,
51         "%s: line %d: syntax is \"map {objectclass | attribute} [<local> | *] {<foreign> | *}\"\n",
52                         fname, lineno );
53                 return 1;
54         }
55
56         if ( strcasecmp( argv[1], "objectclass" ) == 0 ) {
57                 map = oc_map;
58                 is_oc = 1;
59
60         } else if ( strcasecmp( argv[1], "attribute" ) == 0 ) {
61                 map = at_map;
62
63         } else {
64                 fprintf( stderr, "%s: line %d: syntax is "
65                         "\"map {objectclass | attribute} [<local> | *] "
66                         "{<foreign> | *}\"\n",
67                         fname, lineno );
68                 return 1;
69         }
70
71         if ( strcmp( argv[2], "*" ) == 0 ) {
72                 if ( argc < 4 || strcmp( argv[3], "*" ) == 0 ) {
73                         map->drop_missing = ( argc < 4 );
74                         return 0;
75                 }
76                 src = dst = argv[3];
77
78         } else if ( argc < 4 ) {
79                 src = "";
80                 dst = argv[2];
81
82         } else {
83                 src = argv[2];
84                 dst = ( strcmp( argv[3], "*" ) == 0 ? src : argv[3] );
85         }
86
87         if ( ( map == at_map )
88                         && ( strcasecmp( src, "objectclass" ) == 0
89                         || strcasecmp( dst, "objectclass" ) == 0 ) )
90         {
91                 fprintf( stderr,
92                         "%s: line %d: objectclass attribute cannot be mapped\n",
93                         fname, lineno );
94         }
95
96         mapping = (struct ldapmapping *)ch_calloc( 2,
97                 sizeof(struct ldapmapping) );
98         if ( mapping == NULL ) {
99                 fprintf( stderr,
100                         "%s: line %d: out of memory\n",
101                         fname, lineno );
102                 return 1;
103         }
104         ber_str2bv( src, 0, 1, &mapping->src );
105         ber_str2bv( dst, 0, 1, &mapping->dst );
106         mapping[1].src = mapping->dst;
107         mapping[1].dst = mapping->src;
108
109         /*
110          * schema check
111          */
112         if ( is_oc ) {
113                 if ( src[0] != '\0' ) {
114                         if ( oc_bvfind( &mapping->src ) == NULL ) {
115                                 fprintf( stderr,
116         "%s: line %d: warning, source objectClass '%s' "
117         "should be defined in schema\n",
118                                         fname, lineno, src );
119
120                                 /*
121                                  * FIXME: this should become an err
122                                  */
123                         }
124                 }
125
126                 if ( oc_bvfind( &mapping->dst ) == NULL ) {
127                         fprintf( stderr,
128         "%s: line %d: warning, destination objectClass '%s' "
129         "is not defined in schema\n",
130                                 fname, lineno, dst );
131                 }
132         } else {
133                 int                     rc;
134                 const char              *text = NULL;
135                 AttributeDescription    *ad = NULL;
136
137                 if ( src[0] != '\0' ) {
138                         rc = slap_bv2ad( &mapping->src, &ad, &text );
139                         if ( rc != LDAP_SUCCESS ) {
140                                 fprintf( stderr,
141         "%s: line %d: warning, source attributeType '%s' "
142         "should be defined in schema\n",
143                                         fname, lineno, src );
144
145                                 /*
146                                  * FIXME: this should become an err
147                                  */
148                         }
149
150                         ad = NULL;
151                 }
152
153                 rc = slap_bv2ad( &mapping->dst, &ad, &text );
154                 if ( rc != LDAP_SUCCESS ) {
155                         fprintf( stderr,
156         "%s: line %d: warning, destination attributeType '%s' "
157         "is not defined in schema\n",
158                                 fname, lineno, dst );
159                 }
160         }
161
162         if ( (src[0] != '\0' && avl_find( map->map, (caddr_t)mapping, mapping_cmp ) != NULL)
163                         || avl_find( map->remap, (caddr_t)&mapping[1], mapping_cmp ) != NULL)
164         {
165                 fprintf( stderr,
166                         "%s: line %d: duplicate mapping found (ignored)\n",
167                         fname, lineno );
168                 /* FIXME: free stuff */
169                 goto error_return;
170         }
171
172         if ( src[0] != '\0' ) {
173                 avl_insert( &map->map, (caddr_t)mapping,
174                                         mapping_cmp, mapping_dup );
175         }
176         avl_insert( &map->remap, (caddr_t)&mapping[1],
177                                 mapping_cmp, mapping_dup );
178
179         return 0;
180
181 error_return:;
182         if ( mapping ) {
183                 ch_free( mapping->src.bv_val );
184                 ch_free( mapping->dst.bv_val );
185                 ch_free( mapping );
186         }
187
188         return 1;
189 }
190
191 #ifdef ENABLE_REWRITE
192 static char *
193 suffix_massage_regexize( const char *s )
194 {
195         char *res, *ptr;
196         const char *p, *r;
197         int i;
198
199         for ( i = 0, p = s; 
200                         ( r = strchr( p, ',' ) ) != NULL; 
201                         p = r + 1, i++ )
202                 ;
203
204         res = ch_calloc( sizeof( char ), strlen( s ) + 4 + 4*i + 1 );
205
206         ptr = lutil_strcopy( res, "(.*)" );
207         for ( i = 0, p = s;
208                         ( r = strchr( p, ',' ) ) != NULL;
209                         p = r + 1 , i++ ) {
210                 ptr = lutil_strncopy( ptr, p, r - p + 1 );
211                 ptr = lutil_strcopy( ptr, "[ ]?" );
212
213                 if ( r[ 1 ] == ' ' ) {
214                         r++;
215                 }
216         }
217         lutil_strcopy( ptr, p );
218
219         return res;
220 }
221
222 static char *
223 suffix_massage_patternize( const char *s )
224 {
225         ber_len_t       len;
226         char            *res;
227
228         len = strlen( s );
229
230         res = ch_calloc( sizeof( char ), len + sizeof( "%1" ) );
231         if ( res == NULL ) {
232                 return NULL;
233         }
234
235         strcpy( res, "%1" );
236         strcpy( res + sizeof( "%1" ) - 1, s );
237
238         return res;
239 }
240
241 int
242 suffix_massage_config( 
243                 struct rewrite_info *info,
244                 struct berval *pvnc,
245                 struct berval *nvnc,
246                 struct berval *prnc,
247                 struct berval *nrnc
248 )
249 {
250         char *rargv[ 5 ];
251         int line = 0;
252
253         rargv[ 0 ] = "rewriteEngine";
254         rargv[ 1 ] = "on";
255         rargv[ 2 ] = NULL;
256         rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
257
258         rargv[ 0 ] = "rewriteContext";
259         rargv[ 1 ] = "default";
260         rargv[ 2 ] = NULL;
261         rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
262
263         rargv[ 0 ] = "rewriteRule";
264         rargv[ 1 ] = suffix_massage_regexize( pvnc->bv_val );
265         rargv[ 2 ] = suffix_massage_patternize( prnc->bv_val );
266         rargv[ 3 ] = ":";
267         rargv[ 4 ] = NULL;
268         rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
269         ch_free( rargv[ 1 ] );
270         ch_free( rargv[ 2 ] );
271         
272         rargv[ 0 ] = "rewriteContext";
273         rargv[ 1 ] = "searchResultDN";
274         rargv[ 2 ] = NULL;
275         rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
276         
277         rargv[ 0 ] = "rewriteRule";
278         rargv[ 1 ] = suffix_massage_regexize( prnc->bv_val );
279         rargv[ 2 ] = suffix_massage_patternize( pvnc->bv_val );
280         rargv[ 3 ] = ":";
281         rargv[ 4 ] = NULL;
282         rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
283         ch_free( rargv[ 1 ] );
284         ch_free( rargv[ 2 ] );
285
286         rargv[ 0 ] = "rewriteContext";
287         rargv[ 1 ] = "matchedDN";
288         rargv[ 2 ] = "alias";
289         rargv[ 3 ] = "searchResultDN";
290         rargv[ 4 ] = NULL;
291         rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
292
293         rargv[ 0 ] = "rewriteContext";
294         rargv[ 1 ] = "searchAttrDN";
295         rargv[ 2 ] = "alias";
296         rargv[ 3 ] = "searchResultDN";
297         rargv[ 4 ] = NULL;
298         rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
299
300         return 0;
301 }
302 #endif /* ENABLE_REWRITE */