]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldap/map.c
more fixes/updates
[openldap] / servers / slapd / back-ldap / map.c
1 /* map.c - ldap backend mapping routines */
2 /*
3  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /* This is an altered version */
7 /*
8  * Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
9  * 
10  * Permission is granted to anyone to use this software for any purpose
11  * on any computer system, and to alter it and redistribute it, subject
12  * to the following restrictions:
13  * 
14  * 1. The author is not responsible for the consequences of use of this
15  *    software, no matter how awful, even if they arise from flaws in it.
16  * 
17  * 2. The origin of this software must not be misrepresented, either by
18  *    explicit claim or by omission.  Since few users ever read sources,
19  *    credits should appear in the documentation.
20  * 
21  * 3. Altered versions must be plainly marked as such, and must not be
22  *    misrepresented as being the original software.  Since few users
23  *    ever read sources, credits should appear in the documentation.
24  * 
25  * 4. This notice may not be removed or altered.
26  *
27  *
28  *
29  * Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
30  * 
31  * This software is being modified by Pierangelo Masarati.
32  * The previously reported conditions apply to the modified code as well.
33  * Changes in the original code are highlighted where required.
34  * Credits for the original code go to the author, Howard Chu.
35  */
36
37 #include "portable.h"
38
39 #include <stdio.h>
40
41 #include <ac/string.h>
42 #include <ac/socket.h>
43
44 #include "slap.h"
45 #include "back-ldap.h"
46
47 int
48 mapping_cmp ( const void *c1, const void *c2 )
49 {
50         struct ldapmapping *map1 = (struct ldapmapping *)c1;
51         struct ldapmapping *map2 = (struct ldapmapping *)c2;
52         int rc = map1->src.bv_len - map2->src.bv_len;
53         if (rc) return rc;
54         return ( strcasecmp(map1->src.bv_val, map2->src.bv_val) );
55 }
56
57 int
58 mapping_dup ( void *c1, void *c2 )
59 {
60         struct ldapmapping *map1 = (struct ldapmapping *)c1;
61         struct ldapmapping *map2 = (struct ldapmapping *)c2;
62
63         return( ( strcasecmp(map1->src.bv_val, map2->src.bv_val) == 0 ) ? -1 : 0 );
64 }
65
66 void
67 ldap_back_map_init ( struct ldapmap *lm, struct ldapmapping **m )
68 {
69         struct ldapmapping *mapping;
70
71         assert( m );
72
73         *m = NULL;
74         
75         mapping = (struct ldapmapping *)ch_calloc( 2, 
76                         sizeof( struct ldapmapping ) );
77         if ( mapping == NULL ) {
78                 return;
79         }
80
81         ber_str2bv( "objectclass", sizeof("objectclass")-1, 1, &mapping->src);
82         ber_dupbv( &mapping->dst, &mapping->src );
83         mapping[1].src = mapping->src;
84         mapping[1].dst = mapping->dst;
85
86         avl_insert( &lm->map, (caddr_t)mapping, 
87                         mapping_cmp, mapping_dup );
88         avl_insert( &lm->remap, (caddr_t)&mapping[1], 
89                         mapping_cmp, mapping_dup );
90         *m = mapping;
91 }
92
93 void
94 ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv,
95         int remap )
96 {
97         Avlnode *tree;
98         struct ldapmapping *mapping, fmapping;
99
100         if (remap)
101                 tree = map->remap;
102         else
103                 tree = map->map;
104
105         bv->bv_len = 0;
106         bv->bv_val = NULL;
107         fmapping.src = *s;
108         mapping = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping, mapping_cmp );
109         if (mapping != NULL) {
110                 if ( mapping->dst.bv_val )
111                         *bv = mapping->dst;
112                 return;
113         }
114
115         if (!map->drop_missing)
116                 *bv = *s;
117
118         return;
119 }
120
121 char *
122 ldap_back_map_filter(
123                 struct ldapmap *at_map,
124                 struct ldapmap *oc_map,
125                 struct berval *f,
126                 int remap
127 )
128 {
129         char *nf, *p, *q, *s, c;
130         int len, extra, plen, in_quote;
131         struct berval m, tmp;
132
133         if (f == NULL)
134                 return(NULL);
135
136         len = f->bv_len;
137         extra = len;
138         len *= 2;
139         nf = ch_malloc( len + 1 );
140         if (nf == NULL)
141                 return(NULL);
142
143         /* this loop assumes the filter ends with one
144          * of the delimiter chars -- probably ')'.
145          */
146
147         s = nf;
148         q = NULL;
149         in_quote = 0;
150         for (p = f->bv_val; (c = *p); p++) {
151                 if (c == '"') {
152                         in_quote = !in_quote;
153                         if (q != NULL) {
154                                 plen = p - q;
155                                 AC_MEMCPY(s, q, plen);
156                                 s += plen;
157                                 q = NULL;
158                         }
159                         *s++ = c;
160                 } else if (in_quote) {
161                         /* ignore everything in quotes --
162                          * what about attrs in DNs?
163                          */
164                         *s++ = c;
165                 } else if (c != '(' && c != ')'
166                         && c != '=' && c != '>' && c != '<'
167                         && c != '|' && c != '&')
168                 {
169                         if (q == NULL)
170                                 q = p;
171                 } else {
172                         if (q != NULL) {
173                                 *p = 0;
174                                 tmp.bv_len = p - q;
175                                 tmp.bv_val = q;
176                                 ldap_back_map(at_map, &tmp, &m, remap);
177                                 if (m.bv_val == NULL)
178                                         ldap_back_map(oc_map, &tmp, &m, remap);
179                                 if (m.bv_val == NULL) {
180                                         m = tmp;
181                                 }
182                                 extra += p - q;
183                                 plen = m.bv_len;
184                                 extra -= plen;
185                                 if (extra < 0) {
186                                         while (extra < 0) {
187                                                 extra += len;
188                                                 len *= 2;
189                                         }
190                                         s -= (long)nf;
191                                         nf = ch_realloc(nf, len + 1);
192                                         if (nf == NULL) {
193                                                 free(nf);
194                                                 return(NULL);
195                                         }
196                                         s += (long)nf;
197                                 }
198                                 AC_MEMCPY(s, m.bv_val, plen);
199                                 s += plen;
200                                 *p = c;
201                                 q = NULL;
202                         }
203                         *s++ = c;
204                 }
205         }
206         *s = 0;
207         return(nf);
208 }
209
210 char **
211 ldap_back_map_attrs(
212                 struct ldapmap *at_map,
213                 AttributeName *an,
214                 int remap
215 )
216 {
217         int i;
218         char **na;
219         struct berval mapped;
220
221         if (an == NULL)
222                 return(NULL);
223
224         for (i = 0; an[i].an_name.bv_val; i++) {
225                 /*  */
226         }
227
228         na = (char **)ch_calloc( i + 1, sizeof(char *) );
229         if (na == NULL)
230                 return(NULL);
231
232         for (i = 0; an[i].an_name.bv_val; ) {
233                 ldap_back_map(at_map, &an[i].an_name, &mapped, remap);
234                 if (mapped.bv_val != NULL) {
235                         na[i] = mapped.bv_val;
236                         i++;
237                 }
238         }
239         na[i] = NULL;
240
241         return(na);
242 }
243