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 #define HASH_BYTES LUTIL_HASH_BYTES
25 #define HASH_CONTEXT lutil_HASH_CTX
26 #define HASH_Init(c) lutil_HASHInit(c)
27 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
28 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
30 /* recycled validatation routines */
31 #define berValidate blobValidate
33 /* unimplemented pretters */
34 #define integerPretty NULL
36 /* recycled matching routines */
37 #define bitStringMatch octetStringMatch
38 #define numericStringMatch caseIgnoreIA5Match
39 #define objectIdentifierMatch caseIgnoreIA5Match
40 #define telephoneNumberMatch caseIgnoreIA5Match
41 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
42 #define generalizedTimeMatch caseIgnoreIA5Match
43 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
44 #define uniqueMemberMatch dnMatch
46 /* approx matching rules */
47 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
48 #define directoryStringApproxMatch approxMatch
49 #define directoryStringApproxIndexer approxIndexer
50 #define directoryStringApproxFilter approxFilter
51 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
52 #define IA5StringApproxMatch approxMatch
53 #define IA5StringApproxIndexer approxIndexer
54 #define IA5StringApproxFilter approxFilter
56 /* orderring matching rules */
57 #define caseIgnoreOrderingMatch caseIgnoreMatch
58 #define caseExactOrderingMatch caseExactMatch
60 /* unimplemented matching routines */
61 #define caseIgnoreListMatch NULL
62 #define caseIgnoreListSubstringsMatch NULL
63 #define protocolInformationMatch NULL
64 #define integerFirstComponentMatch NULL
66 #define OpenLDAPaciMatch NULL
67 #define authPasswordMatch NULL
69 /* recycled indexing/filtering routines */
70 #define dnIndexer caseExactIgnoreIndexer
71 #define dnFilter caseExactIgnoreFilter
72 #define bitStringFilter octetStringFilter
73 #define bitStringIndexer octetStringIndexer
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 static int octetStringIndexer(
125 struct berval *prefix,
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].bv_val != 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 = syntax->ssyn_oidlen;
148 mlen = mr->smr_oidlen;
150 for( i=0; values[i].bv_val != 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 ber_dupbv( &keys[i], &digest );
167 keys[i].bv_val = NULL;
174 /* Index generation function */
175 static int octetStringFilter(
180 struct berval *prefix,
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 = syntax->ssyn_oidlen;
194 mlen = mr->smr_oidlen;
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 ber_dupbv( keys, &digest );
212 keys[1].bv_val = NULL;
227 if( in->bv_len == 0 ) return LDAP_SUCCESS;
229 dn = ber_bvdup( in );
230 if( !dn ) return LDAP_OTHER;
232 if( dn->bv_val[dn->bv_len-1] == 'B'
233 && dn->bv_val[dn->bv_len-2] == '\'' )
235 /* assume presence of optional UID */
238 for(i=dn->bv_len-3; i>1; i--) {
239 if( dn->bv_val[i] != '0' && dn->bv_val[i] != '1' ) {
243 if( dn->bv_val[i] != '\'' ||
244 dn->bv_val[i-1] != '#' ) {
246 return LDAP_INVALID_SYNTAX;
249 /* trim the UID to allow use of dnValidate */
250 dn->bv_val[i-1] = '\0';
254 rc = dnValidate( NULL, dn );
264 struct berval *normalized )
269 ber_dupbv( &out, val );
270 if( out.bv_len != 0 ) {
273 ber_len_t uidlen = 0;
275 if( out.bv_val[out.bv_len-1] == '\'' ) {
276 /* assume presence of optional UID */
277 uid = strrchr( out.bv_val, '#' );
281 return LDAP_INVALID_SYNTAX;
284 uidlen = out.bv_len - (uid - out.bv_val);
285 /* temporarily trim the UID */
287 out.bv_len -= uidlen;
290 #ifdef USE_DN_NORMALIZE
291 rc = dnNormalize2( NULL, &out, normalized );
293 rc = dnPretty2( NULL, &out, normalized );
296 if( rc != LDAP_SUCCESS ) {
298 return LDAP_INVALID_SYNTAX;
301 dnlen = normalized->bv_len;
305 b2.bv_val = ch_malloc(dnlen + uidlen + 1);
306 AC_MEMCPY( b2.bv_val, normalized->bv_val, dnlen );
308 /* restore the separator */
311 AC_MEMCPY( normalized->bv_val+dnlen, uid, uidlen );
312 b2.bv_len = dnlen + uidlen;
313 normalized->bv_val[dnlen+uidlen] = '\0';
314 free(normalized->bv_val);
328 /* any value allowed */
337 /* any value allowed */
348 /* very unforgiving validation, requires no normalization
349 * before simplistic matching
351 if( in->bv_len < 3 ) {
352 return LDAP_INVALID_SYNTAX;
356 * rfc 2252 section 6.3 Bit String
357 * bitstring = "'" *binary-digit "'"
358 * binary-digit = "0" / "1"
359 * example: '0101111101'B
362 if( in->bv_val[0] != '\'' ||
363 in->bv_val[in->bv_len-2] != '\'' ||
364 in->bv_val[in->bv_len-1] != 'B' )
366 return LDAP_INVALID_SYNTAX;
369 for( i=in->bv_len-3; i>0; i-- ) {
370 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
371 return LDAP_INVALID_SYNTAX;
382 struct berval *normalized )
385 * A normalized bitString is has no extaneous (leading) zero bits.
386 * That is, '00010'B is normalized to '10'B
387 * However, as a special case, '0'B requires no normalization.
391 /* start at the first bit */
394 /* Find the first non-zero bit */
395 while ( *p == '0' ) p++;
398 /* no non-zero bits */
399 ber_str2bv( "\'0\'B", sizeof("\'0\'B") - 1, 1, normalized );
403 normalized->bv_val = ch_malloc( val->bv_len + 1 );
405 normalized->bv_val[0] = '\'';
406 normalized->bv_len = 1;
408 for( ; *p != '\0'; p++ ) {
409 normalized->bv_val[normalized->bv_len++] = *p;
412 normalized->bv_val[normalized->bv_len] = '\0';
419 * Handling boolean syntax and matching is quite rigid.
420 * A more flexible approach would be to allow a variety
421 * of strings to be normalized and prettied into TRUE
429 /* very unforgiving validation, requires no normalization
430 * before simplistic matching
433 if( in->bv_len == 4 ) {
434 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
437 } else if( in->bv_len == 5 ) {
438 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
443 return LDAP_INVALID_SYNTAX;
452 struct berval *value,
453 void *assertedValue )
455 /* simplistic matching allowed by rigid validation */
456 struct berval *asserted = (struct berval *) assertedValue;
457 *matchp = value->bv_len != asserted->bv_len;
468 unsigned char *u = in->bv_val;
470 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
472 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
473 /* get the length indicated by the first byte */
474 len = LDAP_UTF8_CHARLEN( u );
476 /* should not be zero */
477 if( len == 0 ) return LDAP_INVALID_SYNTAX;
479 /* make sure len corresponds with the offset
480 to the next character */
481 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
484 if( count != 0 ) return LDAP_INVALID_SYNTAX;
493 struct berval *normalized )
500 /* Ignore initial whitespace */
501 /* All space is ASCII. All ASCII is 1 byte */
502 while ( ASCII_SPACE( *p ) ) {
507 return LDAP_INVALID_SYNTAX;
510 ber_str2bv( p, val->bv_len - (p - val->bv_val), 1, normalized );
512 assert( normalized->bv_val );
514 p = q = normalized->bv_val;
519 if ( ASCII_SPACE( *p ) ) {
524 /* Ignore the extra whitespace */
525 while ( ASCII_SPACE( *p ) ) {
529 len = LDAP_UTF8_COPY(q,p);
535 assert( normalized->bv_val < p );
536 assert( q+len <= p );
538 /* cannot start with a space */
539 assert( !ASCII_SPACE(normalized->bv_val[0]) );
542 * If the string ended in space, backup the pointer one
543 * position. One is enough because the above loop collapsed
544 * all whitespace to a single space.
552 /* cannot end with a space */
553 assert( !ASCII_SPACE( *q ) );
560 normalized->bv_len = q - normalized->bv_val;
565 /* Returns Unicode canonically normalized copy of a substring assertion
566 * Skipping attribute description */
567 static SubstringsAssertion *
568 UTF8SubstringsassertionNormalize(
569 SubstringsAssertion *sa,
572 SubstringsAssertion *nsa;
575 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
580 if( sa->sa_initial.bv_val != NULL ) {
581 ber_str2bv( UTF8normalize( &sa->sa_initial, casefold ), 0,
582 0, &nsa->sa_initial );
583 if( nsa->sa_initial.bv_val == NULL ) {
588 if( sa->sa_any != NULL ) {
589 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
592 nsa->sa_any = (struct berval *)ch_malloc( (i + 1) * sizeof(struct berval) );
593 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
594 ber_str2bv( UTF8normalize( &sa->sa_any[i], casefold ),
595 0, 0, &nsa->sa_any[i] );
596 if( nsa->sa_any[i].bv_val == NULL ) {
600 nsa->sa_any[i].bv_val = NULL;
603 if( sa->sa_final.bv_val != NULL ) {
604 ber_str2bv( UTF8normalize( &sa->sa_final, casefold ), 0,
606 if( nsa->sa_final.bv_val == NULL ) {
614 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
615 if ( nsa->sa_any )bvarray_free( nsa->sa_any );
616 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
621 /* Strip characters with the 8th bit set */
634 while( *++q & 0x80 ) {
637 p = AC_MEMCPY(p, q, strlen(q) + 1);
645 #ifndef SLAPD_APPROX_OLDSINGLESTRING
647 #if defined(SLAPD_APPROX_INITIALS)
648 #define SLAPD_APPROX_DELIMITER "._ "
649 #define SLAPD_APPROX_WORDLEN 2
651 #define SLAPD_APPROX_DELIMITER " "
652 #define SLAPD_APPROX_WORDLEN 1
661 struct berval *value,
662 void *assertedValue )
664 char *val, *nval, *assertv, **values, **words, *c;
665 int i, count, len, nextchunk=0, nextavail=0;
668 /* Yes, this is necessary */
669 nval = UTF8normalize( value, LDAP_UTF8_NOCASEFOLD );
674 strip8bitChars( nval );
676 /* Yes, this is necessary */
677 assertv = UTF8normalize( ((struct berval *)assertedValue),
678 LDAP_UTF8_NOCASEFOLD );
679 if( assertv == NULL ) {
684 strip8bitChars( assertv );
685 avlen = strlen( assertv );
687 /* Isolate how many words there are */
688 for( c=nval,count=1; *c; c++ ) {
689 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
690 if ( c == NULL ) break;
695 /* Get a phonetic copy of each word */
696 words = (char **)ch_malloc( count * sizeof(char *) );
697 values = (char **)ch_malloc( count * sizeof(char *) );
698 for( c=nval,i=0; i<count; i++,c+=strlen(c)+1 ) {
700 values[i] = phonetic(c);
703 /* Work through the asserted value's words, to see if at least some
704 of the words are there, in the same order. */
706 while ( (size_t) nextchunk < avlen ) {
707 len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER);
712 #if defined(SLAPD_APPROX_INITIALS)
713 else if( len == 1 ) {
714 /* Single letter words need to at least match one word's initial */
715 for( i=nextavail; i<count; i++ )
716 if( !strncasecmp( assertv+nextchunk, words[i], 1 )) {
723 /* Isolate the next word in the asserted value and phonetic it */
724 assertv[nextchunk+len] = '\0';
725 val = phonetic( assertv + nextchunk );
727 /* See if this phonetic chunk is in the remaining words of *value */
728 for( i=nextavail; i<count; i++ ){
729 if( !strcmp( val, values[i] ) ){
737 /* This chunk in the asserted value was NOT within the *value. */
743 /* Go on to the next word in the asserted value */
747 /* If some of the words were seen, call it a match */
748 if( nextavail > 0 ) {
757 for( i=0; i<count; i++ ) {
758 ch_free( values[i] );
773 struct berval *prefix,
778 int i,j, len, wordcount, keycount=0;
779 struct berval *newkeys;
782 for( j=0; values[j].bv_val != NULL; j++ ) {
783 /* Yes, this is necessary */
784 val = UTF8normalize( &values[j], LDAP_UTF8_NOCASEFOLD );
785 strip8bitChars( val );
787 /* Isolate how many words there are. There will be a key for each */
788 for( wordcount=0,c=val; *c; c++) {
789 len = strcspn(c, SLAPD_APPROX_DELIMITER);
790 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
792 if (*c == '\0') break;
796 /* Allocate/increase storage to account for new keys */
797 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
798 * sizeof(struct berval) );
799 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
800 if( keys ) ch_free( keys );
803 /* Get a phonetic copy of each word */
804 for( c=val,i=0; i<wordcount; c+=len+1 ) {
806 if( len < SLAPD_APPROX_WORDLEN ) continue;
807 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
814 keys[keycount].bv_val = NULL;
826 struct berval *prefix,
834 /* Yes, this is necessary */
835 val = UTF8normalize( ((struct berval *)assertValue),
836 LDAP_UTF8_NOCASEFOLD );
838 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
839 keys[0].bv_val = NULL;
843 strip8bitChars( val );
845 /* Isolate how many words there are. There will be a key for each */
846 for( count=0,c=val; *c; c++) {
847 len = strcspn(c, SLAPD_APPROX_DELIMITER);
848 if( len >= SLAPD_APPROX_WORDLEN ) count++;
850 if (*c == '\0') break;
854 /* Allocate storage for new keys */
855 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
857 /* Get a phonetic copy of each word */
858 for( c=val,i=0; i<count; c+=len+1 ) {
860 if( len < SLAPD_APPROX_WORDLEN ) continue;
861 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
867 keys[count].bv_val = NULL;
875 /* No other form of Approximate Matching is defined */
883 struct berval *value,
884 void *assertedValue )
886 char *vapprox, *avapprox;
889 /* Yes, this is necessary */
890 s = UTF8normalize( value, UTF8_NOCASEFOLD );
896 /* Yes, this is necessary */
897 t = UTF8normalize( ((struct berval *)assertedValue),
905 vapprox = phonetic( strip8bitChars( s ) );
906 avapprox = phonetic( strip8bitChars( t ) );
911 *matchp = strcmp( vapprox, avapprox );
925 struct berval *prefix,
933 for( i=0; values[i].bv_val != NULL; i++ ) {
934 /* empty - just count them */
937 /* we should have at least one value at this point */
940 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
942 /* Copy each value and run it through phonetic() */
943 for( i=0; values[i].bv_val != NULL; i++ ) {
944 /* Yes, this is necessary */
945 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
947 /* strip 8-bit chars and run through phonetic() */
948 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
951 keys[i].bv_val = NULL;
964 struct berval *prefix,
971 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
973 /* Yes, this is necessary */
974 s = UTF8normalize( ((struct berval *)assertValue),
979 /* strip 8-bit chars and run through phonetic() */
980 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
997 struct berval *value,
998 void *assertedValue )
1000 *matchp = UTF8normcmp( value->bv_val,
1001 ((struct berval *) assertedValue)->bv_val,
1002 LDAP_UTF8_NOCASEFOLD );
1003 return LDAP_SUCCESS;
1007 caseExactIgnoreSubstringsMatch(
1012 struct berval *value,
1013 void *assertedValue )
1016 SubstringsAssertion *sub = NULL;
1023 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1024 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1026 nav = UTF8normalize( value, casefold );
1032 left.bv_len = strlen( nav );
1034 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1040 /* Add up asserted input length */
1041 if( sub->sa_initial.bv_val ) {
1042 inlen += sub->sa_initial.bv_len;
1045 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1046 inlen += sub->sa_any[i].bv_len;
1049 if( sub->sa_final.bv_val ) {
1050 inlen += sub->sa_final.bv_len;
1053 if( sub->sa_initial.bv_val ) {
1054 if( inlen > left.bv_len ) {
1059 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
1060 sub->sa_initial.bv_len );
1066 left.bv_val += sub->sa_initial.bv_len;
1067 left.bv_len -= sub->sa_initial.bv_len;
1068 inlen -= sub->sa_initial.bv_len;
1071 if( sub->sa_final.bv_val ) {
1072 if( inlen > left.bv_len ) {
1077 match = strncmp( sub->sa_final.bv_val,
1078 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1079 sub->sa_final.bv_len );
1085 left.bv_len -= sub->sa_final.bv_len;
1086 inlen -= sub->sa_final.bv_len;
1090 for(i=0; sub->sa_any[i].bv_val; i++) {
1095 if( inlen > left.bv_len ) {
1096 /* not enough length */
1101 if( sub->sa_any[i].bv_len == 0 ) {
1105 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
1112 idx = p - left.bv_val;
1113 assert( idx < left.bv_len );
1115 if( idx >= left.bv_len ) {
1116 /* this shouldn't happen */
1118 if ( sub->sa_final.bv_val )
1119 ch_free( sub->sa_final.bv_val );
1121 bvarray_free( sub->sa_any );
1122 if ( sub->sa_initial.bv_val )
1123 ch_free( sub->sa_initial.bv_val );
1131 if( sub->sa_any[i].bv_len > left.bv_len ) {
1132 /* not enough left */
1137 match = strncmp( left.bv_val,
1138 sub->sa_any[i].bv_val,
1139 sub->sa_any[i].bv_len );
1147 left.bv_val += sub->sa_any[i].bv_len;
1148 left.bv_len -= sub->sa_any[i].bv_len;
1149 inlen -= sub->sa_any[i].bv_len;
1156 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1157 if ( sub->sa_any ) bvarray_free( sub->sa_any );
1158 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1162 return LDAP_SUCCESS;
1165 /* Index generation function */
1166 static int caseExactIgnoreIndexer(
1171 struct berval *prefix,
1179 HASH_CONTEXT HASHcontext;
1180 unsigned char HASHdigest[HASH_BYTES];
1181 struct berval digest;
1182 digest.bv_val = HASHdigest;
1183 digest.bv_len = sizeof(HASHdigest);
1185 for( i=0; values[i].bv_val != NULL; i++ ) {
1186 /* empty - just count them */
1189 /* we should have at least one value at this point */
1192 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1194 slen = syntax->ssyn_oidlen;
1195 mlen = mr->smr_oidlen;
1197 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1198 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1200 for( i=0; values[i].bv_val != NULL; i++ ) {
1201 struct berval value;
1202 ber_str2bv( UTF8normalize( &values[i], casefold ), 0, 0,
1205 HASH_Init( &HASHcontext );
1206 if( prefix != NULL && prefix->bv_len > 0 ) {
1207 HASH_Update( &HASHcontext,
1208 prefix->bv_val, prefix->bv_len );
1210 HASH_Update( &HASHcontext,
1211 syntax->ssyn_oid, slen );
1212 HASH_Update( &HASHcontext,
1213 mr->smr_oid, mlen );
1214 HASH_Update( &HASHcontext,
1215 value.bv_val, value.bv_len );
1216 HASH_Final( HASHdigest, &HASHcontext );
1218 free( value.bv_val );
1220 ber_dupbv( &keys[i], &digest );
1223 keys[i].bv_val = NULL;
1225 return LDAP_SUCCESS;
1228 /* Index generation function */
1229 static int caseExactIgnoreFilter(
1234 struct berval *prefix,
1241 HASH_CONTEXT HASHcontext;
1242 unsigned char HASHdigest[HASH_BYTES];
1243 struct berval value;
1244 struct berval digest;
1245 digest.bv_val = HASHdigest;
1246 digest.bv_len = sizeof(HASHdigest);
1248 slen = syntax->ssyn_oidlen;
1249 mlen = mr->smr_oidlen;
1251 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1252 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1254 ber_str2bv( UTF8normalize( ((struct berval *) assertValue), casefold ),
1256 /* This usually happens if filter contains bad UTF8 */
1257 if( value.bv_val == NULL ) {
1258 keys = ch_malloc( sizeof( struct berval ) );
1259 keys[0].bv_val = NULL;
1260 return LDAP_SUCCESS;
1263 keys = ch_malloc( sizeof( struct berval ) * 2 );
1265 HASH_Init( &HASHcontext );
1266 if( prefix != NULL && prefix->bv_len > 0 ) {
1267 HASH_Update( &HASHcontext,
1268 prefix->bv_val, prefix->bv_len );
1270 HASH_Update( &HASHcontext,
1271 syntax->ssyn_oid, slen );
1272 HASH_Update( &HASHcontext,
1273 mr->smr_oid, mlen );
1274 HASH_Update( &HASHcontext,
1275 value.bv_val, value.bv_len );
1276 HASH_Final( HASHdigest, &HASHcontext );
1278 ber_dupbv( keys, &digest );
1279 keys[1].bv_val = NULL;
1281 free( value.bv_val );
1284 return LDAP_SUCCESS;
1287 /* Substrings Index generation function */
1288 static int caseExactIgnoreSubstringsIndexer(
1293 struct berval *prefix,
1303 HASH_CONTEXT HASHcontext;
1304 unsigned char HASHdigest[HASH_BYTES];
1305 struct berval digest;
1306 digest.bv_val = HASHdigest;
1307 digest.bv_len = sizeof(HASHdigest);
1311 for( i=0; values[i].bv_val != NULL; i++ ) {
1312 /* empty - just count them */
1315 /* we should have at least one value at this point */
1318 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1319 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1321 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1322 for( i=0; values[i].bv_val != NULL; i++ ) {
1323 ber_str2bv( UTF8normalize( &values[i], casefold ),
1324 0, 0, &nvalues[i] );
1326 nvalues[i].bv_val = NULL;
1329 for( i=0; values[i].bv_val != NULL; i++ ) {
1330 /* count number of indices to generate */
1331 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1335 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1336 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1337 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1338 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1340 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1344 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1345 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1346 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1350 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1351 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1352 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1353 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1355 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1361 /* no keys to generate */
1363 bvarray_free( nvalues );
1364 return LDAP_SUCCESS;
1367 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1369 slen = syntax->ssyn_oidlen;
1370 mlen = mr->smr_oidlen;
1373 for( i=0; values[i].bv_val != NULL; i++ ) {
1376 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1378 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1379 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1381 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1382 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1384 for( j=0; j<max; j++ ) {
1385 HASH_Init( &HASHcontext );
1386 if( prefix != NULL && prefix->bv_len > 0 ) {
1387 HASH_Update( &HASHcontext,
1388 prefix->bv_val, prefix->bv_len );
1391 HASH_Update( &HASHcontext,
1392 &pre, sizeof( pre ) );
1393 HASH_Update( &HASHcontext,
1394 syntax->ssyn_oid, slen );
1395 HASH_Update( &HASHcontext,
1396 mr->smr_oid, mlen );
1397 HASH_Update( &HASHcontext,
1398 &values[i].bv_val[j],
1399 SLAP_INDEX_SUBSTR_MAXLEN );
1400 HASH_Final( HASHdigest, &HASHcontext );
1402 ber_dupbv( &keys[nkeys++], &digest );
1406 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1407 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1409 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1412 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1413 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1414 HASH_Init( &HASHcontext );
1415 if( prefix != NULL && prefix->bv_len > 0 ) {
1416 HASH_Update( &HASHcontext,
1417 prefix->bv_val, prefix->bv_len );
1419 HASH_Update( &HASHcontext,
1420 &pre, sizeof( pre ) );
1421 HASH_Update( &HASHcontext,
1422 syntax->ssyn_oid, slen );
1423 HASH_Update( &HASHcontext,
1424 mr->smr_oid, mlen );
1425 HASH_Update( &HASHcontext,
1426 values[i].bv_val, j );
1427 HASH_Final( HASHdigest, &HASHcontext );
1429 ber_dupbv( &keys[nkeys++], &digest );
1432 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1433 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1434 HASH_Init( &HASHcontext );
1435 if( prefix != NULL && prefix->bv_len > 0 ) {
1436 HASH_Update( &HASHcontext,
1437 prefix->bv_val, prefix->bv_len );
1439 HASH_Update( &HASHcontext,
1440 &pre, sizeof( pre ) );
1441 HASH_Update( &HASHcontext,
1442 syntax->ssyn_oid, slen );
1443 HASH_Update( &HASHcontext,
1444 mr->smr_oid, mlen );
1445 HASH_Update( &HASHcontext,
1446 &values[i].bv_val[values[i].bv_len-j], j );
1447 HASH_Final( HASHdigest, &HASHcontext );
1449 ber_dupbv( &keys[nkeys++], &digest );
1457 keys[nkeys].bv_val = NULL;
1464 bvarray_free( nvalues );
1466 return LDAP_SUCCESS;
1469 static int caseExactIgnoreSubstringsFilter(
1474 struct berval *prefix,
1478 SubstringsAssertion *sa;
1481 ber_len_t nkeys = 0;
1482 size_t slen, mlen, klen;
1484 HASH_CONTEXT HASHcontext;
1485 unsigned char HASHdigest[HASH_BYTES];
1486 struct berval *value;
1487 struct berval digest;
1489 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1490 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1492 sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
1495 return LDAP_SUCCESS;
1498 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1499 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1504 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1506 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1507 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1508 /* don't bother accounting for stepping */
1509 nkeys += sa->sa_any[i].bv_len -
1510 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1515 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1516 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1522 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1523 if ( sa->sa_any ) bvarray_free( sa->sa_any );
1524 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1527 return LDAP_SUCCESS;
1530 digest.bv_val = HASHdigest;
1531 digest.bv_len = sizeof(HASHdigest);
1533 slen = syntax->ssyn_oidlen;
1534 mlen = mr->smr_oidlen;
1536 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1539 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1540 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1542 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1543 value = &sa->sa_initial;
1545 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1546 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1548 HASH_Init( &HASHcontext );
1549 if( prefix != NULL && prefix->bv_len > 0 ) {
1550 HASH_Update( &HASHcontext,
1551 prefix->bv_val, prefix->bv_len );
1553 HASH_Update( &HASHcontext,
1554 &pre, sizeof( pre ) );
1555 HASH_Update( &HASHcontext,
1556 syntax->ssyn_oid, slen );
1557 HASH_Update( &HASHcontext,
1558 mr->smr_oid, mlen );
1559 HASH_Update( &HASHcontext,
1560 value->bv_val, klen );
1561 HASH_Final( HASHdigest, &HASHcontext );
1563 ber_dupbv( &keys[nkeys++], &digest );
1566 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1568 pre = SLAP_INDEX_SUBSTR_PREFIX;
1569 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1571 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1572 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1576 value = &sa->sa_any[i];
1579 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1580 j += SLAP_INDEX_SUBSTR_STEP )
1582 HASH_Init( &HASHcontext );
1583 if( prefix != NULL && prefix->bv_len > 0 ) {
1584 HASH_Update( &HASHcontext,
1585 prefix->bv_val, prefix->bv_len );
1587 HASH_Update( &HASHcontext,
1588 &pre, sizeof( pre ) );
1589 HASH_Update( &HASHcontext,
1590 syntax->ssyn_oid, slen );
1591 HASH_Update( &HASHcontext,
1592 mr->smr_oid, mlen );
1593 HASH_Update( &HASHcontext,
1594 &value->bv_val[j], klen );
1595 HASH_Final( HASHdigest, &HASHcontext );
1597 ber_dupbv( &keys[nkeys++], &digest );
1603 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1604 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1606 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1607 value = &sa->sa_final;
1609 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1610 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1612 HASH_Init( &HASHcontext );
1613 if( prefix != NULL && prefix->bv_len > 0 ) {
1614 HASH_Update( &HASHcontext,
1615 prefix->bv_val, prefix->bv_len );
1617 HASH_Update( &HASHcontext,
1618 &pre, sizeof( pre ) );
1619 HASH_Update( &HASHcontext,
1620 syntax->ssyn_oid, slen );
1621 HASH_Update( &HASHcontext,
1622 mr->smr_oid, mlen );
1623 HASH_Update( &HASHcontext,
1624 &value->bv_val[value->bv_len-klen], klen );
1625 HASH_Final( HASHdigest, &HASHcontext );
1627 ber_dupbv( &keys[nkeys++], &digest );
1631 keys[nkeys].bv_val = NULL;
1637 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1638 if ( sa->sa_any ) bvarray_free( sa->sa_any );
1639 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1642 return LDAP_SUCCESS;
1651 struct berval *value,
1652 void *assertedValue )
1654 *matchp = UTF8normcmp( value->bv_val,
1655 ((struct berval *) assertedValue)->bv_val,
1656 LDAP_UTF8_CASEFOLD );
1657 return LDAP_SUCCESS;
1663 struct berval *val )
1667 if( val->bv_len == 0 ) {
1668 /* disallow empty strings */
1669 return LDAP_INVALID_SYNTAX;
1672 if( OID_LEADCHAR(val->bv_val[0]) ) {
1674 for(i=1; i < val->bv_len; i++) {
1675 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1676 if( dot++ ) return 1;
1677 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1680 return LDAP_INVALID_SYNTAX;
1684 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1686 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1687 for(i=1; i < val->bv_len; i++) {
1688 if( !DESC_CHAR(val->bv_val[i] ) ) {
1689 return LDAP_INVALID_SYNTAX;
1693 return LDAP_SUCCESS;
1696 return LDAP_INVALID_SYNTAX;
1705 struct berval *value,
1706 void *assertedValue )
1709 int vsign=0, avsign=0;
1710 struct berval *asserted;
1711 ber_len_t vlen, avlen;
1714 /* Start off pessimistic */
1717 /* Skip past leading spaces/zeros, and get the sign of the *value number */
1719 vlen = value->bv_len;
1721 if( ASCII_SPACE(*v) || ( *v == '0' )) {
1722 /* empty -- skip spaces */
1724 else if ( *v == '+' ) {
1727 else if ( *v == '-' ) {
1730 else if ( ASCII_DIGIT(*v) ) {
1731 if ( vsign == 0 ) vsign = 1;
1739 /* Skip past leading spaces/zeros, and get the sign of the *assertedValue
1741 asserted = (struct berval *) assertedValue;
1742 av = asserted->bv_val;
1743 avlen = asserted->bv_len;
1745 if( ASCII_SPACE(*av) || ( *av == '0' )) {
1746 /* empty -- skip spaces */
1748 else if ( *av == '+' ) {
1751 else if ( *av == '-' ) {
1754 else if ( ASCII_DIGIT(*av) ) {
1755 if ( avsign == 0 ) avsign = 1;
1763 /* The two ?sign vars are now one of :
1764 -2 negative non-zero number
1766 0 0 collapse these three to 0
1768 +2 positive non-zero number
1770 if ( abs( vsign ) == 1 ) vsign = 0;
1771 if ( abs( avsign ) == 1 ) avsign = 0;
1773 if( vsign != avsign ) return LDAP_SUCCESS;
1775 /* Check the significant digits */
1776 while( vlen && avlen ) {
1777 if( *v != *av ) break;
1784 /* If all digits compared equal, the numbers are equal */
1785 if(( vlen == 0 ) && ( avlen == 0 )) {
1788 return LDAP_SUCCESS;
1794 struct berval *val )
1798 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1800 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
1801 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1802 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1803 return LDAP_INVALID_SYNTAX;
1806 for( i=1; i < val->bv_len; i++ ) {
1807 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1810 return LDAP_SUCCESS;
1817 struct berval *normalized )
1827 /* Ignore leading spaces */
1828 while ( len && ( *p == ' ' )) {
1835 negative = ( *p == '-' );
1836 if(( *p == '-' ) || ( *p == '+' )) {
1842 /* Ignore leading zeros */
1843 while ( len && ( *p == '0' )) {
1848 /* If there are no non-zero digits left, the number is zero, otherwise
1849 allocate space for the number and copy it into the buffer */
1851 normalized->bv_val = ch_strdup("0");
1852 normalized->bv_len = 1;
1855 normalized->bv_len = len+negative;
1856 normalized->bv_val = ch_malloc( normalized->bv_len );
1858 normalized->bv_val[0] = '-';
1860 AC_MEMCPY( normalized->bv_val + negative, p, len );
1863 return LDAP_SUCCESS;
1866 /* Index generation function */
1867 static int integerIndexer(
1872 struct berval *prefix,
1879 /* we should have at least one value at this point */
1880 assert( values != NULL && values[0].bv_val != NULL );
1882 for( i=0; values[i].bv_val != NULL; i++ ) {
1883 /* empty -- just count them */
1886 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1888 for( i=0; values[i].bv_val != NULL; i++ ) {
1889 integerNormalize( syntax, &values[i], &keys[i] );
1892 keys[i].bv_val = NULL;
1894 return LDAP_SUCCESS;
1897 /* Index generation function */
1898 static int integerFilter(
1903 struct berval *prefix,
1909 keys = ch_malloc( sizeof( struct berval ) * 2 );
1910 integerNormalize( syntax, assertValue, &keys[0] );
1911 keys[1].bv_val = NULL;
1914 return LDAP_SUCCESS;
1919 countryStringValidate(
1921 struct berval *val )
1923 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
1925 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
1926 return LDAP_INVALID_SYNTAX;
1928 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
1929 return LDAP_INVALID_SYNTAX;
1932 return LDAP_SUCCESS;
1936 printableStringValidate(
1938 struct berval *val )
1942 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1944 for(i=0; i < val->bv_len; i++) {
1945 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
1946 return LDAP_INVALID_SYNTAX;
1950 return LDAP_SUCCESS;
1954 printablesStringValidate(
1956 struct berval *val )
1960 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1962 for(i=0; i < val->bv_len; i++) {
1963 if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
1964 return LDAP_INVALID_SYNTAX;
1968 return LDAP_SUCCESS;
1974 struct berval *val )
1978 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1980 for(i=0; i < val->bv_len; i++) {
1981 if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1984 return LDAP_SUCCESS;
1991 struct berval *normalized )
1997 /* Ignore initial whitespace */
1998 while ( ASCII_SPACE( *p ) ) {
2003 return LDAP_INVALID_SYNTAX;
2006 normalized->bv_val = ch_strdup( p );
2007 p = q = normalized->bv_val;
2010 if ( ASCII_SPACE( *p ) ) {
2013 /* Ignore the extra whitespace */
2014 while ( ASCII_SPACE( *p ) ) {
2022 assert( normalized->bv_val < p );
2025 /* cannot start with a space */
2026 assert( !ASCII_SPACE(*normalized->bv_val) );
2029 * If the string ended in space, backup the pointer one
2030 * position. One is enough because the above loop collapsed
2031 * all whitespace to a single space.
2034 if ( ASCII_SPACE( q[-1] ) ) {
2038 /* cannot end with a space */
2039 assert( !ASCII_SPACE( q[-1] ) );
2041 /* null terminate */
2044 normalized->bv_len = q - normalized->bv_val;
2046 return LDAP_SUCCESS;
2055 struct berval *value,
2056 void *assertedValue )
2058 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2061 match = strncmp( value->bv_val,
2062 ((struct berval *) assertedValue)->bv_val,
2067 return LDAP_SUCCESS;
2071 caseExactIA5SubstringsMatch(
2076 struct berval *value,
2077 void *assertedValue )
2080 SubstringsAssertion *sub = assertedValue;
2081 struct berval left = *value;
2085 /* Add up asserted input length */
2086 if( sub->sa_initial.bv_val ) {
2087 inlen += sub->sa_initial.bv_len;
2090 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2091 inlen += sub->sa_any[i].bv_len;
2094 if( sub->sa_final.bv_val ) {
2095 inlen += sub->sa_final.bv_len;
2098 if( sub->sa_initial.bv_val ) {
2099 if( inlen > left.bv_len ) {
2104 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
2105 sub->sa_initial.bv_len );
2111 left.bv_val += sub->sa_initial.bv_len;
2112 left.bv_len -= sub->sa_initial.bv_len;
2113 inlen -= sub->sa_initial.bv_len;
2116 if( sub->sa_final.bv_val ) {
2117 if( inlen > left.bv_len ) {
2122 match = strncmp( sub->sa_final.bv_val,
2123 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2124 sub->sa_final.bv_len );
2130 left.bv_len -= sub->sa_final.bv_len;
2131 inlen -= sub->sa_final.bv_len;
2135 for(i=0; sub->sa_any[i].bv_val; i++) {
2140 if( inlen > left.bv_len ) {
2141 /* not enough length */
2146 if( sub->sa_any[i].bv_len == 0 ) {
2150 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
2157 idx = p - left.bv_val;
2158 assert( idx < left.bv_len );
2160 if( idx >= left.bv_len ) {
2161 /* this shouldn't happen */
2168 if( sub->sa_any[i].bv_len > left.bv_len ) {
2169 /* not enough left */
2174 match = strncmp( left.bv_val,
2175 sub->sa_any[i].bv_val,
2176 sub->sa_any[i].bv_len );
2184 left.bv_val += sub->sa_any[i].bv_len;
2185 left.bv_len -= sub->sa_any[i].bv_len;
2186 inlen -= sub->sa_any[i].bv_len;
2192 return LDAP_SUCCESS;
2195 /* Index generation function */
2196 static int caseExactIA5Indexer(
2201 struct berval *prefix,
2208 HASH_CONTEXT HASHcontext;
2209 unsigned char HASHdigest[HASH_BYTES];
2210 struct berval digest;
2211 digest.bv_val = HASHdigest;
2212 digest.bv_len = sizeof(HASHdigest);
2214 for( i=0; values[i].bv_val != NULL; i++ ) {
2215 /* empty - just count them */
2218 /* we should have at least one value at this point */
2221 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2223 slen = syntax->ssyn_oidlen;
2224 mlen = mr->smr_oidlen;
2226 for( i=0; values[i].bv_val != NULL; i++ ) {
2227 struct berval *value = &values[i];
2229 HASH_Init( &HASHcontext );
2230 if( prefix != NULL && prefix->bv_len > 0 ) {
2231 HASH_Update( &HASHcontext,
2232 prefix->bv_val, prefix->bv_len );
2234 HASH_Update( &HASHcontext,
2235 syntax->ssyn_oid, slen );
2236 HASH_Update( &HASHcontext,
2237 mr->smr_oid, mlen );
2238 HASH_Update( &HASHcontext,
2239 value->bv_val, value->bv_len );
2240 HASH_Final( HASHdigest, &HASHcontext );
2242 ber_dupbv( &keys[i], &digest );
2245 keys[i].bv_val = NULL;
2247 return LDAP_SUCCESS;
2250 /* Index generation function */
2251 static int caseExactIA5Filter(
2256 struct berval *prefix,
2262 HASH_CONTEXT HASHcontext;
2263 unsigned char HASHdigest[HASH_BYTES];
2264 struct berval *value;
2265 struct berval digest;
2266 digest.bv_val = HASHdigest;
2267 digest.bv_len = sizeof(HASHdigest);
2269 slen = syntax->ssyn_oidlen;
2270 mlen = mr->smr_oidlen;
2272 value = (struct berval *) assertValue;
2274 keys = ch_malloc( sizeof( struct berval ) * 2 );
2276 HASH_Init( &HASHcontext );
2277 if( prefix != NULL && prefix->bv_len > 0 ) {
2278 HASH_Update( &HASHcontext,
2279 prefix->bv_val, prefix->bv_len );
2281 HASH_Update( &HASHcontext,
2282 syntax->ssyn_oid, slen );
2283 HASH_Update( &HASHcontext,
2284 mr->smr_oid, mlen );
2285 HASH_Update( &HASHcontext,
2286 value->bv_val, value->bv_len );
2287 HASH_Final( HASHdigest, &HASHcontext );
2289 ber_dupbv( &keys[0], &digest );
2290 keys[1].bv_val = NULL;
2293 return LDAP_SUCCESS;
2296 /* Substrings Index generation function */
2297 static int caseExactIA5SubstringsIndexer(
2302 struct berval *prefix,
2309 HASH_CONTEXT HASHcontext;
2310 unsigned char HASHdigest[HASH_BYTES];
2311 struct berval digest;
2312 digest.bv_val = HASHdigest;
2313 digest.bv_len = sizeof(HASHdigest);
2315 /* we should have at least one value at this point */
2316 assert( values != NULL && values[0].bv_val != NULL );
2319 for( i=0; values[i].bv_val != NULL; i++ ) {
2320 /* count number of indices to generate */
2321 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2325 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2326 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2327 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2328 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2330 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2334 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2335 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2336 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2340 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2341 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2342 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2343 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2345 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2351 /* no keys to generate */
2353 return LDAP_SUCCESS;
2356 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2358 slen = syntax->ssyn_oidlen;
2359 mlen = mr->smr_oidlen;
2362 for( i=0; values[i].bv_val != NULL; i++ ) {
2364 struct berval *value;
2367 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2369 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2370 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2372 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2373 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2375 for( j=0; j<max; j++ ) {
2376 HASH_Init( &HASHcontext );
2377 if( prefix != NULL && prefix->bv_len > 0 ) {
2378 HASH_Update( &HASHcontext,
2379 prefix->bv_val, prefix->bv_len );
2382 HASH_Update( &HASHcontext,
2383 &pre, sizeof( pre ) );
2384 HASH_Update( &HASHcontext,
2385 syntax->ssyn_oid, slen );
2386 HASH_Update( &HASHcontext,
2387 mr->smr_oid, mlen );
2388 HASH_Update( &HASHcontext,
2390 SLAP_INDEX_SUBSTR_MAXLEN );
2391 HASH_Final( HASHdigest, &HASHcontext );
2393 ber_dupbv( &keys[nkeys++], &digest );
2397 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2398 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2400 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2403 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2404 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2405 HASH_Init( &HASHcontext );
2406 if( prefix != NULL && prefix->bv_len > 0 ) {
2407 HASH_Update( &HASHcontext,
2408 prefix->bv_val, prefix->bv_len );
2410 HASH_Update( &HASHcontext,
2411 &pre, sizeof( pre ) );
2412 HASH_Update( &HASHcontext,
2413 syntax->ssyn_oid, slen );
2414 HASH_Update( &HASHcontext,
2415 mr->smr_oid, mlen );
2416 HASH_Update( &HASHcontext,
2418 HASH_Final( HASHdigest, &HASHcontext );
2420 ber_dupbv( &keys[nkeys++], &digest );
2423 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2424 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2425 HASH_Init( &HASHcontext );
2426 if( prefix != NULL && prefix->bv_len > 0 ) {
2427 HASH_Update( &HASHcontext,
2428 prefix->bv_val, prefix->bv_len );
2430 HASH_Update( &HASHcontext,
2431 &pre, sizeof( pre ) );
2432 HASH_Update( &HASHcontext,
2433 syntax->ssyn_oid, slen );
2434 HASH_Update( &HASHcontext,
2435 mr->smr_oid, mlen );
2436 HASH_Update( &HASHcontext,
2437 &value->bv_val[value->bv_len-j], j );
2438 HASH_Final( HASHdigest, &HASHcontext );
2440 ber_dupbv( &keys[nkeys++], &digest );
2447 keys[nkeys].bv_val = NULL;
2454 return LDAP_SUCCESS;
2457 static int caseExactIA5SubstringsFilter(
2462 struct berval *prefix,
2466 SubstringsAssertion *sa = assertValue;
2468 ber_len_t nkeys = 0;
2469 size_t slen, mlen, klen;
2471 HASH_CONTEXT HASHcontext;
2472 unsigned char HASHdigest[HASH_BYTES];
2473 struct berval *value;
2474 struct berval digest;
2476 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2477 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2482 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2484 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2485 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2486 /* don't bother accounting for stepping */
2487 nkeys += sa->sa_any[i].bv_len -
2488 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2493 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2494 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2501 return LDAP_SUCCESS;
2504 digest.bv_val = HASHdigest;
2505 digest.bv_len = sizeof(HASHdigest);
2507 slen = syntax->ssyn_oidlen;
2508 mlen = mr->smr_oidlen;
2510 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2513 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2514 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2516 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2517 value = &sa->sa_initial;
2519 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2520 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2522 HASH_Init( &HASHcontext );
2523 if( prefix != NULL && prefix->bv_len > 0 ) {
2524 HASH_Update( &HASHcontext,
2525 prefix->bv_val, prefix->bv_len );
2527 HASH_Update( &HASHcontext,
2528 &pre, sizeof( pre ) );
2529 HASH_Update( &HASHcontext,
2530 syntax->ssyn_oid, slen );
2531 HASH_Update( &HASHcontext,
2532 mr->smr_oid, mlen );
2533 HASH_Update( &HASHcontext,
2534 value->bv_val, klen );
2535 HASH_Final( HASHdigest, &HASHcontext );
2537 ber_dupbv( &keys[nkeys++], &digest );
2540 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2542 pre = SLAP_INDEX_SUBSTR_PREFIX;
2543 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2545 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2546 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2550 value = &sa->sa_any[i];
2553 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2554 j += SLAP_INDEX_SUBSTR_STEP )
2556 HASH_Init( &HASHcontext );
2557 if( prefix != NULL && prefix->bv_len > 0 ) {
2558 HASH_Update( &HASHcontext,
2559 prefix->bv_val, prefix->bv_len );
2561 HASH_Update( &HASHcontext,
2562 &pre, sizeof( pre ) );
2563 HASH_Update( &HASHcontext,
2564 syntax->ssyn_oid, slen );
2565 HASH_Update( &HASHcontext,
2566 mr->smr_oid, mlen );
2567 HASH_Update( &HASHcontext,
2568 &value->bv_val[j], klen );
2569 HASH_Final( HASHdigest, &HASHcontext );
2571 ber_dupbv( &keys[nkeys++], &digest );
2576 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2577 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2579 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2580 value = &sa->sa_final;
2582 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2583 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2585 HASH_Init( &HASHcontext );
2586 if( prefix != NULL && prefix->bv_len > 0 ) {
2587 HASH_Update( &HASHcontext,
2588 prefix->bv_val, prefix->bv_len );
2590 HASH_Update( &HASHcontext,
2591 &pre, sizeof( pre ) );
2592 HASH_Update( &HASHcontext,
2593 syntax->ssyn_oid, slen );
2594 HASH_Update( &HASHcontext,
2595 mr->smr_oid, mlen );
2596 HASH_Update( &HASHcontext,
2597 &value->bv_val[value->bv_len-klen], klen );
2598 HASH_Final( HASHdigest, &HASHcontext );
2600 ber_dupbv( &keys[nkeys++], &digest );
2604 keys[nkeys].bv_val = NULL;
2611 return LDAP_SUCCESS;
2620 struct berval *value,
2621 void *assertedValue )
2623 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2625 if( match == 0 && value->bv_len ) {
2626 match = strncasecmp( value->bv_val,
2627 ((struct berval *) assertedValue)->bv_val,
2632 return LDAP_SUCCESS;
2636 caseIgnoreIA5SubstringsMatch(
2641 struct berval *value,
2642 void *assertedValue )
2645 SubstringsAssertion *sub = assertedValue;
2646 struct berval left = *value;
2650 /* Add up asserted input length */
2651 if( sub->sa_initial.bv_val ) {
2652 inlen += sub->sa_initial.bv_len;
2655 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2656 inlen += sub->sa_any[i].bv_len;
2659 if( sub->sa_final.bv_val ) {
2660 inlen += sub->sa_final.bv_len;
2663 if( sub->sa_initial.bv_val ) {
2664 if( inlen > left.bv_len ) {
2669 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
2670 sub->sa_initial.bv_len );
2676 left.bv_val += sub->sa_initial.bv_len;
2677 left.bv_len -= sub->sa_initial.bv_len;
2678 inlen -= sub->sa_initial.bv_len;
2681 if( sub->sa_final.bv_val ) {
2682 if( inlen > left.bv_len ) {
2687 match = strncasecmp( sub->sa_final.bv_val,
2688 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2689 sub->sa_final.bv_len );
2695 left.bv_len -= sub->sa_final.bv_len;
2696 inlen -= sub->sa_final.bv_len;
2700 for(i=0; sub->sa_any[i].bv_val; i++) {
2705 if( inlen > left.bv_len ) {
2706 /* not enough length */
2711 if( sub->sa_any[i].bv_len == 0 ) {
2715 p = strcasechr( left.bv_val, *sub->sa_any[i].bv_val );
2722 idx = p - left.bv_val;
2723 assert( idx < left.bv_len );
2725 if( idx >= left.bv_len ) {
2726 /* this shouldn't happen */
2733 if( sub->sa_any[i].bv_len > left.bv_len ) {
2734 /* not enough left */
2739 match = strncasecmp( left.bv_val,
2740 sub->sa_any[i].bv_val,
2741 sub->sa_any[i].bv_len );
2750 left.bv_val += sub->sa_any[i].bv_len;
2751 left.bv_len -= sub->sa_any[i].bv_len;
2752 inlen -= sub->sa_any[i].bv_len;
2758 return LDAP_SUCCESS;
2761 /* Index generation function */
2762 static int caseIgnoreIA5Indexer(
2767 struct berval *prefix,
2774 HASH_CONTEXT HASHcontext;
2775 unsigned char HASHdigest[HASH_BYTES];
2776 struct berval digest;
2777 digest.bv_val = HASHdigest;
2778 digest.bv_len = sizeof(HASHdigest);
2780 /* we should have at least one value at this point */
2781 assert( values != NULL && values[0].bv_val != NULL );
2783 for( i=0; values[i].bv_val != NULL; i++ ) {
2784 /* just count them */
2787 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2789 slen = syntax->ssyn_oidlen;
2790 mlen = mr->smr_oidlen;
2792 for( i=0; values[i].bv_val != NULL; i++ ) {
2793 struct berval value;
2794 ber_dupbv( &value, &values[i] );
2795 ldap_pvt_str2upper( value.bv_val );
2797 HASH_Init( &HASHcontext );
2798 if( prefix != NULL && prefix->bv_len > 0 ) {
2799 HASH_Update( &HASHcontext,
2800 prefix->bv_val, prefix->bv_len );
2802 HASH_Update( &HASHcontext,
2803 syntax->ssyn_oid, slen );
2804 HASH_Update( &HASHcontext,
2805 mr->smr_oid, mlen );
2806 HASH_Update( &HASHcontext,
2807 value.bv_val, value.bv_len );
2808 HASH_Final( HASHdigest, &HASHcontext );
2810 free( value.bv_val );
2812 ber_dupbv( &keys[i], &digest );
2815 keys[i].bv_val = NULL;
2817 return LDAP_SUCCESS;
2820 /* Index generation function */
2821 static int caseIgnoreIA5Filter(
2826 struct berval *prefix,
2832 HASH_CONTEXT HASHcontext;
2833 unsigned char HASHdigest[HASH_BYTES];
2834 struct berval value;
2835 struct berval digest;
2836 digest.bv_val = HASHdigest;
2837 digest.bv_len = sizeof(HASHdigest);
2839 slen = syntax->ssyn_oidlen;
2840 mlen = mr->smr_oidlen;
2842 ber_dupbv( &value, (struct berval *) assertValue );
2843 ldap_pvt_str2upper( value.bv_val );
2845 keys = ch_malloc( sizeof( struct berval ) * 2 );
2847 HASH_Init( &HASHcontext );
2848 if( prefix != NULL && prefix->bv_len > 0 ) {
2849 HASH_Update( &HASHcontext,
2850 prefix->bv_val, prefix->bv_len );
2852 HASH_Update( &HASHcontext,
2853 syntax->ssyn_oid, slen );
2854 HASH_Update( &HASHcontext,
2855 mr->smr_oid, mlen );
2856 HASH_Update( &HASHcontext,
2857 value.bv_val, value.bv_len );
2858 HASH_Final( HASHdigest, &HASHcontext );
2860 ber_dupbv( &keys[0], &digest );
2861 keys[1].bv_val = NULL;
2863 free( value.bv_val );
2867 return LDAP_SUCCESS;
2870 /* Substrings Index generation function */
2871 static int caseIgnoreIA5SubstringsIndexer(
2876 struct berval *prefix,
2883 HASH_CONTEXT HASHcontext;
2884 unsigned char HASHdigest[HASH_BYTES];
2885 struct berval digest;
2886 digest.bv_val = HASHdigest;
2887 digest.bv_len = sizeof(HASHdigest);
2889 /* we should have at least one value at this point */
2890 assert( values != NULL && values[0].bv_val != NULL );
2893 for( i=0; values[i].bv_val != NULL; i++ ) {
2894 /* count number of indices to generate */
2895 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2899 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2900 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2901 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2902 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2904 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2908 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2909 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2910 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2914 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2915 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2916 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2917 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2919 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2925 /* no keys to generate */
2927 return LDAP_SUCCESS;
2930 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2932 slen = syntax->ssyn_oidlen;
2933 mlen = mr->smr_oidlen;
2936 for( i=0; values[i].bv_val != NULL; i++ ) {
2938 struct berval value;
2940 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2942 ber_dupbv( &value, &values[i] );
2943 ldap_pvt_str2upper( value.bv_val );
2945 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2946 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2948 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2949 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2951 for( j=0; j<max; j++ ) {
2952 HASH_Init( &HASHcontext );
2953 if( prefix != NULL && prefix->bv_len > 0 ) {
2954 HASH_Update( &HASHcontext,
2955 prefix->bv_val, prefix->bv_len );
2958 HASH_Update( &HASHcontext,
2959 &pre, sizeof( pre ) );
2960 HASH_Update( &HASHcontext,
2961 syntax->ssyn_oid, slen );
2962 HASH_Update( &HASHcontext,
2963 mr->smr_oid, mlen );
2964 HASH_Update( &HASHcontext,
2966 SLAP_INDEX_SUBSTR_MAXLEN );
2967 HASH_Final( HASHdigest, &HASHcontext );
2969 ber_dupbv( &keys[nkeys++], &digest );
2973 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
2974 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
2976 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2979 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2980 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2981 HASH_Init( &HASHcontext );
2982 if( prefix != NULL && prefix->bv_len > 0 ) {
2983 HASH_Update( &HASHcontext,
2984 prefix->bv_val, prefix->bv_len );
2986 HASH_Update( &HASHcontext,
2987 &pre, sizeof( pre ) );
2988 HASH_Update( &HASHcontext,
2989 syntax->ssyn_oid, slen );
2990 HASH_Update( &HASHcontext,
2991 mr->smr_oid, mlen );
2992 HASH_Update( &HASHcontext,
2994 HASH_Final( HASHdigest, &HASHcontext );
2996 ber_dupbv( &keys[nkeys++], &digest );
2999 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3000 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3001 HASH_Init( &HASHcontext );
3002 if( prefix != NULL && prefix->bv_len > 0 ) {
3003 HASH_Update( &HASHcontext,
3004 prefix->bv_val, prefix->bv_len );
3006 HASH_Update( &HASHcontext,
3007 &pre, sizeof( pre ) );
3008 HASH_Update( &HASHcontext,
3009 syntax->ssyn_oid, slen );
3010 HASH_Update( &HASHcontext,
3011 mr->smr_oid, mlen );
3012 HASH_Update( &HASHcontext,
3013 &value.bv_val[value.bv_len-j], j );
3014 HASH_Final( HASHdigest, &HASHcontext );
3016 ber_dupbv( &keys[nkeys++], &digest );
3021 free( value.bv_val );
3025 keys[nkeys].bv_val = NULL;
3032 return LDAP_SUCCESS;
3035 static int caseIgnoreIA5SubstringsFilter(
3040 struct berval *prefix,
3044 SubstringsAssertion *sa = assertValue;
3046 ber_len_t nkeys = 0;
3047 size_t slen, mlen, klen;
3049 HASH_CONTEXT HASHcontext;
3050 unsigned char HASHdigest[HASH_BYTES];
3051 struct berval value;
3052 struct berval digest;
3054 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3055 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3060 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3062 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3063 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3064 /* don't bother accounting for stepping */
3065 nkeys += sa->sa_any[i].bv_len -
3066 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3071 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3072 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3079 return LDAP_SUCCESS;
3082 digest.bv_val = HASHdigest;
3083 digest.bv_len = sizeof(HASHdigest);
3085 slen = syntax->ssyn_oidlen;
3086 mlen = mr->smr_oidlen;
3088 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3091 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3092 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3094 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3095 ber_dupbv( &value, &sa->sa_initial );
3096 ldap_pvt_str2upper( value.bv_val );
3098 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3099 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3101 HASH_Init( &HASHcontext );
3102 if( prefix != NULL && prefix->bv_len > 0 ) {
3103 HASH_Update( &HASHcontext,
3104 prefix->bv_val, prefix->bv_len );
3106 HASH_Update( &HASHcontext,
3107 &pre, sizeof( pre ) );
3108 HASH_Update( &HASHcontext,
3109 syntax->ssyn_oid, slen );
3110 HASH_Update( &HASHcontext,
3111 mr->smr_oid, mlen );
3112 HASH_Update( &HASHcontext,
3113 value.bv_val, klen );
3114 HASH_Final( HASHdigest, &HASHcontext );
3116 free( value.bv_val );
3117 ber_dupbv( &keys[nkeys++], &digest );
3120 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3122 pre = SLAP_INDEX_SUBSTR_PREFIX;
3123 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3125 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3126 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3130 ber_dupbv( &value, &sa->sa_any[i] );
3131 ldap_pvt_str2upper( value.bv_val );
3134 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3135 j += SLAP_INDEX_SUBSTR_STEP )
3137 HASH_Init( &HASHcontext );
3138 if( prefix != NULL && prefix->bv_len > 0 ) {
3139 HASH_Update( &HASHcontext,
3140 prefix->bv_val, prefix->bv_len );
3142 HASH_Update( &HASHcontext,
3143 &pre, sizeof( pre ) );
3144 HASH_Update( &HASHcontext,
3145 syntax->ssyn_oid, slen );
3146 HASH_Update( &HASHcontext,
3147 mr->smr_oid, mlen );
3148 HASH_Update( &HASHcontext,
3149 &value.bv_val[j], klen );
3150 HASH_Final( HASHdigest, &HASHcontext );
3152 ber_dupbv( &keys[nkeys++], &digest );
3155 free( value.bv_val );
3159 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3160 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3162 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3163 ber_dupbv( &value, &sa->sa_final );
3164 ldap_pvt_str2upper( value.bv_val );
3166 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3167 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3169 HASH_Init( &HASHcontext );
3170 if( prefix != NULL && prefix->bv_len > 0 ) {
3171 HASH_Update( &HASHcontext,
3172 prefix->bv_val, prefix->bv_len );
3174 HASH_Update( &HASHcontext,
3175 &pre, sizeof( pre ) );
3176 HASH_Update( &HASHcontext,
3177 syntax->ssyn_oid, slen );
3178 HASH_Update( &HASHcontext,
3179 mr->smr_oid, mlen );
3180 HASH_Update( &HASHcontext,
3181 &value.bv_val[value.bv_len-klen], klen );
3182 HASH_Final( HASHdigest, &HASHcontext );
3184 free( value.bv_val );
3185 ber_dupbv( &keys[nkeys++], &digest );
3189 keys[nkeys].bv_val = NULL;
3196 return LDAP_SUCCESS;
3200 numericStringValidate(
3206 for(i=0; i < in->bv_len; i++) {
3207 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3208 return LDAP_INVALID_SYNTAX;
3212 return LDAP_SUCCESS;
3216 numericStringNormalize(
3219 struct berval *normalized )
3221 /* removal all spaces */
3224 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3227 q = normalized->bv_val;
3230 if ( ASCII_SPACE( *p ) ) {
3231 /* Ignore whitespace */
3238 /* we should have copied no more then is in val */
3239 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3241 /* null terminate */
3244 normalized->bv_len = q - normalized->bv_val;
3246 return LDAP_SUCCESS;
3250 objectIdentifierFirstComponentMatch(
3255 struct berval *value,
3256 void *assertedValue )
3258 int rc = LDAP_SUCCESS;
3260 struct berval *asserted = (struct berval *) assertedValue;
3264 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3265 return LDAP_INVALID_SYNTAX;
3268 /* trim leading white space */
3269 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3273 /* grab next word */
3274 oid.bv_val = &value->bv_val[i];
3275 oid.bv_len = value->bv_len - i;
3276 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3281 /* insert attributeTypes, objectclass check here */
3282 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3283 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3286 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3287 MatchingRule *asserted_mr = mr_bvfind( asserted );
3288 MatchingRule *stored_mr = mr_bvfind( &oid );
3290 if( asserted_mr == NULL ) {
3291 rc = SLAPD_COMPARE_UNDEFINED;
3293 match = asserted_mr != stored_mr;
3296 } else if ( !strcmp( syntax->ssyn_oid,
3297 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3299 AttributeType *asserted_at = at_bvfind( asserted );
3300 AttributeType *stored_at = at_bvfind( &oid );
3302 if( asserted_at == NULL ) {
3303 rc = SLAPD_COMPARE_UNDEFINED;
3305 match = asserted_at != stored_at;
3308 } else if ( !strcmp( syntax->ssyn_oid,
3309 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3311 ObjectClass *asserted_oc = oc_bvfind( asserted );
3312 ObjectClass *stored_oc = oc_bvfind( &oid );
3314 if( asserted_oc == NULL ) {
3315 rc = SLAPD_COMPARE_UNDEFINED;
3317 match = asserted_oc != stored_oc;
3323 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3324 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3325 match, value->bv_val, asserted->bv_val ));
3327 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3328 "%d\n\t\"%s\"\n\t\"%s\"\n",
3329 match, value->bv_val, asserted->bv_val );
3333 if( rc == LDAP_SUCCESS ) *matchp = match;
3343 struct berval *value,
3344 void *assertedValue )
3346 long lValue, lAssertedValue;
3348 /* safe to assume integers are NUL terminated? */
3349 lValue = strtoul(value->bv_val, NULL, 10);
3350 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3351 return LDAP_CONSTRAINT_VIOLATION;
3353 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3354 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3355 return LDAP_CONSTRAINT_VIOLATION;
3357 *matchp = (lValue & lAssertedValue);
3358 return LDAP_SUCCESS;
3367 struct berval *value,
3368 void *assertedValue )
3370 long lValue, lAssertedValue;
3372 /* safe to assume integers are NUL terminated? */
3373 lValue = strtoul(value->bv_val, NULL, 10);
3374 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3375 return LDAP_CONSTRAINT_VIOLATION;
3377 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3378 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3379 return LDAP_CONSTRAINT_VIOLATION;
3381 *matchp = (lValue | lAssertedValue);
3382 return LDAP_SUCCESS;
3386 #include <openssl/x509.h>
3387 #include <openssl/err.h>
3388 char digit[] = "0123456789";
3391 * Next function returns a string representation of a ASN1_INTEGER.
3392 * It works for unlimited lengths.
3395 static struct berval *
3396 asn1_integer2str(ASN1_INTEGER *a)
3401 /* We work backwards, make it fill from the end of buf */
3402 p = buf + sizeof(buf) - 1;
3405 if ( a == NULL || a->length == 0 ) {
3413 /* We want to preserve the original */
3414 copy = ch_malloc(n*sizeof(unsigned int));
3415 for (i = 0; i<n; i++) {
3416 copy[i] = a->data[i];
3420 * base indicates the index of the most significant
3421 * byte that might be nonzero. When it goes off the
3422 * end, we now there is nothing left to do.
3428 for (i = base; i<n; i++ ) {
3429 copy[i] += carry*256;
3430 carry = copy[i] % 10;
3435 * Way too large, we need to leave
3436 * room for sign if negative
3441 *--p = digit[carry];
3442 if (copy[base] == 0)
3448 if ( a->type == V_ASN1_NEG_INTEGER ) {
3452 return ber_bvstrdup(p);
3455 /* Get a DN in RFC2253 format from a X509_NAME internal struct */
3456 static struct berval *
3457 dn_openssl2ldap(X509_NAME *name)
3459 char issuer_dn[1024];
3462 bio = BIO_new(BIO_s_mem());
3465 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3466 "dn_openssl2ldap: error creating BIO_s_mem: %s\n",
3467 ERR_error_string(ERR_get_error(),NULL)));
3469 Debug( LDAP_DEBUG_ARGS, "dn_openssl2ldap: "
3470 "error creating BIO: %s\n",
3471 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3475 X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253);
3477 BIO_gets(bio, issuer_dn, 1024);
3480 return ber_bvstrdup(issuer_dn);
3484 * Given a certificate in DER format, extract the corresponding
3485 * assertion value for certificateExactMatch
3488 certificateExactConvert(
3490 struct berval * out )
3493 unsigned char *p = in->bv_val;
3494 struct berval *serial;
3495 struct berval *issuer_dn;
3496 struct berval *bv_tmp;
3498 xcert = d2i_X509(NULL, &p, in->bv_len);
3501 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3502 "certificateExactConvert: error parsing cert: %s\n",
3503 ERR_error_string(ERR_get_error(),NULL)));
3505 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3506 "error parsing cert: %s\n",
3507 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3509 return LDAP_INVALID_SYNTAX;
3512 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3515 return LDAP_INVALID_SYNTAX;
3517 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
3521 return LDAP_INVALID_SYNTAX;
3523 /* Actually, dn_openssl2ldap returns in a normalized format, but
3524 it is different from our normalized format */
3526 if ( dnNormalize(NULL, bv_tmp, &issuer_dn) != LDAP_SUCCESS ) {
3530 return LDAP_INVALID_SYNTAX;
3536 out->bv_len = serial->bv_len + issuer_dn->bv_len + sizeof(" $ ");
3537 out->bv_val = ch_malloc(out->bv_len);
3539 AC_MEMCPY(p, serial->bv_val, serial->bv_len);
3540 p += serial->bv_len;
3541 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
3543 AC_MEMCPY(p, issuer_dn->bv_val, issuer_dn->bv_len);
3544 p += issuer_dn->bv_len;
3548 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3549 "certificateExactConvert: \n %s\n",
3552 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3554 out->bv_val, NULL, NULL );
3558 ber_bvfree(issuer_dn);
3560 return LDAP_SUCCESS;
3564 serial_and_issuer_parse(
3565 struct berval *assertion,
3566 struct berval **serial,
3567 struct berval **issuer_dn
3575 begin = assertion->bv_val;
3576 end = assertion->bv_val+assertion->bv_len-1;
3577 for (p=begin; p<=end && *p != '$'; p++)
3580 return LDAP_INVALID_SYNTAX;
3582 /* p now points at the $ sign, now use begin and end to delimit the
3584 while (ASCII_SPACE(*begin))
3587 while (ASCII_SPACE(*end))
3590 bv.bv_len = end-begin+1;
3592 *serial = ber_bvdup(&bv);
3594 /* now extract the issuer, remember p was at the dollar sign */
3596 end = assertion->bv_val+assertion->bv_len-1;
3597 while (ASCII_SPACE(*begin))
3599 /* should we trim spaces at the end too? is it safe always? */
3601 bv.bv_len = end-begin+1;
3603 dnNormalize( NULL, &bv, issuer_dn );
3605 return LDAP_SUCCESS;
3609 certificateExactMatch(
3614 struct berval *value,
3615 void *assertedValue )
3618 unsigned char *p = value->bv_val;
3619 struct berval *serial;
3620 struct berval *issuer_dn;
3621 struct berval *asserted_serial;
3622 struct berval *asserted_issuer_dn;
3625 xcert = d2i_X509(NULL, &p, value->bv_len);
3628 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3629 "certificateExactMatch: error parsing cert: %s\n",
3630 ERR_error_string(ERR_get_error(),NULL)));
3632 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
3633 "error parsing cert: %s\n",
3634 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3636 return LDAP_INVALID_SYNTAX;
3639 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3640 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
3644 serial_and_issuer_parse(assertedValue,
3646 &asserted_issuer_dn);
3651 slap_schema.si_syn_integer,
3652 slap_schema.si_mr_integerMatch,
3655 if ( ret == LDAP_SUCCESS ) {
3656 if ( *matchp == 0 ) {
3657 /* We need to normalize everything for dnMatch */
3661 slap_schema.si_syn_distinguishedName,
3662 slap_schema.si_mr_distinguishedNameMatch,
3664 asserted_issuer_dn);
3669 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3670 "certificateExactMatch: %d\n %s $ %s\n %s $ %s\n",
3671 *matchp, serial->bv_val, issuer_dn->bv_val,
3672 asserted->serial->bv_val, asserted_issuer_dn->bv_val));
3674 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3675 "%d\n\t\"%s $ %s\"\n",
3676 *matchp, serial->bv_val, issuer_dn->bv_val );
3677 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3678 asserted_serial->bv_val, asserted_issuer_dn->bv_val,
3683 ber_bvfree(issuer_dn);
3684 ber_bvfree(asserted_serial);
3685 ber_bvfree(asserted_issuer_dn);
3691 * Index generation function
3692 * We just index the serials, in most scenarios the issuer DN is one of
3693 * a very small set of values.
3695 static int certificateExactIndexer(
3700 struct berval *prefix,
3708 struct berval * serial;
3710 /* we should have at least one value at this point */
3711 assert( values != NULL && values[0].bv_val != NULL );
3713 for( i=0; values[i].bv_val != NULL; i++ ) {
3714 /* empty -- just count them */
3717 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3719 for( i=0; values[i].bv_val != NULL; i++ ) {
3720 p = values[i].bv_val;
3721 xcert = d2i_X509(NULL, &p, values[i].bv_len);
3724 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3725 "certificateExactIndexer: error parsing cert: %s\n",
3726 ERR_error_string(ERR_get_error(),NULL)));
3728 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3729 "error parsing cert: %s\n",
3730 ERR_error_string(ERR_get_error(),NULL),
3733 /* Do we leak keys on error? */
3734 return LDAP_INVALID_SYNTAX;
3737 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3739 integerNormalize( slap_schema.si_syn_integer,
3744 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3745 "certificateExactIndexer: returning: %s\n",
3748 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3755 keys[i].bv_val = NULL;
3757 return LDAP_SUCCESS;
3760 /* Index generation function */
3761 /* We think this is always called with a value in matching rule syntax */
3762 static int certificateExactFilter(
3767 struct berval *prefix,
3772 struct berval *asserted_serial;
3773 struct berval *asserted_issuer_dn;
3775 serial_and_issuer_parse(assertValue,
3777 &asserted_issuer_dn);
3779 keys = ch_malloc( sizeof( struct berval ) * 2 );
3780 integerNormalize( syntax, asserted_serial, &keys[0] );
3781 keys[1].bv_val = NULL;
3784 ber_bvfree(asserted_serial);
3785 ber_bvfree(asserted_issuer_dn);
3786 return LDAP_SUCCESS;
3791 check_time_syntax (struct berval *val,
3795 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3796 static int mdays[2][12] = {
3797 /* non-leap years */
3798 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3800 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3803 int part, c, tzoffset, leapyear = 0 ;
3805 if( val->bv_len == 0 ) {
3806 return LDAP_INVALID_SYNTAX;
3809 p = (char *)val->bv_val;
3810 e = p + val->bv_len;
3812 /* Ignore initial whitespace */
3813 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3817 if (e - p < 13 - (2 * start)) {
3818 return LDAP_INVALID_SYNTAX;
3821 for (part = 0; part < 9; part++) {
3825 for (part = start; part < 7; part++) {
3827 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3834 return LDAP_INVALID_SYNTAX;
3836 if (c < 0 || c > 9) {
3837 return LDAP_INVALID_SYNTAX;
3843 return LDAP_INVALID_SYNTAX;
3845 if (c < 0 || c > 9) {
3846 return LDAP_INVALID_SYNTAX;
3851 if (part == 2 || part == 3) {
3854 if (parts[part] < 0) {
3855 return LDAP_INVALID_SYNTAX;
3857 if (parts[part] > ceiling[part]) {
3858 return LDAP_INVALID_SYNTAX;
3862 /* leapyear check for the Gregorian calendar (year>1581) */
3863 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
3864 ((parts[0] % 4 == 0) && (parts[1] == 0)))
3869 if (parts[3] > mdays[leapyear][parts[2]]) {
3870 return LDAP_INVALID_SYNTAX;
3875 tzoffset = 0; /* UTC */
3876 } else if (c != '+' && c != '-') {
3877 return LDAP_INVALID_SYNTAX;
3881 } else /* c == '+' */ {
3886 return LDAP_INVALID_SYNTAX;
3889 for (part = 7; part < 9; part++) {
3891 if (c < 0 || c > 9) {
3892 return LDAP_INVALID_SYNTAX;
3897 if (c < 0 || c > 9) {
3898 return LDAP_INVALID_SYNTAX;
3902 if (parts[part] < 0 || parts[part] > ceiling[part]) {
3903 return LDAP_INVALID_SYNTAX;
3908 /* Ignore trailing whitespace */
3909 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3913 return LDAP_INVALID_SYNTAX;
3916 switch ( tzoffset ) {
3917 case -1: /* negativ offset to UTC, ie west of Greenwich */
3918 parts[4] += parts[7];
3919 parts[5] += parts[8];
3920 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
3924 c = mdays[leapyear][parts[2]];
3926 if (parts[part] > c) {
3927 parts[part] -= c + 1;
3932 case 1: /* positive offset to UTC, ie east of Greenwich */
3933 parts[4] -= parts[7];
3934 parts[5] -= parts[8];
3935 for (part = 6; --part > 0; ) {
3939 /* first arg to % needs to be non negativ */
3940 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
3942 if (parts[part] < 0) {
3943 parts[part] += c + 1;
3948 case 0: /* already UTC */
3952 return LDAP_SUCCESS;
3959 struct berval *normalized )
3963 rc = check_time_syntax(val, 1, parts);
3964 if (rc != LDAP_SUCCESS) {
3968 normalized->bv_val = ch_malloc( 14 );
3969 if ( normalized->bv_val == NULL ) {
3970 return LBER_ERROR_MEMORY;
3973 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
3974 parts[1], parts[2] + 1, parts[3] + 1,
3975 parts[4], parts[5], parts[6] );
3976 normalized->bv_len = 13;
3978 return LDAP_SUCCESS;
3988 return check_time_syntax(in, 1, parts);
3992 generalizedTimeValidate(
3998 return check_time_syntax(in, 0, parts);
4002 generalizedTimeNormalize(
4005 struct berval *normalized )
4009 rc = check_time_syntax(val, 0, parts);
4010 if (rc != LDAP_SUCCESS) {
4014 normalized->bv_val = ch_malloc( 16 );
4015 if ( normalized->bv_val == NULL ) {
4016 return LBER_ERROR_MEMORY;
4019 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4020 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4021 parts[4], parts[5], parts[6] );
4022 normalized->bv_len = 15;
4024 return LDAP_SUCCESS;
4028 nisNetgroupTripleValidate(
4030 struct berval *val )
4035 if ( val->bv_len == 0 ) {
4036 return LDAP_INVALID_SYNTAX;
4039 p = (char *)val->bv_val;
4040 e = p + val->bv_len;
4042 if ( *p != '(' /*')'*/ ) {
4043 return LDAP_INVALID_SYNTAX;
4046 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4050 return LDAP_INVALID_SYNTAX;
4053 } else if ( !ATTR_CHAR( *p ) ) {
4054 return LDAP_INVALID_SYNTAX;
4058 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4059 return LDAP_INVALID_SYNTAX;
4065 return LDAP_INVALID_SYNTAX;
4068 return LDAP_SUCCESS;
4072 bootParameterValidate(
4074 struct berval *val )
4078 if ( val->bv_len == 0 ) {
4079 return LDAP_INVALID_SYNTAX;
4082 p = (char *)val->bv_val;
4083 e = p + val->bv_len;
4086 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4087 if ( !ATTR_CHAR( *p ) ) {
4088 return LDAP_INVALID_SYNTAX;
4093 return LDAP_INVALID_SYNTAX;
4097 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4098 if ( !ATTR_CHAR( *p ) ) {
4099 return LDAP_INVALID_SYNTAX;
4104 return LDAP_INVALID_SYNTAX;
4108 for ( p++; p < e; p++ ) {
4109 if ( !ATTR_CHAR( *p ) ) {
4110 return LDAP_INVALID_SYNTAX;
4114 return LDAP_SUCCESS;
4117 static struct syntax_defs_rec {
4119 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4120 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4122 slap_syntax_validate_func *sd_validate;
4123 slap_syntax_transform_func *sd_normalize;
4124 slap_syntax_transform_func *sd_pretty;
4125 #ifdef SLAPD_BINARY_CONVERSION
4126 slap_syntax_transform_func *sd_ber2str;
4127 slap_syntax_transform_func *sd_str2ber;
4130 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
4131 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4132 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4133 0, NULL, NULL, NULL},
4134 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4135 0, NULL, NULL, NULL},
4136 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
4137 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4138 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_NOT_H_R ")",
4139 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4140 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4141 0, bitStringValidate, bitStringNormalize, NULL },
4142 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4143 0, booleanValidate, NULL, NULL},
4144 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4145 X_BINARY X_NOT_H_R ")",
4146 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4147 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4148 X_BINARY X_NOT_H_R ")",
4149 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4150 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4151 X_BINARY X_NOT_H_R ")",
4152 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4153 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4154 0, countryStringValidate, IA5StringNormalize, NULL},
4155 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4156 0, dnValidate, dnNormalize2, dnPretty2},
4157 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4158 0, NULL, NULL, NULL},
4159 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4160 0, NULL, NULL, NULL},
4161 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4162 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4163 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4164 0, NULL, NULL, NULL},
4165 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4166 0, NULL, NULL, NULL},
4167 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4168 0, NULL, NULL, NULL},
4169 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4170 0, NULL, NULL, NULL},
4171 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4172 0, NULL, NULL, NULL},
4173 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4174 0, printablesStringValidate, IA5StringNormalize, NULL},
4175 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4176 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4177 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4178 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4179 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4180 0, NULL, NULL, NULL},
4181 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4182 0, IA5StringValidate, IA5StringNormalize, NULL},
4183 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4184 0, integerValidate, integerNormalize, NULL},
4185 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4186 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4187 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4188 0, NULL, NULL, NULL},
4189 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4190 0, NULL, NULL, NULL},
4191 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4192 0, NULL, NULL, NULL},
4193 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4194 0, NULL, NULL, NULL},
4195 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4196 0, NULL, NULL, NULL},
4197 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4198 0, nameUIDValidate, nameUIDNormalize, NULL},
4199 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4200 0, NULL, NULL, NULL},
4201 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4202 0, numericStringValidate, numericStringNormalize, NULL},
4203 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4204 0, NULL, NULL, NULL},
4205 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4206 0, oidValidate, NULL, NULL},
4207 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4208 0, IA5StringValidate, IA5StringNormalize, NULL},
4209 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4210 0, blobValidate, NULL, NULL},
4211 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4212 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4213 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4214 0, NULL, NULL, NULL},
4215 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4216 0, NULL, NULL, NULL},
4217 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4218 0, printableStringValidate, IA5StringNormalize, NULL},
4219 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
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.50 DESC 'Telephone Number' )",
4223 0, printableStringValidate, IA5StringNormalize, NULL},
4224 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4225 0, NULL, NULL, NULL},
4226 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4227 0, printablesStringValidate, IA5StringNormalize, NULL},
4228 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4229 0, utcTimeValidate, utcTimeNormalize, NULL},
4230 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4231 0, NULL, NULL, NULL},
4232 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4233 0, NULL, NULL, NULL},
4234 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4235 0, NULL, NULL, NULL},
4236 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4237 0, NULL, NULL, NULL},
4238 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4239 0, NULL, NULL, NULL},
4241 /* RFC 2307 NIS Syntaxes */
4242 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4243 0, nisNetgroupTripleValidate, NULL, NULL},
4244 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4245 0, bootParameterValidate, NULL, NULL},
4249 /* These OIDs are not published yet, but will be in the next
4250 * I-D for PKIX LDAPv3 schema as have been advanced by David
4251 * Chadwick in private mail.
4253 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4254 0, NULL, NULL, NULL},
4257 /* OpenLDAP Experimental Syntaxes */
4258 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4260 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4263 /* needs updating */
4264 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4265 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4267 /* OpenLDAP Void Syntax */
4268 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4269 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4270 {NULL, 0, NULL, NULL, NULL}
4274 * Other matching rules in X.520 that we do not use (yet):
4276 * 2.5.13.9 numericStringOrderingMatch
4277 * 2.5.13.15 integerOrderingMatch
4278 * 2.5.13.18 octetStringOrderingMatch
4279 * 2.5.13.19 octetStringSubstringsMatch
4280 * 2.5.13.25 uTCTimeMatch
4281 * 2.5.13.26 uTCTimeOrderingMatch
4282 * 2.5.13.31 directoryStringFirstComponentMatch
4283 * 2.5.13.32 wordMatch
4284 * 2.5.13.33 keywordMatch
4285 * 2.5.13.35 certificateMatch
4286 * 2.5.13.36 certificatePairExactMatch
4287 * 2.5.13.37 certificatePairMatch
4288 * 2.5.13.38 certificateListExactMatch
4289 * 2.5.13.39 certificateListMatch
4290 * 2.5.13.40 algorithmIdentifierMatch
4291 * 2.5.13.41 storedPrefixMatch
4292 * 2.5.13.42 attributeCertificateMatch
4293 * 2.5.13.43 readerAndKeyIDMatch
4294 * 2.5.13.44 attributeIntegrityMatch
4296 static struct mrule_defs_rec {
4298 slap_mask_t mrd_usage;
4299 slap_mr_convert_func * mrd_convert;
4300 slap_mr_normalize_func * mrd_normalize;
4301 slap_mr_match_func * mrd_match;
4302 slap_mr_indexer_func * mrd_indexer;
4303 slap_mr_filter_func * mrd_filter;
4305 char * mrd_associated;
4308 * EQUALITY matching rules must be listed after associated APPROX
4309 * matching rules. So, we list all APPROX matching rules first.
4311 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4312 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4313 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4315 directoryStringApproxMatch,
4316 directoryStringApproxIndexer,
4317 directoryStringApproxFilter,
4320 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4321 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4322 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4324 IA5StringApproxMatch,
4325 IA5StringApproxIndexer,
4326 IA5StringApproxFilter,
4330 * Other matching rules
4333 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4334 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4335 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4337 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4340 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4341 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4342 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4344 dnMatch, dnIndexer, dnFilter,
4347 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4348 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4349 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4351 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4352 directoryStringApproxMatchOID },
4354 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4355 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4358 caseIgnoreOrderingMatch, NULL, NULL,
4361 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4362 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4363 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4365 caseExactIgnoreSubstringsMatch,
4366 caseExactIgnoreSubstringsIndexer,
4367 caseExactIgnoreSubstringsFilter,
4370 {"( 2.5.13.5 NAME 'caseExactMatch' "
4371 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4372 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4374 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4375 directoryStringApproxMatchOID },
4377 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4378 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4381 caseExactOrderingMatch, NULL, NULL,
4384 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4385 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4386 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4388 caseExactIgnoreSubstringsMatch,
4389 caseExactIgnoreSubstringsIndexer,
4390 caseExactIgnoreSubstringsFilter,
4393 {"( 2.5.13.8 NAME 'numericStringMatch' "
4394 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4395 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4398 caseIgnoreIA5Indexer,
4399 caseIgnoreIA5Filter,
4402 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4403 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4404 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4406 caseIgnoreIA5SubstringsMatch,
4407 caseIgnoreIA5SubstringsIndexer,
4408 caseIgnoreIA5SubstringsFilter,
4411 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4412 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4413 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4415 caseIgnoreListMatch, NULL, NULL,
4418 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4419 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4420 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4422 caseIgnoreListSubstringsMatch, NULL, NULL,
4425 {"( 2.5.13.13 NAME 'booleanMatch' "
4426 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4427 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4429 booleanMatch, NULL, NULL,
4432 {"( 2.5.13.14 NAME 'integerMatch' "
4433 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4434 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4436 integerMatch, integerIndexer, integerFilter,
4439 {"( 2.5.13.16 NAME 'bitStringMatch' "
4440 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4441 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4443 bitStringMatch, bitStringIndexer, bitStringFilter,
4446 {"( 2.5.13.17 NAME 'octetStringMatch' "
4447 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4448 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4450 octetStringMatch, octetStringIndexer, octetStringFilter,
4453 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4454 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4455 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4457 telephoneNumberMatch,
4458 telephoneNumberIndexer,
4459 telephoneNumberFilter,
4462 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4463 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4464 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4466 telephoneNumberSubstringsMatch,
4467 telephoneNumberSubstringsIndexer,
4468 telephoneNumberSubstringsFilter,
4471 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4472 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4473 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4478 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4479 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4480 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4482 uniqueMemberMatch, NULL, NULL,
4485 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4486 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4487 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4489 protocolInformationMatch, NULL, NULL,
4492 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4493 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4494 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4496 generalizedTimeMatch, NULL, NULL,
4499 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4500 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4503 generalizedTimeOrderingMatch, NULL, NULL,
4506 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4507 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4508 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4510 integerFirstComponentMatch, NULL, NULL,
4513 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4514 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4515 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4517 objectIdentifierFirstComponentMatch, NULL, NULL,
4521 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4522 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4523 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4524 certificateExactConvert, NULL,
4525 certificateExactMatch,
4526 certificateExactIndexer, certificateExactFilter,
4530 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4531 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4532 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4534 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4535 IA5StringApproxMatchOID },
4537 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4538 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4539 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4541 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4542 IA5StringApproxMatchOID },
4544 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4545 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4548 caseIgnoreIA5SubstringsMatch,
4549 caseIgnoreIA5SubstringsIndexer,
4550 caseIgnoreIA5SubstringsFilter,
4553 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4554 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4557 caseExactIA5SubstringsMatch,
4558 caseExactIA5SubstringsIndexer,
4559 caseExactIA5SubstringsFilter,
4562 /* needs updating */
4563 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4564 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4567 authPasswordMatch, NULL, NULL,
4570 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4571 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4574 OpenLDAPaciMatch, NULL, NULL,
4577 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4578 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4581 integerBitAndMatch, NULL, NULL,
4584 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4585 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4588 integerBitOrMatch, NULL, NULL,
4591 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
4600 /* we should only be called once (from main) */
4601 assert( schema_init_done == 0 );
4603 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4604 res = register_syntax( syntax_defs[i].sd_desc,
4605 syntax_defs[i].sd_flags,
4606 syntax_defs[i].sd_validate,
4607 syntax_defs[i].sd_normalize,
4608 syntax_defs[i].sd_pretty
4609 #ifdef SLAPD_BINARY_CONVERSION
4611 syntax_defs[i].sd_ber2str,
4612 syntax_defs[i].sd_str2ber
4617 fprintf( stderr, "schema_init: Error registering syntax %s\n",
4618 syntax_defs[i].sd_desc );
4623 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4624 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
4626 "schema_init: Ingoring unusable matching rule %s\n",
4627 mrule_defs[i].mrd_desc );
4631 res = register_matching_rule(
4632 mrule_defs[i].mrd_desc,
4633 mrule_defs[i].mrd_usage,
4634 mrule_defs[i].mrd_convert,
4635 mrule_defs[i].mrd_normalize,
4636 mrule_defs[i].mrd_match,
4637 mrule_defs[i].mrd_indexer,
4638 mrule_defs[i].mrd_filter,
4639 mrule_defs[i].mrd_associated );
4643 "schema_init: Error registering matching rule %s\n",
4644 mrule_defs[i].mrd_desc );
4648 schema_init_done = 1;
4649 return LDAP_SUCCESS;
4653 schema_destroy( void )