]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldap/config.c
fix for select_backend suggested G. Gombas (ITS 1090)
[openldap] / servers / slapd / back-ldap / config.c
1 /* config.c - ldap backend configuration file routine */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7 /* This is an altered version */
8 /*
9  * Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
10  * 
11  * Permission is granted to anyone to use this software for any purpose
12  * on any computer system, and to alter it and redistribute it, subject
13  * to the following restrictions:
14  * 
15  * 1. The author is not responsible for the consequences of use of this
16  *    software, no matter how awful, even if they arise from flaws in it.
17  * 
18  * 2. The origin of this software must not be misrepresented, either by
19  *    explicit claim or by omission.  Since few users ever read sources,
20  *    credits should appear in the documentation.
21  * 
22  * 3. Altered versions must be plainly marked as such, and must not be
23  *    misrepresented as being the original software.  Since few users
24  *    ever read sources, credits should appear in the documentation.
25  * 
26  * 4. This notice may not be removed or altered.
27  *
28  *
29  *
30  * Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
31  * 
32  * This software is being modified by Pierangelo Masarati.
33  * The previously reported conditions apply to the modified code as well.
34  * Changes in the original code are highlighted where required.
35  * Credits for the original code go to the author, Howard Chu.
36  */
37
38 #include "portable.h"
39
40 #include <stdio.h>
41
42 #include <ac/string.h>
43 #include <ac/socket.h>
44
45 #include "slap.h"
46 #include "back-ldap.h"
47
48 int
49 ldap_back_db_config(
50     BackendDB   *be,
51     const char  *fname,
52     int         lineno,
53     int         argc,
54     char        **argv
55 )
56 {
57         struct ldapinfo *li = (struct ldapinfo *) be->be_private;
58
59         if ( li == NULL ) {
60                 fprintf( stderr, "%s: line %d: ldap backend info is null!\n",
61                     fname, lineno );
62                 return( 1 );
63         }
64
65         /* server address to query (depricated, use "uri" directive) */
66         if ( strcasecmp( argv[0], "server" ) == 0 ) {
67                 if (argc != 2) {
68                         fprintf( stderr,
69         "%s: line %d: missing address in \"server <address>\" line\n",
70                             fname, lineno );
71                         return( 1 );
72                 }
73                 if (li->url != NULL)
74                         ch_free(li->url);
75                 li->url = ch_calloc(strlen(argv[1]) + 9, sizeof(char));
76                 if (li->url != NULL) {
77                         strcpy(li->url, "ldap://");
78                         strcat(li->url, argv[1]);
79                         strcat(li->url, "/");
80                 }
81
82         /* URI of server to query (preferred over "server" directive) */
83         } else if ( strcasecmp( argv[0], "uri" ) == 0 ) {
84                 if (argc != 2) {
85                         fprintf( stderr,
86         "%s: line %d: missing address in \"uri <address>\" line\n",
87                             fname, lineno );
88                         return( 1 );
89                 }
90                 if (li->url != NULL)
91                         ch_free(li->url);
92                 li->url = ch_strdup(argv[1]);
93
94         /* name to use for ldap_back_group */
95         } else if ( strcasecmp( argv[0], "binddn" ) == 0 ) {
96                 if (argc != 2) {
97                         fprintf( stderr,
98         "%s: line %d: missing name in \"binddn <name>\" line\n",
99                             fname, lineno );
100                         return( 1 );
101                 }
102                 li->binddn = ch_strdup(argv[1]);
103
104         /* password to use for ldap_back_group */
105         } else if ( strcasecmp( argv[0], "bindpw" ) == 0 ) {
106                 if (argc != 2) {
107                         fprintf( stderr,
108         "%s: line %d: missing password in \"bindpw <password>\" line\n",
109                             fname, lineno );
110                         return( 1 );
111                 }
112                 li->bindpw = ch_strdup(argv[1]);
113         
114         /* dn massaging */
115         } else if ( strcasecmp( argv[0], "suffixmassage" ) == 0 ) {
116                 char *dn, *massaged_dn;
117                 BackendDB *tmp_be;
118                 
119                 if ( argc != 3 ) {
120                         fprintf( stderr,
121         "%s: line %d: syntax is \"suffixMassage <suffix> <massaged suffix>\"\n",
122                                 fname, lineno );
123                         return( 1 );
124                 }
125                 
126                 tmp_be = select_backend( argv[1], 0 );
127                 if ( tmp_be != NULL && tmp_be != be ) {
128                         fprintf( stderr,
129         "%s: line %d: suffix already in use by another backend in"
130         " \"suffixMassage <suffix> <massaged suffix>\"\n",
131                                 fname, lineno );
132                         return( 1 );                                            
133                 }
134
135                 tmp_be = select_backend( argv[2], 0 );
136                 if ( tmp_be != NULL ) {
137                         fprintf( stderr,
138         "%s: line %d: massaged suffix already in use by another backend in" 
139         " \"suffixMassage <suffix> <massaged suffix>\"\n",
140                                 fname, lineno );
141                         return( 1 );
142                 }
143                 
144                 dn = ch_strdup( argv[1] );
145                 charray_add( &li->suffix_massage, dn );
146                 (void) dn_normalize( dn );
147                 charray_add( &li->suffix_massage, dn );
148                 
149                 massaged_dn = ch_strdup( argv[2] );
150                 charray_add( &li->suffix_massage, massaged_dn );
151                 (void) dn_normalize( massaged_dn );
152                 charray_add( &li->suffix_massage, massaged_dn );
153                 
154                 free( dn );
155                 free( massaged_dn );
156
157         /* objectclass/attribute mapping */
158         } else if ( strcasecmp( argv[0], "map" ) == 0 ) {
159                 struct ldapmap *map;
160                 struct ldapmapping *mapping;
161                 char *src, *dst;
162
163                 if ( argc < 3 || argc > 4 ) {
164                         fprintf( stderr,
165         "%s: line %d: syntax is \"map {objectclass | attribute} {<source> | *} [<dest> | *]\"\n",
166                                 fname, lineno );
167                         return( 1 );
168                 }
169
170                 if ( strcasecmp( argv[1], "objectclass" ) == 0 ) {
171                         map = &li->oc_map;
172                 } else if ( strcasecmp( argv[1], "attribute" ) == 0 ) {
173                         map = &li->at_map;
174                 } else {
175                         fprintf( stderr,
176         "%s: line %d: syntax is \"map {objectclass | attribute} {<source> | *} [<dest> | *]\"\n",
177                                 fname, lineno );
178                         return( 1 );
179                 }
180
181                 if ( strcasecmp( argv[2], "*" ) != 0 ) {
182                         src = argv[2];
183                         if ( argc < 4 )
184                                 dst = "";
185                         else if ( strcasecmp( argv[3], "*" ) == 0 )
186                                 dst = src;
187                         else
188                                 dst = argv[3];
189                 } else {
190                         if ( argc < 4 ) {
191                                 map->drop_missing = 1;
192                                 return 0;
193                         }
194                         if ( strcasecmp( argv[3], "*" ) == 0 ) {
195                                 map->drop_missing = 0;
196                                 return 0;
197                         }
198
199                         src = argv[3];
200                         dst = src;
201                 }
202
203                 if ( ( map == &li->at_map )
204                         && ( strcasecmp( src, "objectclass" ) == 0
205                                 || strcasecmp( dst, "objectclass" ) == 0 ) )
206                 {
207                         fprintf( stderr,
208                                 "%s: line %d: objectclass attribute cannot be mapped\n",
209                                 fname, lineno );
210                 }
211
212                 mapping = (struct ldapmapping *)ch_calloc( 2, sizeof(struct ldapmapping) );
213                 if ( mapping == NULL ) {
214                         fprintf( stderr,
215                                 "%s: line %d: out of memory\n",
216                                 fname, lineno );
217                         return( 1 );
218                 }
219                 mapping->src = ch_strdup(src);
220                 mapping->dst = ch_strdup(dst);
221                 if ( *dst != 0 ) {
222                         mapping[1].src = mapping->dst;
223                         mapping[1].dst = mapping->src;
224                 } else {
225                         mapping[1].src = mapping->src;
226                         mapping[1].dst = mapping->dst;
227                 }
228
229                 if ( avl_find( map->map, (caddr_t)mapping, mapping_cmp ) != NULL
230                         || avl_find( map->remap, (caddr_t)&mapping[1], mapping_cmp ) != NULL)
231                 {
232                         fprintf( stderr,
233                                 "%s: line %d: duplicate mapping found (ignored)\n",
234                                 fname, lineno );
235                         return 0;
236                 }
237
238                 avl_insert( &map->map, (caddr_t)mapping,
239                                         mapping_cmp, mapping_dup );
240                 avl_insert( &map->remap, (caddr_t)&mapping[1],
241                                         mapping_cmp, mapping_dup );
242
243         /* anything else */
244         } else {
245                 fprintf( stderr,
246 "%s: line %d: unknown directive \"%s\" in ldap database definition (ignored)\n",
247                     fname, lineno, argv[0] );
248         }
249         return 0;
250 }
251
252 int
253 mapping_cmp ( const void *c1, const void *c2 )
254 {
255         struct ldapmapping *map1 = (struct ldapmapping *)c1;
256         struct ldapmapping *map2 = (struct ldapmapping *)c2;
257
258         return ( strcasecmp(map1->src, map2->src) );
259 }
260
261 int
262 mapping_dup ( void *c1, void *c2 )
263 {
264         struct ldapmapping *map1 = (struct ldapmapping *)c1;
265         struct ldapmapping *map2 = (struct ldapmapping *)c2;
266
267         return( ( strcasecmp(map1->src, map2->src) == 0 ) ? -1 : 0 );
268 }
269
270 char *
271 ldap_back_map ( struct ldapmap *map, char *s, int remap )
272 {
273         Avlnode *tree;
274         struct ldapmapping *mapping, fmapping;
275
276         if (remap)
277                 tree = map->remap;
278         else
279                 tree = map->map;
280
281         fmapping.src = s;
282         mapping = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping, mapping_cmp );
283         if (mapping != NULL) {
284                 if ( *mapping->dst == 0 )
285                         return(NULL);
286                 return(mapping->dst);
287         }
288
289         if (map->drop_missing)
290                 return(NULL);
291
292         return(s);
293 }
294
295 char *
296 ldap_back_map_filter ( struct ldapinfo *li, char *f, int remap )
297 {
298         char *nf, *m, *p, *q, *s, c;
299         int len, extra, plen, in_quote;
300
301         if (f == NULL)
302                 return(NULL);
303
304         len = strlen(f);
305         extra = len;
306         len *= 2;
307         nf = ch_malloc( len + 1 );
308         if (nf == NULL)
309                 return(NULL);
310
311         /* this loop assumes the filter ends with one
312          * of the delimiter chars -- probably ')'.
313          */
314
315         s = nf;
316         q = NULL;
317         in_quote = 0;
318         for (p = f; c = *p; p++) {
319                 if (c == '"') {
320                         in_quote = !in_quote;
321                         if (q != NULL) {
322                                 plen = p - q;
323                                 memcpy(s, q, plen);
324                                 s += plen;
325                                 q = NULL;
326                         }
327                         *s++ = c;
328                 } else if (in_quote) {
329                         /* ignore everything in quotes --
330                          * what about attrs in DNs?
331                          */
332                         *s++ = c;
333                 } else if (c != '(' && c != ')'
334                         && c != '=' && c != '>' && c != '<'
335                         && c != '|' && c != '&')
336                 {
337                         if (q == NULL)
338                                 q = p;
339                 } else {
340                         if (q != NULL) {
341                                 *p = 0;
342                                 m = ldap_back_map(&li->at_map, q, remap);
343                                 if (m == NULL)
344                                         m = ldap_back_map(&li->oc_map, q, remap);
345                                 if (m == NULL) {
346                                         m = q;
347                                 }
348                                 extra += p - q;
349                                 plen = strlen(m);
350                                 extra -= plen;
351                                 if (extra < 0) {
352                                         while (extra < 0) {
353                                                 extra += len;
354                                                 len *= 2;
355                                         }
356                                         s -= (long)nf;
357                                         nf = ch_realloc(nf, len + 1);
358                                         if (nf == NULL) {
359                                                 free(nf);
360                                                 return(NULL);
361                                         }
362                                         s += (long)nf;
363                                 }
364                                 memcpy(s, m, plen);
365                                 s += plen;
366                                 *p = c;
367                                 q = NULL;
368                         }
369                         *s++ = c;
370                 }
371         }
372         *s = 0;
373         return(nf);
374 }
375
376 char **
377 ldap_back_map_attrs ( struct ldapinfo *li, char **a, int remap )
378 {
379         int i, j, count;
380         char **na, *mapped;
381
382         if (a == NULL)
383                 return(NULL);
384
385         for (count = 0; a[count] != NULL; count++) {
386                 /*  */
387         }
388
389         na = (char **)ch_calloc( count + 1, sizeof(char *) );
390         if (na == NULL)
391                 return(NULL);
392
393         for (i = 0, j = 0; i < count; i++) {
394                 mapped = ldap_back_map(&li->at_map, a[i], remap);
395                 if (mapped != NULL) {
396                         mapped = ch_strdup(mapped);
397                         if (mapped == NULL) {
398                                 charray_free(na);
399                                 return(NULL);
400                         }
401                         na[j] = mapped;
402                         j++;
403                 }
404         }
405         return(na);
406 }
407