]> git.sur5r.net Git - openldap/blob - servers/slapd/ad.c
abeac6f4dc71487af8146d4bf22e938e05440ff2
[openldap] / servers / slapd / ad.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /* ad.c - routines for dealing with attribute descriptions */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/ctype.h>
13 #include <ac/errno.h>
14 #include <ac/socket.h>
15 #include <ac/string.h>
16 #include <ac/time.h>
17
18 #include "ldap_pvt.h"
19 #include "slap.h"
20
21 #ifdef SLAPD_SCHEMA_NOT_COMPAT
22 AttributeDescription *ad_dup(
23         AttributeDescription *desc )
24 {
25         AttributeDescription *ad;
26
27         if( desc == NULL ) {
28                 return NULL;
29         }
30
31         ad = (AttributeDescription *) ch_malloc( sizeof(AttributeDescription) );
32
33         *ad = *desc;
34
35         if( ad->ad_cname != NULL ) {
36                 ad->ad_cname = ber_bvdup( ad->ad_cname );
37         }
38
39         if( ad->ad_lang != NULL ) {
40                 ad->ad_lang = ch_strdup( ad->ad_lang );
41         }
42
43         return ad;
44 }
45
46 void
47 ad_free( AttributeDescription *ad, int freeit )
48 {
49         if( ad == NULL ) return;
50
51         if( ad->ad_cname != NULL ) {
52                 ber_bvfree( ad->ad_cname );
53         }
54
55         free( ad->ad_lang );
56
57         if( freeit ) free( ad );
58 }
59
60 static int ad_keystring(
61         struct berval *bv )
62 {
63         ber_len_t i;
64
65         if( !AD_CHAR( bv->bv_val[0] ) ) {
66                 return 1;
67         }
68
69         for( i=1; i<bv->bv_len; i++ ) {
70                 if( !AD_CHAR( bv->bv_val[i] ) ) {
71                         return 1;
72                 }
73         }
74         return 0;
75 }
76
77 int slap_str2ad(
78         const char *str,
79         AttributeDescription **ad,
80         char **text )
81 {
82         struct berval bv;
83         bv.bv_val = (char *) str;
84         bv.bv_len = strlen( str );
85
86         return slap_bv2ad( &bv, ad, text );
87 }
88
89 int slap_bv2ad(
90         struct berval *bv,
91         AttributeDescription **ad,
92         char **text )
93 {
94         int rtn = LDAP_UNDEFINED_TYPE;
95         int i;
96         AttributeDescription desc;
97         char **tokens;
98
99         assert( ad != NULL );
100         assert( *text != NULL );
101
102         if( bv == NULL || bv->bv_len == 0 ) {
103                 *text = "empty attribute description";
104                 return rtn;
105         }
106
107         /* make sure description is IA5 */
108         if( ad_keystring( bv ) ) {
109                 *text = "attribute description contains inappropriate characters";
110                 return rtn;
111         }
112
113         tokens = str2charray( bv->bv_val, ";");
114
115         if( tokens == NULL || *tokens == NULL ) {
116                 *text = "no attribute type";
117                 goto done;
118         }
119
120         desc.ad_type = at_find( *tokens );
121
122         if( desc.ad_type == NULL ) {
123                 *text = "attribute type undefined";
124                 goto done;
125         }
126
127         desc.ad_flags = SLAP_DESC_NONE;
128         desc.ad_lang = NULL;
129
130         for( i=1; tokens[i] != NULL; i++ ) {
131                 if( strcasecmp( tokens[i], "binary" ) == 0 ) {
132                         if( desc.ad_flags & SLAP_DESC_BINARY ) {
133                                 *text = "option \"binary\" specified multiple times";
134                                 goto done;
135                         }
136
137                         if(!( desc.ad_type->sat_syntax->ssyn_flags
138                                 & SLAP_SYNTAX_BINARY ))
139                         {
140                                 /* not stored in binary, disallow option */
141                                 *text = "option \"binary\" with type not supported";
142                                 goto done;
143                         }
144
145                         desc.ad_flags |= SLAP_DESC_BINARY;
146
147                 } else if ( strncasecmp( tokens[i], "lang-",
148                         sizeof("lang-")-1 ) == 0 && tokens[i][sizeof("lang-")-1] )
149                 {
150                         if( desc.ad_lang != NULL ) {
151                                 *text = "multiple language tag options specified";
152                                 goto done;
153                         }
154                         desc.ad_lang = tokens[i];
155
156                         /* normalize to all lower case, it's easy */
157                         ldap_pvt_str2lower( desc.ad_lang );
158
159                 } else {
160                         *text = "unrecognized option";
161                         goto done;
162                 }
163         }
164
165         desc.ad_cname = ch_malloc( sizeof( struct berval ) );
166
167         desc.ad_cname->bv_len = strlen( desc.ad_type->sat_cname );
168         if( desc.ad_flags & SLAP_DESC_BINARY ) {
169                 desc.ad_cname->bv_len += sizeof("binary");
170         }
171         if( desc.ad_lang != NULL ) {
172                 desc.ad_cname->bv_len += 1 + strlen( desc.ad_lang );
173         }
174
175         desc.ad_cname->bv_val = ch_malloc( desc.ad_cname->bv_len + 1 );
176
177         strcpy( desc.ad_cname->bv_val, desc.ad_type->sat_cname );
178         if( desc.ad_flags & SLAP_DESC_BINARY ) {
179                 strcat( desc.ad_cname->bv_val, ";binary" );
180         }
181
182         if( desc.ad_lang != NULL ) {
183                 strcat( desc.ad_cname->bv_val, ";" );
184                 strcat( desc.ad_cname->bv_val, desc.ad_lang );
185         }
186
187         if( *ad == NULL ) {
188                 *ad = ch_malloc( sizeof( AttributeDescription ) );
189         }
190
191         **ad = desc;
192
193         rtn = LDAP_SUCCESS;
194
195 done:
196         charray_free( tokens );
197         return rtn;
198 }
199
200 int is_ad_subtype(
201         AttributeDescription *sub,
202         AttributeDescription *super
203 )
204 {
205         if( !is_at_subtype( sub->ad_type, super->ad_type ) ) {
206                 return 0;
207         }
208
209         if( super->ad_flags && ( super->ad_flags == sub->ad_flags )) {
210                 return 0;
211         }
212
213         if( super->ad_lang != NULL && ( sub->ad_lang == NULL
214                 || strcasecmp( super->ad_lang, sub->ad_lang )))
215         {
216                 return 0;
217         }
218
219         return 1;
220 }
221
222
223 int ad_inlist(
224         AttributeDescription *desc,
225         char **attrs )
226 {
227         int i;
228         for( i=0; attrs[i] != NULL; i++ ) {
229                 AttributeDescription *ad = NULL;
230                 char *text;
231                 int rc;
232                 
233                 rc = slap_str2ad( attrs[i], &ad, &text );
234
235                 if( rc != LDAP_SUCCESS ) continue;
236
237                 rc = is_ad_subtype( desc, ad );
238
239                 ad_free( ad, 1 );
240
241                 if( rc ) return 1;
242         }
243
244         return 0;
245 }
246
247 #endif
248