1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
15 #include <ac/string.h>
16 #include <ac/socket.h>
21 #include "ldap_utf8.h"
23 #include "lutil_hash.h"
24 /* We should replace MD5 with a faster hash */
25 #define HASH_BYTES LUTIL_HASH_BYTES
26 #define HASH_CONTEXT lutil_HASH_CTX
27 #define HASH_Init(c) lutil_HASHInit(c)
28 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
29 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
31 /* recycled validatation routines */
32 #define berValidate blobValidate
34 /* unimplemented pretters */
36 #define integerPretty NULL
38 /* recycled matching routines */
39 #define bitStringMatch octetStringMatch
40 #define numericStringMatch caseIgnoreIA5Match
41 #define objectIdentifierMatch caseIgnoreIA5Match
42 #define telephoneNumberMatch caseIgnoreIA5Match
43 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
44 #define generalizedTimeMatch caseIgnoreIA5Match
45 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
46 #define uniqueMemberMatch dnMatch
48 /* approx matching rules */
49 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
50 #define directoryStringApproxMatch approxMatch
51 #define directoryStringApproxIndexer approxIndexer
52 #define directoryStringApproxFilter approxFilter
53 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
54 #define IA5StringApproxMatch approxMatch
55 #define IA5StringApproxIndexer approxIndexer
56 #define IA5StringApproxFilter approxFilter
58 /* orderring matching rules */
59 #define caseIgnoreOrderingMatch caseIgnoreMatch
60 #define caseExactOrderingMatch caseExactMatch
62 /* unimplemented matching routines */
63 #define caseIgnoreListMatch NULL
64 #define caseIgnoreListSubstringsMatch NULL
65 #define protocolInformationMatch NULL
66 #define integerFirstComponentMatch NULL
68 #define OpenLDAPaciMatch NULL
69 #define authPasswordMatch NULL
71 /* recycled indexing/filtering routines */
72 #define dnIndexer caseExactIgnoreIndexer
73 #define dnFilter caseExactIgnoreFilter
75 #define telephoneNumberIndexer caseIgnoreIA5Indexer
76 #define telephoneNumberFilter caseIgnoreIA5Filter
77 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
78 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
80 /* must match OIDs below */
81 #define caseExactMatchOID "2.5.13.5"
82 #define caseExactSubstringsMatchOID "2.5.13.7"
84 static char *strcasechr( const char *str, int c )
86 char *lower = strchr( str, TOLOWER(c) );
87 char *upper = strchr( str, TOUPPER(c) );
89 if( lower && upper ) {
90 return lower < upper ? lower : upper;
104 struct berval *value,
105 void *assertedValue )
107 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
110 match = memcmp( value->bv_val,
111 ((struct berval *) assertedValue)->bv_val,
119 /* Index generation function */
120 int octetStringIndexer(
125 struct berval *prefix,
126 struct berval **values,
127 struct berval ***keysp )
131 struct berval **keys;
132 HASH_CONTEXT HASHcontext;
133 unsigned char HASHdigest[HASH_BYTES];
134 struct berval digest;
135 digest.bv_val = HASHdigest;
136 digest.bv_len = sizeof(HASHdigest);
138 for( i=0; values[i] != NULL; i++ ) {
139 /* just count them */
142 /* we should have at least one value at this point */
145 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
147 slen = strlen( syntax->ssyn_oid );
148 mlen = strlen( mr->smr_oid );
150 for( i=0; values[i] != NULL; i++ ) {
151 HASH_Init( &HASHcontext );
152 if( prefix != NULL && prefix->bv_len > 0 ) {
153 HASH_Update( &HASHcontext,
154 prefix->bv_val, prefix->bv_len );
156 HASH_Update( &HASHcontext,
157 syntax->ssyn_oid, slen );
158 HASH_Update( &HASHcontext,
160 HASH_Update( &HASHcontext,
161 values[i]->bv_val, values[i]->bv_len );
162 HASH_Final( HASHdigest, &HASHcontext );
164 keys[i] = ber_bvdup( &digest );
174 /* Index generation function */
175 int octetStringFilter(
180 struct berval *prefix,
182 struct berval ***keysp )
185 struct berval **keys;
186 HASH_CONTEXT HASHcontext;
187 unsigned char HASHdigest[HASH_BYTES];
188 struct berval *value = (struct berval *) assertValue;
189 struct berval digest;
190 digest.bv_val = HASHdigest;
191 digest.bv_len = sizeof(HASHdigest);
193 slen = strlen( syntax->ssyn_oid );
194 mlen = strlen( mr->smr_oid );
196 keys = ch_malloc( sizeof( struct berval * ) * 2 );
198 HASH_Init( &HASHcontext );
199 if( prefix != NULL && prefix->bv_len > 0 ) {
200 HASH_Update( &HASHcontext,
201 prefix->bv_val, prefix->bv_len );
203 HASH_Update( &HASHcontext,
204 syntax->ssyn_oid, slen );
205 HASH_Update( &HASHcontext,
207 HASH_Update( &HASHcontext,
208 value->bv_val, value->bv_len );
209 HASH_Final( HASHdigest, &HASHcontext );
211 keys[0] = ber_bvdup( &digest );
227 if( in->bv_len == 0 ) return LDAP_SUCCESS;
229 dn = ch_strdup( in->bv_val );
232 return LDAP_INVALID_SYNTAX;
234 } else if ( strlen( in->bv_val ) != in->bv_len ) {
235 rc = LDAP_INVALID_SYNTAX;
237 } else if ( dn_validate( dn ) == NULL ) {
238 rc = LDAP_INVALID_SYNTAX;
252 struct berval **normalized )
256 if ( val->bv_len != 0 ) {
258 out = ber_bvstr( UTF8normalize( val->bv_val, UTF8_CASEFOLD ) );
260 dn = dn_validate( out->bv_val );
264 return LDAP_INVALID_SYNTAX;
268 out->bv_len = strlen( dn );
270 out = ber_bvdup( val );
283 struct berval *value,
284 void *assertedValue )
287 struct berval *asserted = (struct berval *) assertedValue;
289 match = value->bv_len - asserted->bv_len;
292 #ifdef USE_DN_NORMALIZE
293 match = strcmp( value->bv_val, asserted->bv_val );
295 match = strcasecmp( value->bv_val, asserted->bv_val );
300 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
301 "dnMatch: %d\n %s\n %s\n", match,
302 value->bv_val, asserted->bv_val ));
304 Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
305 match, value->bv_val, asserted->bv_val );
321 if( in->bv_len == 0 ) return LDAP_SUCCESS;
323 dn = ber_bvdup( in );
325 if( dn->bv_val[dn->bv_len-1] == '\'' ) {
326 /* assume presence of optional UID */
329 for(i=dn->bv_len-2; i>2; i--) {
330 if( dn->bv_val[i] != '0' && dn->bv_val[i] != '1' ) {
334 if( dn->bv_val[i] != '\'' ) {
335 return LDAP_INVALID_SYNTAX;
337 if( dn->bv_val[i-1] != 'B' ) {
338 return LDAP_INVALID_SYNTAX;
340 if( dn->bv_val[i-2] != '#' ) {
341 return LDAP_INVALID_SYNTAX;
344 /* trim the UID to allow use of dn_validate */
345 dn->bv_val[i-2] = '\0';
348 rc = dn_validate( dn->bv_val ) == NULL
349 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
359 struct berval **normalized )
361 struct berval *out = ber_bvdup( val );
363 if( out->bv_len != 0 ) {
367 ber_len_t uidlen = 0;
369 if( out->bv_val[out->bv_len-1] == '\'' ) {
370 /* assume presence of optional UID */
371 uid = strrchr( out->bv_val, '#' );
375 return LDAP_INVALID_SYNTAX;
378 uidlen = out->bv_len - (out->bv_val - uid);
379 /* temporarily trim the UID */
383 #ifdef USE_DN_NORMALIZE
384 dn = dn_normalize( out->bv_val );
386 dn = dn_validate( out->bv_val );
391 return LDAP_INVALID_SYNTAX;
397 /* restore the separator */
400 SAFEMEMCPY( &dn[dnlen], uid, uidlen );
404 out->bv_len = dnlen + uidlen;
416 /* any value allowed */
425 /* any value allowed */
436 /* very unforgiving validation, requires no normalization
437 * before simplistic matching
439 if( in->bv_len < 3 ) {
440 return LDAP_INVALID_SYNTAX;
443 if( in->bv_val[0] != 'B' ||
444 in->bv_val[1] != '\'' ||
445 in->bv_val[in->bv_len-1] != '\'' )
447 return LDAP_INVALID_SYNTAX;
450 for( i=in->bv_len-2; i>1; i-- ) {
451 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
452 return LDAP_INVALID_SYNTAX;
460 * Handling boolean syntax and matching is quite rigid.
461 * A more flexible approach would be to allow a variety
462 * of strings to be normalized and prettied into TRUE
470 /* very unforgiving validation, requires no normalization
471 * before simplistic matching
474 if( in->bv_len == 4 ) {
475 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
478 } else if( in->bv_len == 5 ) {
479 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
484 return LDAP_INVALID_SYNTAX;
493 struct berval *value,
494 void *assertedValue )
496 /* simplistic matching allowed by rigid validation */
497 struct berval *asserted = (struct berval *) assertedValue;
498 *matchp = value->bv_len != asserted->bv_len;
509 unsigned char *u = in->bv_val;
511 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
513 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
514 /* get the length indicated by the first byte */
515 len = LDAP_UTF8_CHARLEN( u );
517 /* should not be zero */
518 if( len == 0 ) return LDAP_INVALID_SYNTAX;
520 /* make sure len corresponds with the offset
521 to the next character */
522 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
525 if( count != 0 ) return LDAP_INVALID_SYNTAX;
534 struct berval **normalized )
536 struct berval *newval;
539 newval = ch_malloc( sizeof( struct berval ) );
543 /* Ignore initial whitespace */
544 while ( ldap_utf8_isspace( p ) ) {
550 return LDAP_INVALID_SYNTAX;
553 newval->bv_val = ch_strdup( p );
554 p = q = newval->bv_val;
560 if ( ldap_utf8_isspace( p ) ) {
561 len = LDAP_UTF8_COPY(q,p);
566 /* Ignore the extra whitespace */
567 while ( ldap_utf8_isspace( p ) ) {
571 len = LDAP_UTF8_COPY(q,p);
578 assert( *newval->bv_val );
579 assert( newval->bv_val < p );
582 /* cannot start with a space */
583 assert( !ldap_utf8_isspace(newval->bv_val) );
586 * If the string ended in space, backup the pointer one
587 * position. One is enough because the above loop collapsed
588 * all whitespace to a single space.
595 /* cannot end with a space */
596 assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
601 newval->bv_len = q - newval->bv_val;
602 *normalized = newval;
607 /* Returns Unicode cannonically normalized copy of a substring assertion
608 * Skipping attribute description */
609 SubstringsAssertion *
610 UTF8SubstringsassertionNormalize(
611 SubstringsAssertion *sa,
614 SubstringsAssertion *nsa;
617 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
622 if( sa->sa_initial != NULL ) {
623 nsa->sa_initial = ber_bvstr( UTF8normalize( sa->sa_initial->bv_val, casefold ) );
624 if( nsa->sa_initial == NULL ) {
629 if( sa->sa_any != NULL ) {
630 for( i=0; sa->sa_any[i] != NULL; i++ ) {
633 nsa->sa_any = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
634 for( i=0; sa->sa_any[i] != NULL; i++ ) {
635 nsa->sa_any[i] = ber_bvstr( UTF8normalize( sa->sa_any[i]->bv_val, casefold ) );
636 if( nsa->sa_any[i] == NULL ) {
640 nsa->sa_any[i] = NULL;
643 if( sa->sa_final != NULL ) {
644 nsa->sa_final = ber_bvstr( UTF8normalize( sa->sa_final->bv_val, casefold ) );
645 if( nsa->sa_final == NULL ) {
653 ber_bvfree( nsa->sa_final );
654 ber_bvecfree( nsa->sa_any );
655 ber_bvfree( nsa->sa_initial );
660 /* Strip characters with the 8th bit set */
673 while( *++q & 0x80 ) {
676 p = memmove(p, q, strlen(q) + 1);
684 #ifndef SLAPD_APPROX_OLDSINGLESTRING
686 #if defined(SLAPD_APPROX_INITIALS)
687 #define SLAPD_APPROX_DELIMITER "._ "
688 #define SLAPD_APPROX_WORDLEN 2
690 #define SLAPD_APPROX_DELIMITER " "
691 #define SLAPD_APPROX_WORDLEN 1
700 struct berval *value,
701 void *assertedValue )
703 char *val, *nval, *assertv, **values, **words, *c;
704 int i, count, len, nextchunk=0, nextavail=0;
707 /* Yes, this is necessary */
708 nval = UTF8normalize( value->bv_val, UTF8_NOCASEFOLD );
713 strip8bitChars( nval );
715 /* Yes, this is necessary */
716 assertv = UTF8normalize( ((struct berval *)assertedValue)->bv_val,
718 if( assertv == NULL ) {
723 strip8bitChars( assertv );
724 avlen = strlen( assertv );
726 /* Isolate how many words there are */
727 for( c=nval,count=1; *c; c++ ) {
728 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
729 if ( c == NULL ) break;
734 /* Get a phonetic copy of each word */
735 words = (char **)ch_malloc( count * sizeof(char *) );
736 values = (char **)ch_malloc( count * sizeof(char *) );
737 for( c=nval,i=0; i<count; i++,c+=strlen(c)+1 ) {
739 values[i] = phonetic(c);
742 /* Work through the asserted value's words, to see if at least some
743 of the words are there, in the same order. */
745 while ( nextchunk < avlen ) {
746 len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER);
751 #if defined(SLAPD_APPROX_INITIALS)
752 else if( len == 1 ) {
753 /* Single letter words need to at least match one word's initial */
754 for( i=nextavail; i<count; i++ )
755 if( !strncasecmp( assertv+nextchunk, words[i], 1 )) {
762 /* Isolate the next word in the asserted value and phonetic it */
763 assertv[nextchunk+len] = '\0';
764 val = phonetic( assertv + nextchunk );
766 /* See if this phonetic chunk is in the remaining words of *value */
767 for( i=nextavail; i<count; i++ ){
768 if( !strcmp( val, values[i] ) ){
776 /* This chunk in the asserted value was NOT within the *value. */
782 /* Go on to the next word in the asserted value */
786 /* If some of the words were seen, call it a match */
787 if( nextavail > 0 ) {
796 for( i=0; i<count; i++ ) {
797 ch_free( values[i] );
812 struct berval *prefix,
813 struct berval **values,
814 struct berval ***keysp )
817 int i,j, len, wordcount, keycount=0;
818 struct berval **newkeys, **keys=NULL;
820 for( j=0; values[j] != NULL; j++ ) {
821 /* Yes, this is necessary */
822 val = UTF8normalize( values[j]->bv_val, UTF8_NOCASEFOLD );
823 strip8bitChars( val );
825 /* Isolate how many words there are. There will be a key for each */
826 for( wordcount=0,c=val; *c; c++) {
827 len = strcspn(c, SLAPD_APPROX_DELIMITER);
828 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
830 if (*c == '\0') break;
834 /* Allocate/increase storage to account for new keys */
835 newkeys = (struct berval **)ch_malloc( (keycount + wordcount + 1)
836 * sizeof(struct berval *) );
837 memcpy( newkeys, keys, keycount * sizeof(struct berval *) );
838 if( keys ) ch_free( keys );
841 /* Get a phonetic copy of each word */
842 for( c=val,i=0; i<wordcount; c+=len+1 ) {
844 if( len < SLAPD_APPROX_WORDLEN ) continue;
845 keys[keycount] = (struct berval *)ch_malloc( sizeof(struct berval) );
846 keys[keycount]->bv_val = phonetic( c );
847 keys[keycount]->bv_len = strlen( keys[keycount]->bv_val );
854 keys[keycount] = NULL;
866 struct berval *prefix,
868 struct berval ***keysp )
872 struct berval **keys;
874 /* Yes, this is necessary */
875 val = UTF8normalize( ((struct berval *)assertValue)->bv_val,
878 keys = (struct berval **)ch_malloc( sizeof(struct berval *) );
883 strip8bitChars( val );
885 /* Isolate how many words there are. There will be a key for each */
886 for( count=0,c=val; *c; c++) {
887 len = strcspn(c, SLAPD_APPROX_DELIMITER);
888 if( len >= SLAPD_APPROX_WORDLEN ) count++;
890 if (*c == '\0') break;
894 /* Allocate storage for new keys */
895 keys = (struct berval **)ch_malloc( (count + 1) * sizeof(struct berval *) );
897 /* Get a phonetic copy of each word */
898 for( c=val,i=0; i<count; c+=len+1 ) {
900 if( len < SLAPD_APPROX_WORDLEN ) continue;
901 keys[i] = ber_bvstr( phonetic( c ) );
915 /* No other form of Approximate Matching is defined */
923 struct berval *value,
924 void *assertedValue )
926 char *vapprox, *avapprox;
929 /* Yes, this is necessary */
930 s = UTF8normalize( value->bv_val, UTF8_NOCASEFOLD );
936 /* Yes, this is necessary */
937 t = UTF8normalize( ((struct berval *)assertedValue)->bv_val,
945 vapprox = phonetic( strip8bitChars( s ) );
946 avapprox = phonetic( strip8bitChars( t ) );
951 *matchp = strcmp( vapprox, avapprox );
965 struct berval *prefix,
966 struct berval **values,
967 struct berval ***keysp )
970 struct berval **keys;
973 for( i=0; values[i] != NULL; i++ ) {
974 /* empty - just count them */
977 /* we should have at least one value at this point */
980 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * (i+1) );
982 /* Copy each value and run it through phonetic() */
983 for( i=0; values[i] != NULL; i++ ) {
984 /* Yes, this is necessary */
985 s = UTF8normalize( values[i]->bv_val, UTF8_NOCASEFOLD );
987 /* strip 8-bit chars and run through phonetic() */
988 keys[i] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1004 struct berval *prefix,
1006 struct berval ***keysp )
1008 struct berval **keys;
1011 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * 2 );
1013 /* Yes, this is necessary */
1014 s = UTF8normalize( ((struct berval *)assertValue)->bv_val,
1019 /* strip 8-bit chars and run through phonetic() */
1020 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1026 return LDAP_SUCCESS;
1037 struct berval *value,
1038 void *assertedValue )
1040 *matchp = UTF8normcmp( value->bv_val,
1041 ((struct berval *) assertedValue)->bv_val,
1043 return LDAP_SUCCESS;
1047 caseExactIgnoreSubstringsMatch(
1052 struct berval *value,
1053 void *assertedValue )
1056 SubstringsAssertion *sub;
1060 char *nav, casefold;
1062 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1063 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1065 nav = UTF8normalize( value->bv_val, casefold );
1071 left.bv_len = strlen( nav );
1073 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1079 /* Add up asserted input length */
1080 if( sub->sa_initial ) {
1081 inlen += sub->sa_initial->bv_len;
1084 for(i=0; sub->sa_any[i] != NULL; i++) {
1085 inlen += sub->sa_any[i]->bv_len;
1088 if( sub->sa_final ) {
1089 inlen += sub->sa_final->bv_len;
1092 if( sub->sa_initial ) {
1093 if( inlen > left.bv_len ) {
1098 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
1099 sub->sa_initial->bv_len );
1105 left.bv_val += sub->sa_initial->bv_len;
1106 left.bv_len -= sub->sa_initial->bv_len;
1107 inlen -= sub->sa_initial->bv_len;
1110 if( sub->sa_final ) {
1111 if( inlen > left.bv_len ) {
1116 match = strncmp( sub->sa_final->bv_val,
1117 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
1118 sub->sa_final->bv_len );
1124 left.bv_len -= sub->sa_final->bv_len;
1125 inlen -= sub->sa_final->bv_len;
1129 for(i=0; sub->sa_any[i]; i++) {
1134 if( inlen > left.bv_len ) {
1135 /* not enough length */
1140 if( sub->sa_any[i]->bv_len == 0 ) {
1144 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
1151 idx = p - left.bv_val;
1152 assert( idx < left.bv_len );
1154 if( idx >= left.bv_len ) {
1155 /* this shouldn't happen */
1162 if( sub->sa_any[i]->bv_len > left.bv_len ) {
1163 /* not enough left */
1168 match = strncmp( left.bv_val,
1169 sub->sa_any[i]->bv_val,
1170 sub->sa_any[i]->bv_len );
1178 left.bv_val += sub->sa_any[i]->bv_len;
1179 left.bv_len -= sub->sa_any[i]->bv_len;
1180 inlen -= sub->sa_any[i]->bv_len;
1187 ber_bvfree( sub->sa_final );
1188 ber_bvecfree( sub->sa_any );
1189 ber_bvfree( sub->sa_initial );
1193 return LDAP_SUCCESS;
1196 /* Index generation function */
1197 int caseExactIgnoreIndexer(
1202 struct berval *prefix,
1203 struct berval **values,
1204 struct berval ***keysp )
1209 struct berval **keys;
1210 HASH_CONTEXT HASHcontext;
1211 unsigned char HASHdigest[HASH_BYTES];
1212 struct berval digest;
1213 digest.bv_val = HASHdigest;
1214 digest.bv_len = sizeof(HASHdigest);
1216 for( i=0; values[i] != NULL; i++ ) {
1217 /* empty - just count them */
1220 /* we should have at least one value at this point */
1223 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
1225 slen = strlen( syntax->ssyn_oid );
1226 mlen = strlen( mr->smr_oid );
1228 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1229 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1231 for( i=0; values[i] != NULL; i++ ) {
1232 struct berval *value;
1233 value = ber_bvstr( UTF8normalize( values[i]->bv_val,
1236 HASH_Init( &HASHcontext );
1237 if( prefix != NULL && prefix->bv_len > 0 ) {
1238 HASH_Update( &HASHcontext,
1239 prefix->bv_val, prefix->bv_len );
1241 HASH_Update( &HASHcontext,
1242 syntax->ssyn_oid, slen );
1243 HASH_Update( &HASHcontext,
1244 mr->smr_oid, mlen );
1245 HASH_Update( &HASHcontext,
1246 value->bv_val, value->bv_len );
1247 HASH_Final( HASHdigest, &HASHcontext );
1249 ber_bvfree( value );
1251 keys[i] = ber_bvdup( &digest );
1256 return LDAP_SUCCESS;
1259 /* Index generation function */
1260 int caseExactIgnoreFilter(
1265 struct berval *prefix,
1267 struct berval ***keysp )
1271 struct berval **keys;
1272 HASH_CONTEXT HASHcontext;
1273 unsigned char HASHdigest[HASH_BYTES];
1274 struct berval *value;
1275 struct berval digest;
1276 digest.bv_val = HASHdigest;
1277 digest.bv_len = sizeof(HASHdigest);
1279 slen = strlen( syntax->ssyn_oid );
1280 mlen = strlen( mr->smr_oid );
1282 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1283 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1285 value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue)->bv_val,
1287 /* This usually happens if filter contains bad UTF8 */
1288 if( value == NULL ) {
1289 keys = ch_malloc( sizeof( struct berval * ) );
1291 return LDAP_SUCCESS;
1294 keys = ch_malloc( sizeof( struct berval * ) * 2 );
1296 HASH_Init( &HASHcontext );
1297 if( prefix != NULL && prefix->bv_len > 0 ) {
1298 HASH_Update( &HASHcontext,
1299 prefix->bv_val, prefix->bv_len );
1301 HASH_Update( &HASHcontext,
1302 syntax->ssyn_oid, slen );
1303 HASH_Update( &HASHcontext,
1304 mr->smr_oid, mlen );
1305 HASH_Update( &HASHcontext,
1306 value->bv_val, value->bv_len );
1307 HASH_Final( HASHdigest, &HASHcontext );
1309 keys[0] = ber_bvdup( &digest );
1312 ber_bvfree( value );
1315 return LDAP_SUCCESS;
1318 /* Substrings Index generation function */
1319 int caseExactIgnoreSubstringsIndexer(
1324 struct berval *prefix,
1325 struct berval **values,
1326 struct berval ***keysp )
1331 struct berval **keys;
1332 struct berval **nvalues;
1334 HASH_CONTEXT HASHcontext;
1335 unsigned char HASHdigest[HASH_BYTES];
1336 struct berval digest;
1337 digest.bv_val = HASHdigest;
1338 digest.bv_len = sizeof(HASHdigest);
1342 for( i=0; values[i] != NULL; i++ ) {
1343 /* empty - just count them */
1346 /* we should have at least one value at this point */
1349 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1350 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1352 nvalues = ch_malloc( sizeof( struct berval * ) * (i+1) );
1353 for( i=0; values[i] != NULL; i++ ) {
1354 nvalues[i] = ber_bvstr( UTF8normalize( values[i]->bv_val,
1360 for( i=0; values[i] != NULL; i++ ) {
1361 /* count number of indices to generate */
1362 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1366 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1367 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1368 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1369 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1371 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1375 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1376 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1377 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1381 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1382 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1383 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1384 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1386 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1392 /* no keys to generate */
1394 return LDAP_SUCCESS;
1397 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1399 slen = strlen( syntax->ssyn_oid );
1400 mlen = strlen( mr->smr_oid );
1403 for( i=0; values[i] != NULL; i++ ) {
1405 struct berval *value;
1407 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1411 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1412 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1414 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1415 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1417 for( j=0; j<max; j++ ) {
1418 HASH_Init( &HASHcontext );
1419 if( prefix != NULL && prefix->bv_len > 0 ) {
1420 HASH_Update( &HASHcontext,
1421 prefix->bv_val, prefix->bv_len );
1424 HASH_Update( &HASHcontext,
1425 &pre, sizeof( pre ) );
1426 HASH_Update( &HASHcontext,
1427 syntax->ssyn_oid, slen );
1428 HASH_Update( &HASHcontext,
1429 mr->smr_oid, mlen );
1430 HASH_Update( &HASHcontext,
1432 SLAP_INDEX_SUBSTR_MAXLEN );
1433 HASH_Final( HASHdigest, &HASHcontext );
1435 keys[nkeys++] = ber_bvdup( &digest );
1439 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1440 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1442 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1445 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1446 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1447 HASH_Init( &HASHcontext );
1448 if( prefix != NULL && prefix->bv_len > 0 ) {
1449 HASH_Update( &HASHcontext,
1450 prefix->bv_val, prefix->bv_len );
1452 HASH_Update( &HASHcontext,
1453 &pre, sizeof( pre ) );
1454 HASH_Update( &HASHcontext,
1455 syntax->ssyn_oid, slen );
1456 HASH_Update( &HASHcontext,
1457 mr->smr_oid, mlen );
1458 HASH_Update( &HASHcontext,
1460 HASH_Final( HASHdigest, &HASHcontext );
1462 keys[nkeys++] = ber_bvdup( &digest );
1465 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1466 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1467 HASH_Init( &HASHcontext );
1468 if( prefix != NULL && prefix->bv_len > 0 ) {
1469 HASH_Update( &HASHcontext,
1470 prefix->bv_val, prefix->bv_len );
1472 HASH_Update( &HASHcontext,
1473 &pre, sizeof( pre ) );
1474 HASH_Update( &HASHcontext,
1475 syntax->ssyn_oid, slen );
1476 HASH_Update( &HASHcontext,
1477 mr->smr_oid, mlen );
1478 HASH_Update( &HASHcontext,
1479 &value->bv_val[value->bv_len-j], j );
1480 HASH_Final( HASHdigest, &HASHcontext );
1482 keys[nkeys++] = ber_bvdup( &digest );
1497 ber_bvecfree( nvalues );
1499 return LDAP_SUCCESS;
1502 int caseExactIgnoreSubstringsFilter(
1507 struct berval *prefix,
1509 struct berval ***keysp )
1511 SubstringsAssertion *sa;
1513 ber_len_t nkeys = 0;
1514 size_t slen, mlen, klen;
1515 struct berval **keys;
1516 HASH_CONTEXT HASHcontext;
1517 unsigned char HASHdigest[HASH_BYTES];
1518 struct berval *value;
1519 struct berval digest;
1521 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1522 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1524 sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
1527 return LDAP_SUCCESS;
1530 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1531 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1536 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1538 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1539 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1540 /* don't bother accounting for stepping */
1541 nkeys += sa->sa_any[i]->bv_len -
1542 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1547 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1548 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1554 ber_bvfree( sa->sa_final );
1555 ber_bvecfree( sa->sa_any );
1556 ber_bvfree( sa->sa_initial );
1559 return LDAP_SUCCESS;
1562 digest.bv_val = HASHdigest;
1563 digest.bv_len = sizeof(HASHdigest);
1565 slen = strlen( syntax->ssyn_oid );
1566 mlen = strlen( mr->smr_oid );
1568 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1571 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1572 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1574 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1575 value = sa->sa_initial;
1577 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1578 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1580 HASH_Init( &HASHcontext );
1581 if( prefix != NULL && prefix->bv_len > 0 ) {
1582 HASH_Update( &HASHcontext,
1583 prefix->bv_val, prefix->bv_len );
1585 HASH_Update( &HASHcontext,
1586 &pre, sizeof( pre ) );
1587 HASH_Update( &HASHcontext,
1588 syntax->ssyn_oid, slen );
1589 HASH_Update( &HASHcontext,
1590 mr->smr_oid, mlen );
1591 HASH_Update( &HASHcontext,
1592 value->bv_val, klen );
1593 HASH_Final( HASHdigest, &HASHcontext );
1595 keys[nkeys++] = ber_bvdup( &digest );
1598 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1600 pre = SLAP_INDEX_SUBSTR_PREFIX;
1601 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1603 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1604 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1608 value = sa->sa_any[i];
1611 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1612 j += SLAP_INDEX_SUBSTR_STEP )
1614 HASH_Init( &HASHcontext );
1615 if( prefix != NULL && prefix->bv_len > 0 ) {
1616 HASH_Update( &HASHcontext,
1617 prefix->bv_val, prefix->bv_len );
1619 HASH_Update( &HASHcontext,
1620 &pre, sizeof( pre ) );
1621 HASH_Update( &HASHcontext,
1622 syntax->ssyn_oid, slen );
1623 HASH_Update( &HASHcontext,
1624 mr->smr_oid, mlen );
1625 HASH_Update( &HASHcontext,
1626 &value->bv_val[j], klen );
1627 HASH_Final( HASHdigest, &HASHcontext );
1629 keys[nkeys++] = ber_bvdup( &digest );
1635 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1636 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1638 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1639 value = sa->sa_final;
1641 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1642 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1644 HASH_Init( &HASHcontext );
1645 if( prefix != NULL && prefix->bv_len > 0 ) {
1646 HASH_Update( &HASHcontext,
1647 prefix->bv_val, prefix->bv_len );
1649 HASH_Update( &HASHcontext,
1650 &pre, sizeof( pre ) );
1651 HASH_Update( &HASHcontext,
1652 syntax->ssyn_oid, slen );
1653 HASH_Update( &HASHcontext,
1654 mr->smr_oid, mlen );
1655 HASH_Update( &HASHcontext,
1656 &value->bv_val[value->bv_len-klen], klen );
1657 HASH_Final( HASHdigest, &HASHcontext );
1659 keys[nkeys++] = ber_bvdup( &digest );
1669 ber_bvfree( sa->sa_final );
1670 ber_bvecfree( sa->sa_any );
1671 ber_bvfree( sa->sa_initial );
1674 return LDAP_SUCCESS;
1683 struct berval *value,
1684 void *assertedValue )
1686 *matchp = UTF8normcmp( value->bv_val,
1687 ((struct berval *) assertedValue)->bv_val,
1689 return LDAP_SUCCESS;
1695 struct berval *val )
1699 if( val->bv_len == 0 ) {
1700 /* disallow empty strings */
1701 return LDAP_INVALID_SYNTAX;
1704 if( OID_LEADCHAR(val->bv_val[0]) ) {
1706 for(i=1; i < val->bv_len; i++) {
1707 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1708 if( dot++ ) return 1;
1709 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1712 return LDAP_INVALID_SYNTAX;
1716 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1718 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1719 for(i=1; i < val->bv_len; i++) {
1720 if( !DESC_CHAR(val->bv_val[i] ) ) {
1721 return LDAP_INVALID_SYNTAX;
1725 return LDAP_SUCCESS;
1728 return LDAP_INVALID_SYNTAX;
1737 struct berval *value,
1738 void *assertedValue )
1741 int vsign=0, avsign=0;
1742 struct berval *asserted;
1743 ber_len_t vlen, avlen;
1746 /* Start off pessimistic */
1749 /* Skip past leading spaces/zeros, and get the sign of the *value number */
1751 vlen = value->bv_len;
1753 if( ASCII_SPACE(*v) || ( *v == '0' )) {
1754 /* empty -- skip spaces */
1756 else if ( *v == '+' ) {
1759 else if ( *v == '-' ) {
1762 else if ( ASCII_DIGIT(*v) ) {
1763 if ( vsign == 0 ) vsign = 1;
1771 /* Skip past leading spaces/zeros, and get the sign of the *assertedValue
1773 asserted = (struct berval *) assertedValue;
1774 av = asserted->bv_val;
1775 avlen = asserted->bv_len;
1777 if( ASCII_SPACE(*av) || ( *av == '0' )) {
1778 /* empty -- skip spaces */
1780 else if ( *av == '+' ) {
1783 else if ( *av == '-' ) {
1786 else if ( ASCII_DIGIT(*av) ) {
1787 if ( avsign == 0 ) avsign = 1;
1795 /* The two ?sign vars are now one of :
1796 -2 negative non-zero number
1798 0 0 collapse these three to 0
1800 +2 positive non-zero number
1802 if ( abs( vsign ) == 1 ) vsign = 0;
1803 if ( abs( avsign ) == 1 ) avsign = 0;
1805 if( vsign != avsign ) return LDAP_SUCCESS;
1807 /* Check the significant digits */
1808 while( vlen && avlen ) {
1809 if( *v != *av ) break;
1816 /* If all digits compared equal, the numbers are equal */
1817 if(( vlen == 0 ) && ( avlen == 0 )) {
1820 return LDAP_SUCCESS;
1826 struct berval *val )
1830 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1832 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
1833 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1834 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1835 return LDAP_INVALID_SYNTAX;
1838 for( i=1; i < val->bv_len; i++ ) {
1839 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1842 return LDAP_SUCCESS;
1849 struct berval **normalized )
1853 struct berval *newval;
1860 /* Ignore leading spaces */
1861 while ( len && ( *p == ' ' )) {
1868 negative = ( *p == '-' );
1869 if(( *p == '-' ) || ( *p == '+' )) {
1875 /* Ignore leading zeros */
1876 while ( len && ( *p == '0' )) {
1881 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
1883 /* If there are no non-zero digits left, the number is zero, otherwise
1884 allocate space for the number and copy it into the buffer */
1886 newval->bv_val = ch_strdup("0");
1890 newval->bv_len = len+negative;
1891 newval->bv_val = ch_malloc( newval->bv_len );
1893 newval->bv_val[0] = '-';
1895 memcpy( newval->bv_val + negative, p, len );
1898 *normalized = newval;
1899 return LDAP_SUCCESS;
1902 /* Index generation function */
1908 struct berval *prefix,
1909 struct berval **values,
1910 struct berval ***keysp )
1913 struct berval **keys;
1915 /* we should have at least one value at this point */
1916 assert( values != NULL && values[0] != NULL );
1918 for( i=0; values[i] != NULL; i++ ) {
1919 /* empty -- just count them */
1922 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
1924 for( i=0; values[i] != NULL; i++ ) {
1925 integerNormalize( syntax, values[i], &keys[i] );
1930 return LDAP_SUCCESS;
1933 /* Index generation function */
1939 struct berval *prefix,
1941 struct berval ***keysp )
1943 struct berval **keys;
1945 keys = ch_malloc( sizeof( struct berval * ) * 2 );
1946 integerNormalize( syntax, assertValue, &keys[0] );
1950 return LDAP_SUCCESS;
1955 countryStringValidate(
1957 struct berval *val )
1959 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
1961 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
1962 return LDAP_INVALID_SYNTAX;
1964 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
1965 return LDAP_INVALID_SYNTAX;
1968 return LDAP_SUCCESS;
1972 printableStringValidate(
1974 struct berval *val )
1978 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1980 for(i=0; i < val->bv_len; i++) {
1981 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
1982 return LDAP_INVALID_SYNTAX;
1986 return LDAP_SUCCESS;
1990 printablesStringValidate(
1992 struct berval *val )
1996 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1998 for(i=0; i < val->bv_len; i++) {
1999 if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
2000 return LDAP_INVALID_SYNTAX;
2004 return LDAP_SUCCESS;
2010 struct berval *val )
2014 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2016 for(i=0; i < val->bv_len; i++) {
2017 if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2020 return LDAP_SUCCESS;
2027 struct berval **normalized )
2029 struct berval *newval;
2032 newval = ch_malloc( sizeof( struct berval ) );
2036 /* Ignore initial whitespace */
2037 while ( ASCII_SPACE( *p ) ) {
2043 return LDAP_INVALID_SYNTAX;
2046 newval->bv_val = ch_strdup( p );
2047 p = q = newval->bv_val;
2050 if ( ASCII_SPACE( *p ) ) {
2053 /* Ignore the extra whitespace */
2054 while ( ASCII_SPACE( *p ) ) {
2062 assert( *newval->bv_val );
2063 assert( newval->bv_val < p );
2066 /* cannot start with a space */
2067 assert( !ASCII_SPACE(*newval->bv_val) );
2070 * If the string ended in space, backup the pointer one
2071 * position. One is enough because the above loop collapsed
2072 * all whitespace to a single space.
2075 if ( ASCII_SPACE( q[-1] ) ) {
2079 /* cannot end with a space */
2080 assert( !ASCII_SPACE( q[-1] ) );
2082 /* null terminate */
2085 newval->bv_len = q - newval->bv_val;
2086 *normalized = newval;
2088 return LDAP_SUCCESS;
2097 struct berval *value,
2098 void *assertedValue )
2100 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2103 match = strncmp( value->bv_val,
2104 ((struct berval *) assertedValue)->bv_val,
2109 return LDAP_SUCCESS;
2113 caseExactIA5SubstringsMatch(
2118 struct berval *value,
2119 void *assertedValue )
2122 SubstringsAssertion *sub = assertedValue;
2123 struct berval left = *value;
2127 /* Add up asserted input length */
2128 if( sub->sa_initial ) {
2129 inlen += sub->sa_initial->bv_len;
2132 for(i=0; sub->sa_any[i] != NULL; i++) {
2133 inlen += sub->sa_any[i]->bv_len;
2136 if( sub->sa_final ) {
2137 inlen += sub->sa_final->bv_len;
2140 if( sub->sa_initial ) {
2141 if( inlen > left.bv_len ) {
2146 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
2147 sub->sa_initial->bv_len );
2153 left.bv_val += sub->sa_initial->bv_len;
2154 left.bv_len -= sub->sa_initial->bv_len;
2155 inlen -= sub->sa_initial->bv_len;
2158 if( sub->sa_final ) {
2159 if( inlen > left.bv_len ) {
2164 match = strncmp( sub->sa_final->bv_val,
2165 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2166 sub->sa_final->bv_len );
2172 left.bv_len -= sub->sa_final->bv_len;
2173 inlen -= sub->sa_final->bv_len;
2177 for(i=0; sub->sa_any[i]; i++) {
2182 if( inlen > left.bv_len ) {
2183 /* not enough length */
2188 if( sub->sa_any[i]->bv_len == 0 ) {
2192 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
2199 idx = p - left.bv_val;
2200 assert( idx < left.bv_len );
2202 if( idx >= left.bv_len ) {
2203 /* this shouldn't happen */
2210 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2211 /* not enough left */
2216 match = strncmp( left.bv_val,
2217 sub->sa_any[i]->bv_val,
2218 sub->sa_any[i]->bv_len );
2226 left.bv_val += sub->sa_any[i]->bv_len;
2227 left.bv_len -= sub->sa_any[i]->bv_len;
2228 inlen -= sub->sa_any[i]->bv_len;
2234 return LDAP_SUCCESS;
2237 /* Index generation function */
2238 int caseExactIA5Indexer(
2243 struct berval *prefix,
2244 struct berval **values,
2245 struct berval ***keysp )
2249 struct berval **keys;
2250 HASH_CONTEXT HASHcontext;
2251 unsigned char HASHdigest[HASH_BYTES];
2252 struct berval digest;
2253 digest.bv_val = HASHdigest;
2254 digest.bv_len = sizeof(HASHdigest);
2256 for( i=0; values[i] != NULL; i++ ) {
2257 /* empty - just count them */
2260 /* we should have at least one value at this point */
2263 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2265 slen = strlen( syntax->ssyn_oid );
2266 mlen = strlen( mr->smr_oid );
2268 for( i=0; values[i] != NULL; i++ ) {
2269 struct berval *value = values[i];
2271 HASH_Init( &HASHcontext );
2272 if( prefix != NULL && prefix->bv_len > 0 ) {
2273 HASH_Update( &HASHcontext,
2274 prefix->bv_val, prefix->bv_len );
2276 HASH_Update( &HASHcontext,
2277 syntax->ssyn_oid, slen );
2278 HASH_Update( &HASHcontext,
2279 mr->smr_oid, mlen );
2280 HASH_Update( &HASHcontext,
2281 value->bv_val, value->bv_len );
2282 HASH_Final( HASHdigest, &HASHcontext );
2284 keys[i] = ber_bvdup( &digest );
2289 return LDAP_SUCCESS;
2292 /* Index generation function */
2293 int caseExactIA5Filter(
2298 struct berval *prefix,
2300 struct berval ***keysp )
2303 struct berval **keys;
2304 HASH_CONTEXT HASHcontext;
2305 unsigned char HASHdigest[HASH_BYTES];
2306 struct berval *value;
2307 struct berval digest;
2308 digest.bv_val = HASHdigest;
2309 digest.bv_len = sizeof(HASHdigest);
2311 slen = strlen( syntax->ssyn_oid );
2312 mlen = strlen( mr->smr_oid );
2314 value = (struct berval *) assertValue;
2316 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2318 HASH_Init( &HASHcontext );
2319 if( prefix != NULL && prefix->bv_len > 0 ) {
2320 HASH_Update( &HASHcontext,
2321 prefix->bv_val, prefix->bv_len );
2323 HASH_Update( &HASHcontext,
2324 syntax->ssyn_oid, slen );
2325 HASH_Update( &HASHcontext,
2326 mr->smr_oid, mlen );
2327 HASH_Update( &HASHcontext,
2328 value->bv_val, value->bv_len );
2329 HASH_Final( HASHdigest, &HASHcontext );
2331 keys[0] = ber_bvdup( &digest );
2335 return LDAP_SUCCESS;
2338 /* Substrings Index generation function */
2339 int caseExactIA5SubstringsIndexer(
2344 struct berval *prefix,
2345 struct berval **values,
2346 struct berval ***keysp )
2350 struct berval **keys;
2351 HASH_CONTEXT HASHcontext;
2352 unsigned char HASHdigest[HASH_BYTES];
2353 struct berval digest;
2354 digest.bv_val = HASHdigest;
2355 digest.bv_len = sizeof(HASHdigest);
2357 /* we should have at least one value at this point */
2358 assert( values != NULL && values[0] != NULL );
2361 for( i=0; values[i] != NULL; i++ ) {
2362 /* count number of indices to generate */
2363 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2367 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2368 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2369 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2370 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2372 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2376 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2377 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2378 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2382 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2383 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2384 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2385 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2387 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2393 /* no keys to generate */
2395 return LDAP_SUCCESS;
2398 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2400 slen = strlen( syntax->ssyn_oid );
2401 mlen = strlen( mr->smr_oid );
2404 for( i=0; values[i] != NULL; i++ ) {
2406 struct berval *value;
2409 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2411 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2412 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2414 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2415 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2417 for( j=0; j<max; j++ ) {
2418 HASH_Init( &HASHcontext );
2419 if( prefix != NULL && prefix->bv_len > 0 ) {
2420 HASH_Update( &HASHcontext,
2421 prefix->bv_val, prefix->bv_len );
2424 HASH_Update( &HASHcontext,
2425 &pre, sizeof( pre ) );
2426 HASH_Update( &HASHcontext,
2427 syntax->ssyn_oid, slen );
2428 HASH_Update( &HASHcontext,
2429 mr->smr_oid, mlen );
2430 HASH_Update( &HASHcontext,
2432 SLAP_INDEX_SUBSTR_MAXLEN );
2433 HASH_Final( HASHdigest, &HASHcontext );
2435 keys[nkeys++] = ber_bvdup( &digest );
2439 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2440 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2442 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2445 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2446 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2447 HASH_Init( &HASHcontext );
2448 if( prefix != NULL && prefix->bv_len > 0 ) {
2449 HASH_Update( &HASHcontext,
2450 prefix->bv_val, prefix->bv_len );
2452 HASH_Update( &HASHcontext,
2453 &pre, sizeof( pre ) );
2454 HASH_Update( &HASHcontext,
2455 syntax->ssyn_oid, slen );
2456 HASH_Update( &HASHcontext,
2457 mr->smr_oid, mlen );
2458 HASH_Update( &HASHcontext,
2460 HASH_Final( HASHdigest, &HASHcontext );
2462 keys[nkeys++] = ber_bvdup( &digest );
2465 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2466 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2467 HASH_Init( &HASHcontext );
2468 if( prefix != NULL && prefix->bv_len > 0 ) {
2469 HASH_Update( &HASHcontext,
2470 prefix->bv_val, prefix->bv_len );
2472 HASH_Update( &HASHcontext,
2473 &pre, sizeof( pre ) );
2474 HASH_Update( &HASHcontext,
2475 syntax->ssyn_oid, slen );
2476 HASH_Update( &HASHcontext,
2477 mr->smr_oid, mlen );
2478 HASH_Update( &HASHcontext,
2479 &value->bv_val[value->bv_len-j], j );
2480 HASH_Final( HASHdigest, &HASHcontext );
2482 keys[nkeys++] = ber_bvdup( &digest );
2496 return LDAP_SUCCESS;
2499 int caseExactIA5SubstringsFilter(
2504 struct berval *prefix,
2506 struct berval ***keysp )
2508 SubstringsAssertion *sa = assertValue;
2510 ber_len_t nkeys = 0;
2511 size_t slen, mlen, klen;
2512 struct berval **keys;
2513 HASH_CONTEXT HASHcontext;
2514 unsigned char HASHdigest[HASH_BYTES];
2515 struct berval *value;
2516 struct berval digest;
2518 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2519 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2524 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2526 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2527 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2528 /* don't bother accounting for stepping */
2529 nkeys += sa->sa_any[i]->bv_len -
2530 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2535 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2536 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2543 return LDAP_SUCCESS;
2546 digest.bv_val = HASHdigest;
2547 digest.bv_len = sizeof(HASHdigest);
2549 slen = strlen( syntax->ssyn_oid );
2550 mlen = strlen( mr->smr_oid );
2552 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2555 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2556 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2558 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2559 value = sa->sa_initial;
2561 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2562 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2564 HASH_Init( &HASHcontext );
2565 if( prefix != NULL && prefix->bv_len > 0 ) {
2566 HASH_Update( &HASHcontext,
2567 prefix->bv_val, prefix->bv_len );
2569 HASH_Update( &HASHcontext,
2570 &pre, sizeof( pre ) );
2571 HASH_Update( &HASHcontext,
2572 syntax->ssyn_oid, slen );
2573 HASH_Update( &HASHcontext,
2574 mr->smr_oid, mlen );
2575 HASH_Update( &HASHcontext,
2576 value->bv_val, klen );
2577 HASH_Final( HASHdigest, &HASHcontext );
2579 keys[nkeys++] = ber_bvdup( &digest );
2582 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2584 pre = SLAP_INDEX_SUBSTR_PREFIX;
2585 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2587 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2588 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2592 value = sa->sa_any[i];
2595 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2596 j += SLAP_INDEX_SUBSTR_STEP )
2598 HASH_Init( &HASHcontext );
2599 if( prefix != NULL && prefix->bv_len > 0 ) {
2600 HASH_Update( &HASHcontext,
2601 prefix->bv_val, prefix->bv_len );
2603 HASH_Update( &HASHcontext,
2604 &pre, sizeof( pre ) );
2605 HASH_Update( &HASHcontext,
2606 syntax->ssyn_oid, slen );
2607 HASH_Update( &HASHcontext,
2608 mr->smr_oid, mlen );
2609 HASH_Update( &HASHcontext,
2610 &value->bv_val[j], klen );
2611 HASH_Final( HASHdigest, &HASHcontext );
2613 keys[nkeys++] = ber_bvdup( &digest );
2618 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2619 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2621 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2622 value = sa->sa_final;
2624 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2625 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2627 HASH_Init( &HASHcontext );
2628 if( prefix != NULL && prefix->bv_len > 0 ) {
2629 HASH_Update( &HASHcontext,
2630 prefix->bv_val, prefix->bv_len );
2632 HASH_Update( &HASHcontext,
2633 &pre, sizeof( pre ) );
2634 HASH_Update( &HASHcontext,
2635 syntax->ssyn_oid, slen );
2636 HASH_Update( &HASHcontext,
2637 mr->smr_oid, mlen );
2638 HASH_Update( &HASHcontext,
2639 &value->bv_val[value->bv_len-klen], klen );
2640 HASH_Final( HASHdigest, &HASHcontext );
2642 keys[nkeys++] = ber_bvdup( &digest );
2653 return LDAP_SUCCESS;
2662 struct berval *value,
2663 void *assertedValue )
2665 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2667 if( match == 0 && value->bv_len ) {
2668 match = strncasecmp( value->bv_val,
2669 ((struct berval *) assertedValue)->bv_val,
2674 return LDAP_SUCCESS;
2678 caseIgnoreIA5SubstringsMatch(
2683 struct berval *value,
2684 void *assertedValue )
2687 SubstringsAssertion *sub = assertedValue;
2688 struct berval left = *value;
2692 /* Add up asserted input length */
2693 if( sub->sa_initial ) {
2694 inlen += sub->sa_initial->bv_len;
2697 for(i=0; sub->sa_any[i] != NULL; i++) {
2698 inlen += sub->sa_any[i]->bv_len;
2701 if( sub->sa_final ) {
2702 inlen += sub->sa_final->bv_len;
2705 if( sub->sa_initial ) {
2706 if( inlen > left.bv_len ) {
2711 match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
2712 sub->sa_initial->bv_len );
2718 left.bv_val += sub->sa_initial->bv_len;
2719 left.bv_len -= sub->sa_initial->bv_len;
2720 inlen -= sub->sa_initial->bv_len;
2723 if( sub->sa_final ) {
2724 if( inlen > left.bv_len ) {
2729 match = strncasecmp( sub->sa_final->bv_val,
2730 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2731 sub->sa_final->bv_len );
2737 left.bv_len -= sub->sa_final->bv_len;
2738 inlen -= sub->sa_final->bv_len;
2742 for(i=0; sub->sa_any[i]; i++) {
2747 if( inlen > left.bv_len ) {
2748 /* not enough length */
2753 if( sub->sa_any[i]->bv_len == 0 ) {
2757 p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
2764 idx = p - left.bv_val;
2765 assert( idx < left.bv_len );
2767 if( idx >= left.bv_len ) {
2768 /* this shouldn't happen */
2775 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2776 /* not enough left */
2781 match = strncasecmp( left.bv_val,
2782 sub->sa_any[i]->bv_val,
2783 sub->sa_any[i]->bv_len );
2792 left.bv_val += sub->sa_any[i]->bv_len;
2793 left.bv_len -= sub->sa_any[i]->bv_len;
2794 inlen -= sub->sa_any[i]->bv_len;
2800 return LDAP_SUCCESS;
2803 /* Index generation function */
2804 int caseIgnoreIA5Indexer(
2809 struct berval *prefix,
2810 struct berval **values,
2811 struct berval ***keysp )
2815 struct berval **keys;
2816 HASH_CONTEXT HASHcontext;
2817 unsigned char HASHdigest[HASH_BYTES];
2818 struct berval digest;
2819 digest.bv_val = HASHdigest;
2820 digest.bv_len = sizeof(HASHdigest);
2822 /* we should have at least one value at this point */
2823 assert( values != NULL && values[0] != NULL );
2825 for( i=0; values[i] != NULL; i++ ) {
2826 /* just count them */
2829 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2831 slen = strlen( syntax->ssyn_oid );
2832 mlen = strlen( mr->smr_oid );
2834 for( i=0; values[i] != NULL; i++ ) {
2835 struct berval *value = ber_bvdup( values[i] );
2836 ldap_pvt_str2upper( value->bv_val );
2838 HASH_Init( &HASHcontext );
2839 if( prefix != NULL && prefix->bv_len > 0 ) {
2840 HASH_Update( &HASHcontext,
2841 prefix->bv_val, prefix->bv_len );
2843 HASH_Update( &HASHcontext,
2844 syntax->ssyn_oid, slen );
2845 HASH_Update( &HASHcontext,
2846 mr->smr_oid, mlen );
2847 HASH_Update( &HASHcontext,
2848 value->bv_val, value->bv_len );
2849 HASH_Final( HASHdigest, &HASHcontext );
2851 ber_bvfree( value );
2853 keys[i] = ber_bvdup( &digest );
2858 return LDAP_SUCCESS;
2861 /* Index generation function */
2862 int caseIgnoreIA5Filter(
2867 struct berval *prefix,
2869 struct berval ***keysp )
2872 struct berval **keys;
2873 HASH_CONTEXT HASHcontext;
2874 unsigned char HASHdigest[HASH_BYTES];
2875 struct berval *value;
2876 struct berval digest;
2877 digest.bv_val = HASHdigest;
2878 digest.bv_len = sizeof(HASHdigest);
2880 slen = strlen( syntax->ssyn_oid );
2881 mlen = strlen( mr->smr_oid );
2883 value = ber_bvdup( (struct berval *) assertValue );
2884 ldap_pvt_str2upper( value->bv_val );
2886 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2888 HASH_Init( &HASHcontext );
2889 if( prefix != NULL && prefix->bv_len > 0 ) {
2890 HASH_Update( &HASHcontext,
2891 prefix->bv_val, prefix->bv_len );
2893 HASH_Update( &HASHcontext,
2894 syntax->ssyn_oid, slen );
2895 HASH_Update( &HASHcontext,
2896 mr->smr_oid, mlen );
2897 HASH_Update( &HASHcontext,
2898 value->bv_val, value->bv_len );
2899 HASH_Final( HASHdigest, &HASHcontext );
2901 keys[0] = ber_bvdup( &digest );
2904 ber_bvfree( value );
2908 return LDAP_SUCCESS;
2911 /* Substrings Index generation function */
2912 int caseIgnoreIA5SubstringsIndexer(
2917 struct berval *prefix,
2918 struct berval **values,
2919 struct berval ***keysp )
2923 struct berval **keys;
2924 HASH_CONTEXT HASHcontext;
2925 unsigned char HASHdigest[HASH_BYTES];
2926 struct berval digest;
2927 digest.bv_val = HASHdigest;
2928 digest.bv_len = sizeof(HASHdigest);
2930 /* we should have at least one value at this point */
2931 assert( values != NULL && values[0] != NULL );
2934 for( i=0; values[i] != NULL; i++ ) {
2935 /* count number of indices to generate */
2936 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2940 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2941 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2942 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2943 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2945 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2949 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2950 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2951 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2955 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2956 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2957 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2958 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2960 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2966 /* no keys to generate */
2968 return LDAP_SUCCESS;
2971 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2973 slen = strlen( syntax->ssyn_oid );
2974 mlen = strlen( mr->smr_oid );
2977 for( i=0; values[i] != NULL; i++ ) {
2979 struct berval *value;
2981 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2983 value = ber_bvdup( values[i] );
2984 ldap_pvt_str2upper( value->bv_val );
2986 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2987 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2989 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2990 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2992 for( j=0; j<max; j++ ) {
2993 HASH_Init( &HASHcontext );
2994 if( prefix != NULL && prefix->bv_len > 0 ) {
2995 HASH_Update( &HASHcontext,
2996 prefix->bv_val, prefix->bv_len );
2999 HASH_Update( &HASHcontext,
3000 &pre, sizeof( pre ) );
3001 HASH_Update( &HASHcontext,
3002 syntax->ssyn_oid, slen );
3003 HASH_Update( &HASHcontext,
3004 mr->smr_oid, mlen );
3005 HASH_Update( &HASHcontext,
3007 SLAP_INDEX_SUBSTR_MAXLEN );
3008 HASH_Final( HASHdigest, &HASHcontext );
3010 keys[nkeys++] = ber_bvdup( &digest );
3014 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3015 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3017 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3020 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3021 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3022 HASH_Init( &HASHcontext );
3023 if( prefix != NULL && prefix->bv_len > 0 ) {
3024 HASH_Update( &HASHcontext,
3025 prefix->bv_val, prefix->bv_len );
3027 HASH_Update( &HASHcontext,
3028 &pre, sizeof( pre ) );
3029 HASH_Update( &HASHcontext,
3030 syntax->ssyn_oid, slen );
3031 HASH_Update( &HASHcontext,
3032 mr->smr_oid, mlen );
3033 HASH_Update( &HASHcontext,
3035 HASH_Final( HASHdigest, &HASHcontext );
3037 keys[nkeys++] = ber_bvdup( &digest );
3040 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3041 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3042 HASH_Init( &HASHcontext );
3043 if( prefix != NULL && prefix->bv_len > 0 ) {
3044 HASH_Update( &HASHcontext,
3045 prefix->bv_val, prefix->bv_len );
3047 HASH_Update( &HASHcontext,
3048 &pre, sizeof( pre ) );
3049 HASH_Update( &HASHcontext,
3050 syntax->ssyn_oid, slen );
3051 HASH_Update( &HASHcontext,
3052 mr->smr_oid, mlen );
3053 HASH_Update( &HASHcontext,
3054 &value->bv_val[value->bv_len-j], j );
3055 HASH_Final( HASHdigest, &HASHcontext );
3057 keys[nkeys++] = ber_bvdup( &digest );
3062 ber_bvfree( value );
3073 return LDAP_SUCCESS;
3076 int caseIgnoreIA5SubstringsFilter(
3081 struct berval *prefix,
3083 struct berval ***keysp )
3085 SubstringsAssertion *sa = assertValue;
3087 ber_len_t nkeys = 0;
3088 size_t slen, mlen, klen;
3089 struct berval **keys;
3090 HASH_CONTEXT HASHcontext;
3091 unsigned char HASHdigest[HASH_BYTES];
3092 struct berval *value;
3093 struct berval digest;
3095 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3096 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3101 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3103 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3104 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3105 /* don't bother accounting for stepping */
3106 nkeys += sa->sa_any[i]->bv_len -
3107 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3112 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3113 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3120 return LDAP_SUCCESS;
3123 digest.bv_val = HASHdigest;
3124 digest.bv_len = sizeof(HASHdigest);
3126 slen = strlen( syntax->ssyn_oid );
3127 mlen = strlen( mr->smr_oid );
3129 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
3132 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3133 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3135 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3136 value = ber_bvdup( sa->sa_initial );
3137 ldap_pvt_str2upper( value->bv_val );
3139 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3140 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3142 HASH_Init( &HASHcontext );
3143 if( prefix != NULL && prefix->bv_len > 0 ) {
3144 HASH_Update( &HASHcontext,
3145 prefix->bv_val, prefix->bv_len );
3147 HASH_Update( &HASHcontext,
3148 &pre, sizeof( pre ) );
3149 HASH_Update( &HASHcontext,
3150 syntax->ssyn_oid, slen );
3151 HASH_Update( &HASHcontext,
3152 mr->smr_oid, mlen );
3153 HASH_Update( &HASHcontext,
3154 value->bv_val, klen );
3155 HASH_Final( HASHdigest, &HASHcontext );
3157 ber_bvfree( value );
3158 keys[nkeys++] = ber_bvdup( &digest );
3161 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3163 pre = SLAP_INDEX_SUBSTR_PREFIX;
3164 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3166 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3167 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3171 value = ber_bvdup( sa->sa_any[i] );
3172 ldap_pvt_str2upper( value->bv_val );
3175 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3176 j += SLAP_INDEX_SUBSTR_STEP )
3178 HASH_Init( &HASHcontext );
3179 if( prefix != NULL && prefix->bv_len > 0 ) {
3180 HASH_Update( &HASHcontext,
3181 prefix->bv_val, prefix->bv_len );
3183 HASH_Update( &HASHcontext,
3184 &pre, sizeof( pre ) );
3185 HASH_Update( &HASHcontext,
3186 syntax->ssyn_oid, slen );
3187 HASH_Update( &HASHcontext,
3188 mr->smr_oid, mlen );
3189 HASH_Update( &HASHcontext,
3190 &value->bv_val[j], klen );
3191 HASH_Final( HASHdigest, &HASHcontext );
3193 keys[nkeys++] = ber_bvdup( &digest );
3196 ber_bvfree( value );
3200 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3201 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3203 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3204 value = ber_bvdup( sa->sa_final );
3205 ldap_pvt_str2upper( value->bv_val );
3207 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3208 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3210 HASH_Init( &HASHcontext );
3211 if( prefix != NULL && prefix->bv_len > 0 ) {
3212 HASH_Update( &HASHcontext,
3213 prefix->bv_val, prefix->bv_len );
3215 HASH_Update( &HASHcontext,
3216 &pre, sizeof( pre ) );
3217 HASH_Update( &HASHcontext,
3218 syntax->ssyn_oid, slen );
3219 HASH_Update( &HASHcontext,
3220 mr->smr_oid, mlen );
3221 HASH_Update( &HASHcontext,
3222 &value->bv_val[value->bv_len-klen], klen );
3223 HASH_Final( HASHdigest, &HASHcontext );
3225 ber_bvfree( value );
3226 keys[nkeys++] = ber_bvdup( &digest );
3237 return LDAP_SUCCESS;
3241 numericStringValidate(
3247 for(i=0; i < in->bv_len; i++) {
3248 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3249 return LDAP_INVALID_SYNTAX;
3253 return LDAP_SUCCESS;
3257 numericStringNormalize(
3260 struct berval **normalized )
3262 /* removal all spaces */
3263 struct berval *newval;
3266 newval = ch_malloc( sizeof( struct berval ) );
3267 newval->bv_val = ch_malloc( val->bv_len + 1 );
3273 if ( ASCII_SPACE( *p ) ) {
3274 /* Ignore whitespace */
3281 /* we should have copied no more then is in val */
3282 assert( (q - newval->bv_val) <= (p - val->bv_val) );
3284 /* null terminate */
3287 newval->bv_len = q - newval->bv_val;
3288 *normalized = newval;
3290 return LDAP_SUCCESS;
3294 objectIdentifierFirstComponentMatch(
3299 struct berval *value,
3300 void *assertedValue )
3302 int rc = LDAP_SUCCESS;
3304 struct berval *asserted = (struct berval *) assertedValue;
3308 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3309 return LDAP_INVALID_SYNTAX;
3312 /* trim leading white space */
3313 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3317 /* grab next word */
3318 oid.bv_val = &value->bv_val[i];
3319 oid.bv_len = value->bv_len - i;
3320 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3325 /* insert attributeTypes, objectclass check here */
3326 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3327 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3330 char *stored = ch_malloc( oid.bv_len + 1 );
3331 AC_MEMCPY( stored, oid.bv_val, oid.bv_len );
3332 stored[oid.bv_len] = '\0';
3334 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3335 MatchingRule *asserted_mr = mr_find( asserted->bv_val );
3336 MatchingRule *stored_mr = mr_find( stored );
3338 if( asserted_mr == NULL ) {
3339 rc = SLAPD_COMPARE_UNDEFINED;
3341 match = asserted_mr != stored_mr;
3344 } else if ( !strcmp( syntax->ssyn_oid,
3345 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3347 AttributeType *asserted_at = at_find( asserted->bv_val );
3348 AttributeType *stored_at = at_find( stored );
3350 if( asserted_at == NULL ) {
3351 rc = SLAPD_COMPARE_UNDEFINED;
3353 match = asserted_at != stored_at;
3356 } else if ( !strcmp( syntax->ssyn_oid,
3357 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3359 ObjectClass *asserted_oc = oc_find( asserted->bv_val );
3360 ObjectClass *stored_oc = oc_find( stored );
3362 if( asserted_oc == NULL ) {
3363 rc = SLAPD_COMPARE_UNDEFINED;
3365 match = asserted_oc != stored_oc;
3373 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3374 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3375 match, value->bv_val, asserted->bv_val ));
3377 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3378 "%d\n\t\"%s\"\n\t\"%s\"\n",
3379 match, value->bv_val, asserted->bv_val );
3383 if( rc == LDAP_SUCCESS ) *matchp = match;
3393 struct berval *value,
3394 void *assertedValue )
3396 long lValue, lAssertedValue;
3398 /* safe to assume integers are NUL terminated? */
3399 lValue = strtoul(value->bv_val, NULL, 10);
3400 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3401 return LDAP_CONSTRAINT_VIOLATION;
3403 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3404 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3405 return LDAP_CONSTRAINT_VIOLATION;
3407 *matchp = (lValue & lAssertedValue);
3408 return LDAP_SUCCESS;
3417 struct berval *value,
3418 void *assertedValue )
3420 long lValue, lAssertedValue;
3422 /* safe to assume integers are NUL terminated? */
3423 lValue = strtoul(value->bv_val, NULL, 10);
3424 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3425 return LDAP_CONSTRAINT_VIOLATION;
3427 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3428 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3429 return LDAP_CONSTRAINT_VIOLATION;
3431 *matchp = (lValue | lAssertedValue);
3432 return LDAP_SUCCESS;
3436 #include <openssl/x509.h>
3437 #include <openssl/err.h>
3438 char digit[] = "0123456789";
3441 * Next function returns a string representation of a ASN1_INTEGER.
3442 * It works for unlimited lengths.
3445 static struct berval *
3446 asn1_integer2str(ASN1_INTEGER *a)
3451 /* We work backwards, make it fill from the end of buf */
3452 p = buf + sizeof(buf) - 1;
3455 if ( a == NULL || a->length == 0 ) {
3463 /* We want to preserve the original */
3464 copy = ch_malloc(n*sizeof(unsigned int));
3465 for (i = 0; i<n; i++) {
3466 copy[i] = a->data[i];
3470 * base indicates the index of the most significant
3471 * byte that might be nonzero. When it goes off the
3472 * end, we now there is nothing left to do.
3479 for (i = base; i<n; i++ ) {
3480 copy[i] += carry*256;
3481 carry = copy[i] % 10;
3486 * Way too large, we need to leave
3487 * room for sign if negative
3491 *--p = digit[carry];
3492 if (copy[base] == 0)
3498 if ( a->type == V_ASN1_NEG_INTEGER ) {
3502 return ber_bvstrdup(p);
3505 /* Get a DN in RFC2253 format from a X509_NAME internal struct */
3506 static struct berval *
3507 dn_openssl2ldap(X509_NAME *name)
3509 char issuer_dn[1024];
3512 bio = BIO_new(BIO_s_mem());
3515 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3516 "dn_openssl2ldap: error creating BIO_s_mem: %s\n",
3517 ERR_error_string(ERR_get_error(),NULL)));
3519 Debug( LDAP_DEBUG_ARGS, "dn_openssl2ldap: "
3520 "error creating BIO: %s\n",
3521 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3525 X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253);
3527 BIO_gets(bio, issuer_dn, 1024);
3530 return ber_bvstrdup(issuer_dn);
3534 * Given a certificate in DER format, extract the corresponding
3535 * assertion value for certificateExactMatch
3538 certificateExactConvert(
3540 struct berval ** out )
3543 unsigned char *p = in->bv_val;
3544 struct berval *serial;
3545 struct berval *issuer_dn;
3546 struct berval *bv_tmp;
3549 xcert = d2i_X509(NULL, &p, in->bv_len);
3552 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3553 "certificateExactConvert: error parsing cert: %s\n",
3554 ERR_error_string(ERR_get_error(),NULL)));
3556 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3557 "error parsing cert: %s\n",
3558 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3560 return LDAP_INVALID_SYNTAX;
3563 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3566 return LDAP_INVALID_SYNTAX;
3568 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
3572 return LDAP_INVALID_SYNTAX;
3574 /* Actually, dn_openssl2ldap returns in a normalized format, but
3575 it is different from our normalized format */
3577 if ( dnNormalize(NULL, bv_tmp, &issuer_dn) != LDAP_SUCCESS ) {
3581 return LDAP_INVALID_SYNTAX;
3587 *out = ch_malloc(sizeof(struct berval));
3588 (*out)->bv_len = serial->bv_len + 3 + issuer_dn->bv_len + 1;
3589 (*out)->bv_val = ch_malloc((*out)->bv_len);
3591 AC_MEMCPY(p, serial->bv_val, serial->bv_len);
3592 p += serial->bv_len;
3593 AC_MEMCPY(p, " $ ", 3);
3595 AC_MEMCPY(p, issuer_dn->bv_val, issuer_dn->bv_len);
3596 p += issuer_dn->bv_len;
3600 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3601 "certificateExactConvert: \n %s\n",
3604 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3606 (*out)->bv_val, NULL, NULL );
3610 ber_bvfree(issuer_dn);
3612 return LDAP_SUCCESS;
3616 serial_and_issuer_parse(
3617 struct berval *assertion,
3618 struct berval **serial,
3619 struct berval **issuer_dn
3627 begin = assertion->bv_val;
3628 end = assertion->bv_val+assertion->bv_len-1;
3629 for (p=begin; p<=end && *p != '$'; p++)
3632 return LDAP_INVALID_SYNTAX;
3634 /* p now points at the $ sign, now use begin and end to delimit the
3636 while (ASCII_SPACE(*begin))
3639 while (ASCII_SPACE(*end))
3642 q = ch_malloc( (end-begin+1)+1 );
3643 AC_MEMCPY( q, begin, end-begin+1 );
3644 q[end-begin+1] = '\0';
3645 *serial = ber_bvstr(q);
3647 /* now extract the issuer, remember p was at the dollar sign */
3649 end = assertion->bv_val+assertion->bv_len-1;
3650 while (ASCII_SPACE(*begin))
3652 /* should we trim spaces at the end too? is it safe always? */
3654 q = ch_malloc( (end-begin+1)+1 );
3655 AC_MEMCPY( q, begin, end-begin+1 );
3656 q[end-begin+1] = '\0';
3657 *issuer_dn = ber_bvstr(dn_normalize(q));
3659 return LDAP_SUCCESS;
3663 certificateExactMatch(
3668 struct berval *value,
3669 void *assertedValue )
3672 unsigned char *p = value->bv_val;
3673 struct berval *serial;
3674 struct berval *issuer_dn;
3675 struct berval *asserted_serial;
3676 struct berval *asserted_issuer_dn;
3679 xcert = d2i_X509(NULL, &p, value->bv_len);
3682 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3683 "certificateExactMatch: error parsing cert: %s\n",
3684 ERR_error_string(ERR_get_error(),NULL)));
3686 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
3687 "error parsing cert: %s\n",
3688 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3690 return LDAP_INVALID_SYNTAX;
3693 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3694 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
3698 serial_and_issuer_parse(assertedValue,
3700 &asserted_issuer_dn);
3705 slap_schema.si_syn_integer,
3706 slap_schema.si_mr_integerMatch,
3709 if ( ret == LDAP_SUCCESS ) {
3710 if ( *matchp == 0 ) {
3711 /* We need to normalize everything for dnMatch */
3715 slap_schema.si_syn_distinguishedName,
3716 slap_schema.si_mr_distinguishedNameMatch,
3718 asserted_issuer_dn);
3723 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3724 "certificateExactMatch: %d\n %s $ %s\n %s $ %s\n",
3725 *matchp, serial->bv_val, issuer_dn->bv_val,
3726 asserted->serial->bv_val, asserted_issuer_dn->bv_val));
3728 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3729 "%d\n\t\"%s $ %s\"\n",
3730 *matchp, serial->bv_val, issuer_dn->bv_val );
3731 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3732 asserted_serial->bv_val, asserted_issuer_dn->bv_val,
3737 ber_bvfree(issuer_dn);
3738 ber_bvfree(asserted_serial);
3739 ber_bvfree(asserted_issuer_dn);
3745 * Index generation function
3746 * We just index the serials, in most scenarios the issuer DN is one of
3747 * a very small set of values.
3749 int certificateExactIndexer(
3754 struct berval *prefix,
3755 struct berval **values,
3756 struct berval ***keysp )
3759 struct berval **keys;
3762 struct berval * serial;
3764 /* we should have at least one value at this point */
3765 assert( values != NULL && values[0] != NULL );
3767 for( i=0; values[i] != NULL; i++ ) {
3768 /* empty -- just count them */
3771 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
3773 for( i=0; values[i] != NULL; i++ ) {
3774 p = values[i]->bv_val;
3775 xcert = d2i_X509(NULL, &p, values[i]->bv_len);
3778 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3779 "certificateExactIndexer: error parsing cert: %s\n",
3780 ERR_error_string(ERR_get_error(),NULL)));
3782 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3783 "error parsing cert: %s\n",
3784 ERR_error_string(ERR_get_error(),NULL),
3787 /* Do we leak keys on error? */
3788 return LDAP_INVALID_SYNTAX;
3791 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3793 integerNormalize( slap_schema.si_syn_integer,
3798 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3799 "certificateExactIndexer: returning: %s\n",
3802 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3811 return LDAP_SUCCESS;
3814 /* Index generation function */
3815 /* We think this is always called with a value in matching rule syntax */
3816 int certificateExactFilter(
3821 struct berval *prefix,
3823 struct berval ***keysp )
3825 struct berval **keys;
3826 struct berval *asserted_serial;
3827 struct berval *asserted_issuer_dn;
3829 serial_and_issuer_parse(assertValue,
3831 &asserted_issuer_dn);
3833 keys = ch_malloc( sizeof( struct berval * ) * 2 );
3834 integerNormalize( syntax, asserted_serial, &keys[0] );
3838 ber_bvfree(asserted_serial);
3839 ber_bvfree(asserted_issuer_dn);
3840 return LDAP_SUCCESS;
3845 check_time_syntax (struct berval *val,
3849 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3850 static int mdays[2][12] = {
3851 /* non-leap years */
3852 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3854 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3857 int part, c, tzoffset, leapyear = 0 ;
3859 if( val->bv_len == 0 ) {
3860 return LDAP_INVALID_SYNTAX;
3863 p = (char *)val->bv_val;
3864 e = p + val->bv_len;
3866 /* Ignore initial whitespace */
3867 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3871 if (e - p < 13 - (2 * start)) {
3872 return LDAP_INVALID_SYNTAX;
3875 for (part = 0; part < 9; part++) {
3879 for (part = start; part < 7; part++) {
3881 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3888 return LDAP_INVALID_SYNTAX;
3890 if (c < 0 || c > 9) {
3891 return LDAP_INVALID_SYNTAX;
3897 return LDAP_INVALID_SYNTAX;
3899 if (c < 0 || c > 9) {
3900 return LDAP_INVALID_SYNTAX;
3905 if (part == 2 || part == 3) {
3908 if (parts[part] < 0) {
3909 return LDAP_INVALID_SYNTAX;
3911 if (parts[part] > ceiling[part]) {
3912 return LDAP_INVALID_SYNTAX;
3916 /* leapyear check for the Gregorian calendar (year>1581) */
3917 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
3918 ((parts[0] % 4 == 0) && (parts[1] == 0)))
3923 if (parts[3] > mdays[leapyear][parts[2]]) {
3924 return LDAP_INVALID_SYNTAX;
3929 tzoffset = 0; /* UTC */
3930 } else if (c != '+' && c != '-') {
3931 return LDAP_INVALID_SYNTAX;
3935 } else /* c == '+' */ {
3940 return LDAP_INVALID_SYNTAX;
3943 for (part = 7; part < 9; part++) {
3945 if (c < 0 || c > 9) {
3946 return LDAP_INVALID_SYNTAX;
3951 if (c < 0 || c > 9) {
3952 return LDAP_INVALID_SYNTAX;
3956 if (parts[part] < 0 || parts[part] > ceiling[part]) {
3957 return LDAP_INVALID_SYNTAX;
3962 /* Ignore trailing whitespace */
3963 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3967 return LDAP_INVALID_SYNTAX;
3970 switch ( tzoffset ) {
3971 case -1: /* negativ offset to UTC, ie west of Greenwich */
3972 parts[4] += parts[7];
3973 parts[5] += parts[8];
3974 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
3978 c = mdays[leapyear][parts[2]];
3980 if (parts[part] > c) {
3981 parts[part] -= c + 1;
3986 case 1: /* positive offset to UTC, ie east of Greenwich */
3987 parts[4] -= parts[7];
3988 parts[5] -= parts[8];
3989 for (part = 6; --part > 0; ) {
3993 /* first arg to % needs to be non negativ */
3994 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
3996 if (parts[part] < 0) {
3997 parts[part] += c + 1;
4002 case 0: /* already UTC */
4006 return LDAP_SUCCESS;
4013 struct berval **normalized )
4018 rc = check_time_syntax(val, 1, parts);
4019 if (rc != LDAP_SUCCESS) {
4024 out = ch_malloc( sizeof(struct berval) );
4026 return LBER_ERROR_MEMORY;
4029 out->bv_val = ch_malloc( 14 );
4030 if ( out->bv_val == NULL ) {
4032 return LBER_ERROR_MEMORY;
4035 sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ldZ",
4036 parts[1], parts[2] + 1, parts[3] + 1,
4037 parts[4], parts[5], parts[6] );
4041 return LDAP_SUCCESS;
4051 return check_time_syntax(in, 1, parts);
4055 generalizedTimeValidate(
4061 return check_time_syntax(in, 0, parts);
4065 generalizedTimeNormalize(
4068 struct berval **normalized )
4073 rc = check_time_syntax(val, 0, parts);
4074 if (rc != LDAP_SUCCESS) {
4079 out = ch_malloc( sizeof(struct berval) );
4081 return LBER_ERROR_MEMORY;
4084 out->bv_val = ch_malloc( 16 );
4085 if ( out->bv_val == NULL ) {
4087 return LBER_ERROR_MEMORY;
4090 sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ld%02ldZ",
4091 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4092 parts[4], parts[5], parts[6] );
4096 return LDAP_SUCCESS;
4100 nisNetgroupTripleValidate(
4102 struct berval *val )
4107 if ( val->bv_len == 0 ) {
4108 return LDAP_INVALID_SYNTAX;
4111 p = (char *)val->bv_val;
4112 e = p + val->bv_len;
4114 if ( *p != '(' /*')'*/ ) {
4115 return LDAP_INVALID_SYNTAX;
4118 for ( p++; ( p < e ) && ( *p != ')' ); p++ ) {
4122 return LDAP_INVALID_SYNTAX;
4125 } else if ( !ATTR_CHAR( *p ) ) {
4126 return LDAP_INVALID_SYNTAX;
4130 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4131 return LDAP_INVALID_SYNTAX;
4137 return LDAP_INVALID_SYNTAX;
4140 return LDAP_SUCCESS;
4144 bootParameterValidate(
4146 struct berval *val )
4150 if ( val->bv_len == 0 ) {
4151 return LDAP_INVALID_SYNTAX;
4154 p = (char *)val->bv_val;
4155 e = p + val->bv_len;
4158 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4159 if ( !ATTR_CHAR( *p ) ) {
4160 return LDAP_INVALID_SYNTAX;
4165 return LDAP_INVALID_SYNTAX;
4169 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4170 if ( !ATTR_CHAR( *p ) ) {
4171 return LDAP_INVALID_SYNTAX;
4176 return LDAP_INVALID_SYNTAX;
4180 for ( p++; p < e; p++ ) {
4181 if ( !ATTR_CHAR( *p ) ) {
4182 return LDAP_INVALID_SYNTAX;
4186 return LDAP_SUCCESS;
4189 struct syntax_defs_rec {
4192 slap_syntax_validate_func *sd_validate;
4193 slap_syntax_transform_func *sd_normalize;
4194 slap_syntax_transform_func *sd_pretty;
4195 #ifdef SLAPD_BINARY_CONVERSION
4196 slap_syntax_transform_func *sd_ber2str;
4197 slap_syntax_transform_func *sd_str2ber;
4201 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4202 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4204 struct syntax_defs_rec syntax_defs[] = {
4205 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
4206 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4207 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4208 0, NULL, NULL, NULL},
4209 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4210 0, NULL, NULL, NULL},
4211 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
4212 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4213 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_NOT_H_R ")",
4214 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4215 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4216 0, bitStringValidate, NULL, NULL },
4217 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4218 0, booleanValidate, NULL, NULL},
4219 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4220 X_BINARY X_NOT_H_R ")",
4221 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4222 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4223 X_BINARY X_NOT_H_R ")",
4224 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4225 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4226 X_BINARY X_NOT_H_R ")",
4227 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4228 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4229 0, countryStringValidate, IA5StringNormalize, NULL},
4230 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4231 0, dnValidate, dnNormalize, dnPretty},
4232 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4233 0, NULL, NULL, NULL},
4234 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4235 0, NULL, NULL, NULL},
4236 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4237 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4238 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4239 0, NULL, NULL, NULL},
4240 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4241 0, NULL, NULL, NULL},
4242 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4243 0, NULL, NULL, NULL},
4244 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4245 0, NULL, NULL, NULL},
4246 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4247 0, NULL, NULL, NULL},
4248 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4249 0, printablesStringValidate, IA5StringNormalize, NULL},
4250 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4251 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4252 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4253 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4254 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4255 0, NULL, NULL, NULL},
4256 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4257 0, IA5StringValidate, IA5StringNormalize, NULL},
4258 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4259 0, integerValidate, integerNormalize, NULL},
4260 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4261 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4262 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4263 0, NULL, NULL, NULL},
4264 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4265 0, NULL, NULL, NULL},
4266 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4267 0, NULL, NULL, NULL},
4268 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4269 0, NULL, NULL, NULL},
4270 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4271 0, NULL, NULL, NULL},
4272 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4273 0, nameUIDValidate, nameUIDNormalize, NULL},
4274 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4275 0, NULL, NULL, NULL},
4276 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4277 0, numericStringValidate, numericStringNormalize, NULL},
4278 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4279 0, NULL, NULL, NULL},
4280 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4281 0, oidValidate, NULL, NULL},
4282 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4283 0, IA5StringValidate, IA5StringNormalize, NULL},
4284 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4285 0, blobValidate, NULL, NULL},
4286 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4287 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4288 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4289 0, NULL, NULL, NULL},
4290 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4291 0, NULL, NULL, NULL},
4292 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4293 0, printableStringValidate, IA5StringNormalize, NULL},
4294 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4295 X_BINARY X_NOT_H_R ")",
4296 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4297 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4298 0, printableStringValidate, IA5StringNormalize, NULL},
4299 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4300 0, NULL, NULL, NULL},
4301 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4302 0, printablesStringValidate, IA5StringNormalize, NULL},
4303 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4304 0, utcTimeValidate, utcTimeNormalize, NULL},
4305 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4306 0, NULL, NULL, NULL},
4307 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4308 0, NULL, NULL, NULL},
4309 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4310 0, NULL, NULL, NULL},
4311 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4312 0, NULL, NULL, NULL},
4313 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4314 0, NULL, NULL, NULL},
4316 /* RFC 2307 NIS Syntaxes */
4317 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4318 0, nisNetgroupTripleValidate, NULL, NULL},
4319 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4320 0, bootParameterValidate, NULL, NULL},
4324 /* These OIDs are not published yet, but will be in the next
4325 * I-D for PKIX LDAPv3 schema as have been advanced by David
4326 * Chadwick in private mail.
4328 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4329 0, NULL, NULL, NULL},
4332 /* OpenLDAP Experimental Syntaxes */
4333 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4334 0, UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4336 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4337 0, NULL, NULL, NULL},
4339 /* OpenLDAP Void Syntax */
4340 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4341 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4342 {NULL, 0, NULL, NULL, NULL}
4345 struct mrule_defs_rec {
4347 slap_mask_t mrd_usage;
4348 slap_mr_convert_func * mrd_convert;
4349 slap_mr_normalize_func * mrd_normalize;
4350 slap_mr_match_func * mrd_match;
4351 slap_mr_indexer_func * mrd_indexer;
4352 slap_mr_filter_func * mrd_filter;
4354 char * mrd_associated;
4358 * Other matching rules in X.520 that we do not use (yet):
4360 * 2.5.13.9 numericStringOrderingMatch
4361 * 2.5.13.15 integerOrderingMatch
4362 * 2.5.13.18 octetStringOrderingMatch
4363 * 2.5.13.19 octetStringSubstringsMatch
4364 * 2.5.13.25 uTCTimeMatch
4365 * 2.5.13.26 uTCTimeOrderingMatch
4366 * 2.5.13.31 directoryStringFirstComponentMatch
4367 * 2.5.13.32 wordMatch
4368 * 2.5.13.33 keywordMatch
4369 * 2.5.13.35 certificateMatch
4370 * 2.5.13.36 certificatePairExactMatch
4371 * 2.5.13.37 certificatePairMatch
4372 * 2.5.13.38 certificateListExactMatch
4373 * 2.5.13.39 certificateListMatch
4374 * 2.5.13.40 algorithmIdentifierMatch
4375 * 2.5.13.41 storedPrefixMatch
4376 * 2.5.13.42 attributeCertificateMatch
4377 * 2.5.13.43 readerAndKeyIDMatch
4378 * 2.5.13.44 attributeIntegrityMatch
4381 struct mrule_defs_rec mrule_defs[] = {
4383 * EQUALITY matching rules must be listed after associated APPROX
4384 * matching rules. So, we list all APPROX matching rules first.
4386 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4387 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4388 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4390 directoryStringApproxMatch,
4391 directoryStringApproxIndexer,
4392 directoryStringApproxFilter,
4395 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4396 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4397 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4399 IA5StringApproxMatch,
4400 IA5StringApproxIndexer,
4401 IA5StringApproxFilter,
4405 * Other matching rules
4408 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4409 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4410 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4412 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4415 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4416 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4417 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4419 dnMatch, dnIndexer, dnFilter,
4422 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4423 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4424 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4426 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4427 directoryStringApproxMatchOID },
4429 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4430 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4433 caseIgnoreOrderingMatch, NULL, NULL,
4436 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4437 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4438 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4440 caseExactIgnoreSubstringsMatch,
4441 caseExactIgnoreSubstringsIndexer,
4442 caseExactIgnoreSubstringsFilter,
4445 {"( 2.5.13.5 NAME 'caseExactMatch' "
4446 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4447 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4449 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4450 directoryStringApproxMatchOID },
4452 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4453 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4456 caseExactOrderingMatch, NULL, NULL,
4459 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4460 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4461 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4463 caseExactIgnoreSubstringsMatch,
4464 caseExactIgnoreSubstringsIndexer,
4465 caseExactIgnoreSubstringsFilter,
4468 {"( 2.5.13.8 NAME 'numericStringMatch' "
4469 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4470 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4473 caseIgnoreIA5Indexer,
4474 caseIgnoreIA5Filter,
4477 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4478 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4479 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4481 caseIgnoreIA5SubstringsMatch,
4482 caseIgnoreIA5SubstringsIndexer,
4483 caseIgnoreIA5SubstringsFilter,
4486 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4487 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4488 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4490 caseIgnoreListMatch, NULL, NULL,
4493 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4494 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4495 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4497 caseIgnoreListSubstringsMatch, NULL, NULL,
4500 {"( 2.5.13.13 NAME 'booleanMatch' "
4501 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4502 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4504 booleanMatch, NULL, NULL,
4507 {"( 2.5.13.14 NAME 'integerMatch' "
4508 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4509 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4511 integerMatch, integerIndexer, integerFilter,
4514 {"( 2.5.13.16 NAME 'bitStringMatch' "
4515 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4516 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4518 bitStringMatch, NULL, NULL,
4521 {"( 2.5.13.17 NAME 'octetStringMatch' "
4522 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4523 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4525 octetStringMatch, octetStringIndexer, octetStringFilter,
4528 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4529 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4530 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4532 telephoneNumberMatch,
4533 telephoneNumberIndexer,
4534 telephoneNumberFilter,
4537 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4538 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4539 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4541 telephoneNumberSubstringsMatch,
4542 telephoneNumberSubstringsIndexer,
4543 telephoneNumberSubstringsFilter,
4546 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4547 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4548 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4553 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4554 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4555 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4557 uniqueMemberMatch, NULL, NULL,
4560 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4561 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4562 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4564 protocolInformationMatch, NULL, NULL,
4567 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4568 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4569 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4571 generalizedTimeMatch, NULL, NULL,
4574 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4575 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4578 generalizedTimeOrderingMatch, NULL, NULL,
4581 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4582 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4583 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4585 integerFirstComponentMatch, NULL, NULL,
4588 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4589 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4590 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4592 objectIdentifierFirstComponentMatch, NULL, NULL,
4596 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4597 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4598 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4599 certificateExactConvert, NULL,
4600 certificateExactMatch,
4601 certificateExactIndexer, certificateExactFilter,
4605 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4606 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4607 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4609 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4610 IA5StringApproxMatchOID },
4612 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4613 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4614 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4616 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4617 IA5StringApproxMatchOID },
4619 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4620 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4623 caseIgnoreIA5SubstringsMatch,
4624 caseIgnoreIA5SubstringsIndexer,
4625 caseIgnoreIA5SubstringsFilter,
4628 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4629 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4632 caseExactIA5SubstringsMatch,
4633 caseExactIA5SubstringsIndexer,
4634 caseExactIA5SubstringsFilter,
4637 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4638 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4641 authPasswordMatch, NULL, NULL,
4644 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4645 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4648 OpenLDAPaciMatch, NULL, NULL,
4651 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4652 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4655 integerBitAndMatch, NULL, NULL,
4658 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4659 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4662 integerBitOrMatch, NULL, NULL,
4665 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
4674 /* we should only be called once (from main) */
4675 assert( schema_init_done == 0 );
4677 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4678 res = register_syntax( syntax_defs[i].sd_desc,
4679 syntax_defs[i].sd_flags,
4680 syntax_defs[i].sd_validate,
4681 syntax_defs[i].sd_normalize,
4682 syntax_defs[i].sd_pretty
4683 #ifdef SLAPD_BINARY_CONVERSION
4685 syntax_defs[i].sd_ber2str,
4686 syntax_defs[i].sd_str2ber
4691 fprintf( stderr, "schema_init: Error registering syntax %s\n",
4692 syntax_defs[i].sd_desc );
4697 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4698 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
4700 "schema_init: Ingoring unusable matching rule %s\n",
4701 mrule_defs[i].mrd_desc );
4705 res = register_matching_rule(
4706 mrule_defs[i].mrd_desc,
4707 mrule_defs[i].mrd_usage,
4708 mrule_defs[i].mrd_convert,
4709 mrule_defs[i].mrd_normalize,
4710 mrule_defs[i].mrd_match,
4711 mrule_defs[i].mrd_indexer,
4712 mrule_defs[i].mrd_filter,
4713 mrule_defs[i].mrd_associated );
4717 "schema_init: Error registering matching rule %s\n",
4718 mrule_defs[i].mrd_desc );
4722 schema_init_done = 1;
4723 return LDAP_SUCCESS;