]> git.sur5r.net Git - openldap/blob - servers/slapd/ad.c
ba5ba094751f81c8c0bbe117acf24db765ae31c4
[openldap] / servers / slapd / ad.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-1999 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 void
23 ad_free( AttributeDescription *ad, int freeit )
24 {
25         if( ad == NULL ) return;
26
27         ber_bvfree( ad->ad_cname );
28         free( ad->ad_lang );
29
30         if( freeit ) free( ad );
31 }
32
33 static int ad_keystring(
34         struct berval *bv )
35 {
36         ber_len_t i;
37
38         if( !AD_CHAR( bv->bv_val[0] ) ) {
39                 return 1;
40         }
41
42         for( i=1; i<bv->bv_len; i++ ) {
43                 if( !AD_CHAR( bv->bv_val[i] ) ) {
44                         return 1;
45                 }
46         }
47         return 0;
48 }
49
50 int slap_str2ad(
51         const char *str,
52         AttributeDescription **ad,
53         char **text )
54 {
55         struct berval bv;
56         bv.bv_val = (char *) str;
57         bv.bv_len = strlen( str );
58
59         return slap_bv2ad( &bv, ad, text );
60 }
61
62 int slap_bv2ad(
63         struct berval *bv,
64         AttributeDescription **ad,
65         char **text )
66 {
67         int rtn = LDAP_UNDEFINED_TYPE;
68         int i;
69         AttributeDescription desc;
70         char **tokens;
71
72         assert( *ad != NULL );
73         assert( *text != NULL );
74
75         if( bv == NULL || bv->bv_len == 0 ) {
76                 *text = "empty attribute description";
77                 return LDAP_UNDEFINED_TYPE;
78         }
79
80         /* make sure description is IA5 */
81         if( ad_keystring( bv ) ) {
82                 *text = "attribute description contains inappropriate characters";
83                 return LDAP_UNDEFINED_TYPE;
84         }
85
86         tokens = str2charray( bv->bv_val, ";");
87
88         if( tokens == NULL || *tokens == NULL ) {
89                 *text = "no attribute type";
90                 goto done;
91         }
92
93         desc.ad_type = at_find( *tokens );
94
95         if( desc.ad_type == NULL ) {
96                 *text = "attribute type undefined";
97                 goto done;
98         }
99
100         desc.ad_flags = SLAP_DESC_NONE;
101         desc.ad_lang = NULL;
102
103         for( i=1; tokens[i] != NULL; i++ ) {
104                 if( strcasecmp( tokens[i], "binary" ) == 0 ) {
105                         if( desc.ad_flags & SLAP_DESC_BINARY ) {
106                                 *text = "option \"binary\" specified multiple times";
107                                 goto done;
108                         }
109
110                         if(!( desc.ad_type->sat_syntax->ssyn_flags
111                                 & SLAP_SYNTAX_BINARY ))
112                         {
113                                 /* not stored in binary, disallow option */
114                                 *text = "option \"binary\" with type not supported";
115                                 goto done;
116                         }
117
118                         desc.ad_flags |= SLAP_DESC_BINARY;
119
120                 } else if ( strncasecmp( tokens[i], "lang-",
121                         sizeof("lang-")-1 ) == 0 && tokens[i][sizeof("lang-")-1] )
122                 {
123                         if( desc.ad_lang != NULL ) {
124                                 *text = "multiple language tag options specified";
125                                 goto done;
126                         }
127                         desc.ad_lang = tokens[i];
128
129                         /* normalize to all lower case, it's easy */
130                         ldap_pvt_str2lower( desc.ad_lang );
131
132                 } else {
133                         *text = "unrecognized option";
134                         goto done;
135                 }
136         }
137
138         desc.ad_cname = ch_malloc( sizeof( struct berval ) );
139
140         desc.ad_cname->bv_len = strlen( desc.ad_type->sat_cname );
141         if( desc.ad_flags & SLAP_DESC_BINARY ) {
142                 desc.ad_cname->bv_len += sizeof("binary");
143         }
144         if( desc.ad_lang != NULL ) {
145                 desc.ad_cname->bv_len += strlen( desc.ad_lang );
146         }
147
148         desc.ad_cname = ch_malloc( desc.ad_cname->bv_len + 1 );
149
150         strcpy( desc.ad_cname->bv_val, desc.ad_type->sat_cname );
151         strcat( desc.ad_cname->bv_val, ";binary" );
152         if( desc.ad_flags & SLAP_DESC_BINARY ) {
153                 strcat( desc.ad_cname->bv_val, ";binary" );
154         }
155
156         if( desc.ad_lang != NULL ) {
157                 strcat( desc.ad_cname->bv_val, ";" );
158                 strcat( desc.ad_cname->bv_val, desc.ad_lang );
159         }
160
161         if( *ad == NULL ) {
162                 *ad = ch_malloc( sizeof( AttributeDescription ) );
163         }
164
165         **ad = desc;
166
167         rtn = LDAP_SUCCESS;
168
169 done:
170         charray_free( tokens );
171         return rtn;
172 }
173
174 int ad_inlist(
175         AttributeDescription *desc,
176         char **attrs )
177 {
178         int i;
179         for( i=0; attrs[i] != NULL; i++ ) {
180                 AttributeDescription *ad = NULL;
181                 char *text;
182                 int rc = slap_str2ad( attrs[i], &ad, &text );
183
184                 if( rc != LDAP_SUCCESS ) {
185                         goto cont;
186                 }
187
188                 if( !is_at_subtype( desc->ad_type, ad->ad_type ) ) {
189                         goto cont;
190                 }
191
192                 if( ad->ad_flags && ( ad->ad_flags == desc->ad_flags )) {
193                         goto cont;
194                 }
195
196                 if( ad->ad_lang != NULL && ( desc->ad_lang == NULL
197                         || strcasecmp( ad->ad_lang, desc->ad_lang )))
198                 {
199                         goto cont;
200                 }
201
202                 ad_free( ad, 1 );
203                 return 1;
204
205 cont:
206                 ad_free( ad, 1 );
207         }
208
209         return 0;
210 }
211
212 #endif
213