]> git.sur5r.net Git - openldap/blob - servers/slapd/value.c
s/SUBSTRINGS/SUBSTR/
[openldap] / servers / slapd / value.c
1 /* value.c - routines for dealing with values */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/ctype.h>
13 #include <ac/socket.h>
14 #include <ac/string.h>
15 #include <ac/time.h>
16
17 #include <sys/stat.h>
18
19 #include "slap.h"
20
21 int
22 value_add( 
23     struct berval       ***vals,
24     struct berval       **addvals
25 )
26 {
27         int     n, nn, i, j;
28
29         for ( nn = 0; addvals != NULL && addvals[nn] != NULL; nn++ )
30                 ;       /* NULL */
31
32         if ( *vals == NULL ) {
33                 *vals = (struct berval **) ch_malloc( (nn + 1)
34                     * sizeof(struct berval *) );
35                 n = 0;
36         } else {
37                 for ( n = 0; (*vals)[n] != NULL; n++ )
38                         ;       /* NULL */
39                 *vals = (struct berval **) ch_realloc( (char *) *vals,
40                     (n + nn + 1) * sizeof(struct berval *) );
41         }
42
43         for ( i = 0, j = 0; i < nn; i++ ) {
44                 if ( addvals[i]->bv_len > 0 ) {
45                         (*vals)[n + j] = ber_bvdup( addvals[i] );
46                         if( (*vals)[n + j++] == NULL ) break;
47                 }
48         }
49         (*vals)[n + j] = NULL;
50
51         return LDAP_SUCCESS;
52 }
53
54
55 int
56 value_normalize(
57         AttributeDescription *ad,
58         unsigned usage,
59         struct berval *in,
60         struct berval **out,
61         const char **text )
62 {
63         int rc;
64         MatchingRule *mr;
65
66         switch( usage & SLAP_MR_TYPE_MASK ) {
67         case SLAP_MR_NONE:
68         case SLAP_MR_EQUALITY:
69                 mr = ad->ad_type->sat_equality;
70                 break;
71         case SLAP_MR_ORDERING:
72                 mr = ad->ad_type->sat_ordering;
73                 break;
74         case SLAP_MR_SUBSTR:
75                 mr = ad->ad_type->sat_substr;
76                 break;
77         case SLAP_MR_EXT:
78         default:
79                 assert( 0 );
80                 *text = "internal error";
81                 return LDAP_OTHER;
82         }
83
84         if( mr == NULL ) {
85                 *text = "inappropriate matching request";
86                 return LDAP_INAPPROPRIATE_MATCHING;
87         }
88
89         /* we only support equality matching of binary attributes */
90         if( slap_ad_is_binary( ad ) && usage != SLAP_MR_EQUALITY ) {
91                 *text = "inappropriate binary matching";
92                 return LDAP_INAPPROPRIATE_MATCHING;
93         }
94
95         if( mr->smr_normalize ) {
96                 rc = (mr->smr_normalize)( usage,
97                         ad->ad_type->sat_syntax,
98                         mr, in, out );
99
100                 if( rc != LDAP_SUCCESS ) {
101                         *text = "unable to normalize value";
102                         return LDAP_INVALID_SYNTAX;
103                 }
104
105         } else if ( mr->smr_syntax->ssyn_normalize ) {
106                 rc = (mr->smr_syntax->ssyn_normalize)(
107                         ad->ad_type->sat_syntax,
108                         in, out );
109
110                 if( rc != LDAP_SUCCESS ) {
111                         *text = "unable to normalize value";
112                         return LDAP_INVALID_SYNTAX;
113                 }
114
115         } else {
116                 *out = ber_bvdup( in );
117         }
118
119         return LDAP_SUCCESS;
120 }
121
122
123 int
124 value_match(
125         int *match,
126         AttributeDescription *ad,
127         MatchingRule *mr,
128         unsigned flags,
129         struct berval *v1, /* stored value */
130         void *v2, /* assertion */
131         const char ** text )
132 {
133         int rc;
134         struct berval *nv1 = NULL;
135
136         if( !mr->smr_match ) {
137                 return LDAP_INAPPROPRIATE_MATCHING;
138         }
139
140         if( ad->ad_type->sat_syntax->ssyn_normalize ) {
141                 rc = ad->ad_type->sat_syntax->ssyn_normalize(
142                         ad->ad_type->sat_syntax, v1, &nv1 );
143
144                 if( rc != LDAP_SUCCESS ) {
145                         return LDAP_INAPPROPRIATE_MATCHING;
146                 }
147         }
148
149         rc = (mr->smr_match)( match, flags,
150                 ad->ad_type->sat_syntax,
151                 mr,
152                 nv1 != NULL ? nv1 : v1,
153                 v2 );
154         
155         ber_bvfree( nv1 );
156         return rc;
157 }
158
159
160 int value_find(
161         AttributeDescription *ad,
162         struct berval **vals,
163         struct berval *val )
164 {
165         int     i;
166         int rc;
167         struct berval *nval = NULL;
168         MatchingRule *mr = ad->ad_type->sat_equality;
169
170         if( mr == NULL || !mr->smr_match ) {
171                 return LDAP_INAPPROPRIATE_MATCHING;
172         }
173
174         if( mr->smr_syntax->ssyn_normalize ) {
175                 rc = mr->smr_syntax->ssyn_normalize(
176                         mr->smr_syntax, val, &nval );
177
178                 if( rc != LDAP_SUCCESS ) {
179                         return LDAP_INAPPROPRIATE_MATCHING;
180                 }
181         }
182
183         for ( i = 0; vals[i] != NULL; i++ ) {
184                 int match;
185                 const char *text;
186
187                 rc = value_match( &match, ad, mr, 0,
188                         vals[i], nval == NULL ? val : nval, &text );
189
190                 if( rc == LDAP_SUCCESS && match == 0 ) {
191                         return LDAP_SUCCESS;
192                 }
193         }
194
195         return LDAP_NO_SUCH_ATTRIBUTE;
196 }