1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
15 #include <ac/string.h>
16 #include <ac/socket.h>
22 #include "ldap_utf8.h"
24 #include "lutil_hash.h"
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 */
35 #define integerPretty NULL
37 /* recycled matching routines */
38 #define bitStringMatch octetStringMatch
39 #define numericStringMatch caseIgnoreIA5Match
40 #define objectIdentifierMatch caseIgnoreIA5Match
41 #define telephoneNumberMatch caseIgnoreIA5Match
42 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
43 #define generalizedTimeMatch caseIgnoreIA5Match
44 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
45 #define uniqueMemberMatch dnMatch
46 #define integerFirstComponentMatch integerMatch
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 /* ordering matching rules */
59 #define caseIgnoreOrderingMatch caseIgnoreMatch
60 #define caseExactOrderingMatch caseExactMatch
61 #define integerOrderingMatch integerMatch
63 /* unimplemented matching routines */
64 #define caseIgnoreListMatch NULL
65 #define caseIgnoreListSubstringsMatch NULL
66 #define protocolInformationMatch NULL
68 #ifdef SLAPD_ACI_ENABLED
69 #define OpenLDAPaciMatch NULL
71 #ifdef SLAPD_AUTHPASSWD
72 #define authPasswordMatch NULL
75 /* recycled indexing/filtering routines */
76 #define dnIndexer caseExactIgnoreIndexer
77 #define dnFilter caseExactIgnoreFilter
78 #define bitStringFilter octetStringFilter
79 #define bitStringIndexer octetStringIndexer
81 #define telephoneNumberIndexer caseIgnoreIA5Indexer
82 #define telephoneNumberFilter caseIgnoreIA5Filter
83 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
84 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
86 static MatchingRule *caseExactMatchingRule;
87 static MatchingRule *caseExactSubstringsMatchingRule;
88 static MatchingRule *integerFirstComponentMatchingRule;
90 static const struct MatchingRulePtr {
94 /* must match OIDs below */
95 { "2.5.13.5", &caseExactMatchingRule },
96 { "2.5.13.7", &caseExactSubstringsMatchingRule },
97 { "2.5.13.29", &integerFirstComponentMatchingRule }
101 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
104 char lower = TOLOWER( c );
105 char upper = TOUPPER( c );
107 if( c == 0 ) return NULL;
109 for( i=0; i < bv->bv_len; i++ ) {
110 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
112 return &bv->bv_val[i];
125 struct berval *value,
126 void *assertedValue )
128 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
131 match = memcmp( value->bv_val,
132 ((struct berval *) assertedValue)->bv_val,
140 /* Index generation function */
141 static int octetStringIndexer(
146 struct berval *prefix,
153 HASH_CONTEXT HASHcontext;
154 unsigned char HASHdigest[HASH_BYTES];
155 struct berval digest;
156 digest.bv_val = HASHdigest;
157 digest.bv_len = sizeof(HASHdigest);
159 for( i=0; values[i].bv_val != NULL; i++ ) {
160 /* just count them */
163 /* we should have at least one value at this point */
166 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
168 slen = syntax->ssyn_oidlen;
169 mlen = mr->smr_oidlen;
171 for( i=0; values[i].bv_val != NULL; i++ ) {
172 HASH_Init( &HASHcontext );
173 if( prefix != NULL && prefix->bv_len > 0 ) {
174 HASH_Update( &HASHcontext,
175 prefix->bv_val, prefix->bv_len );
177 HASH_Update( &HASHcontext,
178 syntax->ssyn_oid, slen );
179 HASH_Update( &HASHcontext,
181 HASH_Update( &HASHcontext,
182 values[i].bv_val, values[i].bv_len );
183 HASH_Final( HASHdigest, &HASHcontext );
185 ber_dupbv( &keys[i], &digest );
188 keys[i].bv_val = NULL;
195 /* Index generation function */
196 static int octetStringFilter(
201 struct berval *prefix,
207 HASH_CONTEXT HASHcontext;
208 unsigned char HASHdigest[HASH_BYTES];
209 struct berval *value = (struct berval *) assertValue;
210 struct berval digest;
211 digest.bv_val = HASHdigest;
212 digest.bv_len = sizeof(HASHdigest);
214 slen = syntax->ssyn_oidlen;
215 mlen = mr->smr_oidlen;
217 keys = ch_malloc( sizeof( struct berval ) * 2 );
219 HASH_Init( &HASHcontext );
220 if( prefix != NULL && prefix->bv_len > 0 ) {
221 HASH_Update( &HASHcontext,
222 prefix->bv_val, prefix->bv_len );
224 HASH_Update( &HASHcontext,
225 syntax->ssyn_oid, slen );
226 HASH_Update( &HASHcontext,
228 HASH_Update( &HASHcontext,
229 value->bv_val, value->bv_len );
230 HASH_Final( HASHdigest, &HASHcontext );
232 ber_dupbv( keys, &digest );
233 keys[1].bv_val = NULL;
245 /* any value allowed */
254 /* any value allowed */
265 /* very unforgiving validation, requires no normalization
266 * before simplistic matching
268 if( in->bv_len < 3 ) {
269 return LDAP_INVALID_SYNTAX;
273 * rfc 2252 section 6.3 Bit String
274 * bitstring = "'" *binary-digit "'"
275 * binary-digit = "0" / "1"
276 * example: '0101111101'B
279 if( in->bv_val[0] != '\'' ||
280 in->bv_val[in->bv_len-2] != '\'' ||
281 in->bv_val[in->bv_len-1] != 'B' )
283 return LDAP_INVALID_SYNTAX;
286 for( i=in->bv_len-3; i>0; i-- ) {
287 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
288 return LDAP_INVALID_SYNTAX;
299 struct berval *normalized )
302 * A normalized bitString is has no extaneous (leading) zero bits.
303 * That is, '00010'B is normalized to '10'B
304 * However, as a special case, '0'B requires no normalization.
308 /* start at the first bit */
311 /* Find the first non-zero bit */
312 while ( *p == '0' ) p++;
315 /* no non-zero bits */
316 ber_str2bv( "\'0\'B", sizeof("\'0\'B") - 1, 1, normalized );
320 normalized->bv_val = ch_malloc( val->bv_len + 1 );
322 normalized->bv_val[0] = '\'';
323 normalized->bv_len = 1;
325 for( ; *p != '\0'; p++ ) {
326 normalized->bv_val[normalized->bv_len++] = *p;
329 normalized->bv_val[normalized->bv_len] = '\0';
343 if( in->bv_len == 0 ) return LDAP_SUCCESS;
345 ber_dupbv( &dn, in );
346 if( !dn.bv_val ) return LDAP_OTHER;
348 if( dn.bv_val[dn.bv_len-1] == 'B'
349 && dn.bv_val[dn.bv_len-2] == '\'' )
351 /* assume presence of optional UID */
354 for(i=dn.bv_len-3; i>1; i--) {
355 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
359 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
360 ber_memfree( dn.bv_val );
361 return LDAP_INVALID_SYNTAX;
364 /* trim the UID to allow use of dnValidate */
365 dn.bv_val[i-1] = '\0';
369 rc = dnValidate( NULL, &dn );
371 ber_memfree( dn.bv_val );
379 struct berval *normalized )
384 ber_dupbv( &out, val );
385 if( out.bv_len != 0 ) {
386 struct berval uidin = { 0, NULL };
387 struct berval uidout = { 0, NULL };
389 if( out.bv_val[out.bv_len-1] == 'B'
390 && out.bv_val[out.bv_len-2] == '\'' )
392 /* assume presence of optional UID */
393 uidin.bv_val = strrchr( out.bv_val, '#' );
395 if( uidin.bv_val == NULL ) {
397 return LDAP_INVALID_SYNTAX;
400 uidin.bv_len = out.bv_len - (uidin.bv_val - out.bv_val);
401 out.bv_len -= uidin.bv_len--;
403 /* temporarily trim the UID */
404 *(uidin.bv_val++) = '\0';
406 rc = bitStringNormalize( syntax, &uidin, &uidout );
408 if( rc != LDAP_SUCCESS ) {
410 return LDAP_INVALID_SYNTAX;
414 #ifdef USE_DN_NORMALIZE
415 rc = dnNormalize2( NULL, &out, normalized );
417 rc = dnPretty2( NULL, &out, normalized );
420 if( rc != LDAP_SUCCESS ) {
422 free( uidout.bv_val );
423 return LDAP_INVALID_SYNTAX;
426 if( uidout.bv_len ) {
427 normalized->bv_val = ch_realloc( normalized->bv_val,
428 normalized->bv_len + uidout.bv_len + sizeof("#") );
430 /* insert the separator */
431 normalized->bv_val[normalized->bv_len++] = '#';
434 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
435 uidout.bv_val, uidout.bv_len );
436 normalized->bv_len += uidout.bv_len;
439 normalized->bv_val[normalized->bv_len] = '\0';
449 * Handling boolean syntax and matching is quite rigid.
450 * A more flexible approach would be to allow a variety
451 * of strings to be normalized and prettied into TRUE
459 /* very unforgiving validation, requires no normalization
460 * before simplistic matching
463 if( in->bv_len == 4 ) {
464 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
467 } else if( in->bv_len == 5 ) {
468 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
473 return LDAP_INVALID_SYNTAX;
482 struct berval *value,
483 void *assertedValue )
485 /* simplistic matching allowed by rigid validation */
486 struct berval *asserted = (struct berval *) assertedValue;
487 *matchp = value->bv_len != asserted->bv_len;
498 unsigned char *u = in->bv_val;
500 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
502 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
503 /* get the length indicated by the first byte */
504 len = LDAP_UTF8_CHARLEN2( u, len );
506 /* very basic checks */
509 if( (u[5] & 0xC0) != 0x80 ) {
510 return LDAP_INVALID_SYNTAX;
513 if( (u[4] & 0xC0) != 0x80 ) {
514 return LDAP_INVALID_SYNTAX;
517 if( (u[3] & 0xC0) != 0x80 ) {
518 return LDAP_INVALID_SYNTAX;
521 if( (u[2] & 0xC0 )!= 0x80 ) {
522 return LDAP_INVALID_SYNTAX;
525 if( (u[1] & 0xC0) != 0x80 ) {
526 return LDAP_INVALID_SYNTAX;
529 /* CHARLEN already validated it */
532 return LDAP_INVALID_SYNTAX;
535 /* make sure len corresponds with the offset
536 to the next character */
537 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
540 if( count != 0 ) return LDAP_INVALID_SYNTAX;
549 struct berval *normalized )
556 /* Ignore initial whitespace */
557 /* All space is ASCII. All ASCII is 1 byte */
558 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
560 normalized->bv_len = val->bv_len - (p - val->bv_val);
561 ber_mem2bv( p, normalized->bv_len, 1, normalized );
562 e = normalized->bv_val + normalized->bv_len;
564 assert( normalized->bv_val );
566 p = q = normalized->bv_val;
571 if ( ASCII_SPACE( *p ) ) {
576 /* Ignore the extra whitespace */
577 while ( ASCII_SPACE( *p ) ) {
581 len = LDAP_UTF8_COPY(q,p);
587 assert( normalized->bv_val <= p );
588 assert( q+len <= p );
590 /* cannot start with a space */
591 assert( !ASCII_SPACE(normalized->bv_val[0]) );
594 * If the string ended in space, backup the pointer one
595 * position. One is enough because the above loop collapsed
596 * all whitespace to a single space.
604 /* cannot end with a space */
605 assert( !ASCII_SPACE( *q ) );
612 normalized->bv_len = q - normalized->bv_val;
617 /* Returns Unicode canonically normalized copy of a substring assertion
618 * Skipping attribute description */
619 static SubstringsAssertion *
620 UTF8SubstringsassertionNormalize(
621 SubstringsAssertion *sa,
624 SubstringsAssertion *nsa;
627 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
632 if( sa->sa_initial.bv_val != NULL ) {
633 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
634 if( nsa->sa_initial.bv_val == NULL ) {
639 if( sa->sa_any != NULL ) {
640 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
643 nsa->sa_any = (struct berval *)ch_malloc( (i + 1) * sizeof(struct berval) );
644 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
645 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
647 if( nsa->sa_any[i].bv_val == NULL ) {
651 nsa->sa_any[i].bv_val = NULL;
654 if( sa->sa_final.bv_val != NULL ) {
655 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
656 if( nsa->sa_final.bv_val == NULL ) {
664 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
665 if ( nsa->sa_any )ber_bvarray_free( nsa->sa_any );
666 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
671 #ifndef SLAPD_APPROX_OLDSINGLESTRING
673 #if defined(SLAPD_APPROX_INITIALS)
674 #define SLAPD_APPROX_DELIMITER "._ "
675 #define SLAPD_APPROX_WORDLEN 2
677 #define SLAPD_APPROX_DELIMITER " "
678 #define SLAPD_APPROX_WORDLEN 1
687 struct berval *value,
688 void *assertedValue )
690 struct berval *nval, *assertv;
691 char *val, **values, **words, *c;
692 int i, count, len, nextchunk=0, nextavail=0;
694 /* Yes, this is necessary */
695 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
701 /* Yes, this is necessary */
702 assertv = UTF8bvnormalize( ((struct berval *)assertedValue), NULL, LDAP_UTF8_APPROX );
703 if( assertv == NULL ) {
709 /* Isolate how many words there are */
710 for ( c = nval->bv_val, count = 1; *c; c++ ) {
711 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
712 if ( c == NULL ) break;
717 /* Get a phonetic copy of each word */
718 words = (char **)ch_malloc( count * sizeof(char *) );
719 values = (char **)ch_malloc( count * sizeof(char *) );
720 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
722 values[i] = phonetic(c);
725 /* Work through the asserted value's words, to see if at least some
726 of the words are there, in the same order. */
728 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
729 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
734 #if defined(SLAPD_APPROX_INITIALS)
735 else if( len == 1 ) {
736 /* Single letter words need to at least match one word's initial */
737 for( i=nextavail; i<count; i++ )
738 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
745 /* Isolate the next word in the asserted value and phonetic it */
746 assertv->bv_val[nextchunk+len] = '\0';
747 val = phonetic( assertv->bv_val + nextchunk );
749 /* See if this phonetic chunk is in the remaining words of *value */
750 for( i=nextavail; i<count; i++ ){
751 if( !strcmp( val, values[i] ) ){
759 /* This chunk in the asserted value was NOT within the *value. */
765 /* Go on to the next word in the asserted value */
769 /* If some of the words were seen, call it a match */
770 if( nextavail > 0 ) {
778 ber_bvfree( assertv );
779 for( i=0; i<count; i++ ) {
780 ch_free( values[i] );
795 struct berval *prefix,
800 int i,j, len, wordcount, keycount=0;
801 struct berval *newkeys;
804 for( j=0; values[j].bv_val != NULL; j++ ) {
805 struct berval val = { 0, NULL };
806 /* Yes, this is necessary */
807 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
808 assert( val.bv_val != NULL );
810 /* Isolate how many words there are. There will be a key for each */
811 for( wordcount = 0, c = val.bv_val; *c; c++) {
812 len = strcspn(c, SLAPD_APPROX_DELIMITER);
813 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
815 if (*c == '\0') break;
819 /* Allocate/increase storage to account for new keys */
820 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
821 * sizeof(struct berval) );
822 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
823 if( keys ) ch_free( keys );
826 /* Get a phonetic copy of each word */
827 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
829 if( len < SLAPD_APPROX_WORDLEN ) continue;
830 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
835 ber_memfree( val.bv_val );
837 keys[keycount].bv_val = NULL;
849 struct berval *prefix,
858 /* Yes, this is necessary */
859 val = UTF8bvnormalize( ((struct berval *)assertValue), NULL, LDAP_UTF8_APPROX );
860 if( val == NULL || val->bv_val == NULL ) {
861 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
862 keys[0].bv_val = NULL;
868 /* Isolate how many words there are. There will be a key for each */
869 for( count = 0,c = val->bv_val; *c; c++) {
870 len = strcspn(c, SLAPD_APPROX_DELIMITER);
871 if( len >= SLAPD_APPROX_WORDLEN ) count++;
873 if (*c == '\0') break;
877 /* Allocate storage for new keys */
878 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
880 /* Get a phonetic copy of each word */
881 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
883 if( len < SLAPD_APPROX_WORDLEN ) continue;
884 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
890 keys[count].bv_val = NULL;
898 /* No other form of Approximate Matching is defined */
906 struct berval *value,
907 void *assertedValue )
909 char *vapprox, *avapprox;
912 /* Yes, this is necessary */
913 s = UTF8normalize( value, UTF8_NOCASEFOLD );
919 /* Yes, this is necessary */
920 t = UTF8normalize( ((struct berval *)assertedValue),
928 vapprox = phonetic( strip8bitChars( s ) );
929 avapprox = phonetic( strip8bitChars( t ) );
934 *matchp = strcmp( vapprox, avapprox );
948 struct berval *prefix,
956 for( i=0; values[i].bv_val != NULL; i++ ) {
957 /* empty - just count them */
960 /* we should have at least one value at this point */
963 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
965 /* Copy each value and run it through phonetic() */
966 for( i=0; values[i].bv_val != NULL; i++ ) {
967 /* Yes, this is necessary */
968 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
970 /* strip 8-bit chars and run through phonetic() */
971 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
974 keys[i].bv_val = NULL;
987 struct berval *prefix,
994 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
996 /* Yes, this is necessary */
997 s = UTF8normalize( ((struct berval *)assertValue),
1002 /* strip 8-bit chars and run through phonetic() */
1003 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1009 return LDAP_SUCCESS;
1020 struct berval *value,
1021 void *assertedValue )
1023 *matchp = UTF8bvnormcmp( value,
1024 (struct berval *) assertedValue,
1025 LDAP_UTF8_NOCASEFOLD );
1026 return LDAP_SUCCESS;
1030 caseExactIgnoreSubstringsMatch(
1035 struct berval *value,
1036 void *assertedValue )
1039 SubstringsAssertion *sub = NULL;
1040 struct berval left = { 0, NULL };
1046 casefold = ( mr != caseExactSubstringsMatchingRule )
1047 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1049 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1055 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1061 /* Add up asserted input length */
1062 if( sub->sa_initial.bv_val ) {
1063 inlen += sub->sa_initial.bv_len;
1066 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1067 inlen += sub->sa_any[i].bv_len;
1070 if( sub->sa_final.bv_val ) {
1071 inlen += sub->sa_final.bv_len;
1074 if( sub->sa_initial.bv_val ) {
1075 if( inlen > left.bv_len ) {
1080 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1081 sub->sa_initial.bv_len );
1087 left.bv_val += sub->sa_initial.bv_len;
1088 left.bv_len -= sub->sa_initial.bv_len;
1089 inlen -= sub->sa_initial.bv_len;
1092 if( sub->sa_final.bv_val ) {
1093 if( inlen > left.bv_len ) {
1098 match = memcmp( sub->sa_final.bv_val,
1099 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1100 sub->sa_final.bv_len );
1106 left.bv_len -= sub->sa_final.bv_len;
1107 inlen -= sub->sa_final.bv_len;
1111 for(i=0; sub->sa_any[i].bv_val; i++) {
1116 if( inlen > left.bv_len ) {
1117 /* not enough length */
1122 if( sub->sa_any[i].bv_len == 0 ) {
1126 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1132 idx = p - left.bv_val;
1134 if( idx >= left.bv_len ) {
1135 /* this shouldn't happen */
1137 if ( sub->sa_final.bv_val )
1138 ch_free( sub->sa_final.bv_val );
1140 ber_bvarray_free( sub->sa_any );
1141 if ( sub->sa_initial.bv_val )
1142 ch_free( sub->sa_initial.bv_val );
1150 if( sub->sa_any[i].bv_len > left.bv_len ) {
1151 /* not enough left */
1156 match = memcmp( left.bv_val,
1157 sub->sa_any[i].bv_val,
1158 sub->sa_any[i].bv_len );
1166 left.bv_val += sub->sa_any[i].bv_len;
1167 left.bv_len -= sub->sa_any[i].bv_len;
1168 inlen -= sub->sa_any[i].bv_len;
1175 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1176 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1177 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1181 return LDAP_SUCCESS;
1184 /* Index generation function */
1185 static int caseExactIgnoreIndexer(
1190 struct berval *prefix,
1198 HASH_CONTEXT HASHcontext;
1199 unsigned char HASHdigest[HASH_BYTES];
1200 struct berval digest;
1201 digest.bv_val = HASHdigest;
1202 digest.bv_len = sizeof(HASHdigest);
1204 for( i=0; values[i].bv_val != NULL; i++ ) {
1205 /* empty - just count them */
1208 /* we should have at least one value at this point */
1211 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1213 slen = syntax->ssyn_oidlen;
1214 mlen = mr->smr_oidlen;
1216 casefold = ( mr != caseExactMatchingRule )
1217 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1219 for( i=0; values[i].bv_val != NULL; i++ ) {
1220 struct berval value;
1221 UTF8bvnormalize( &values[i], &value, casefold );
1223 HASH_Init( &HASHcontext );
1224 if( prefix != NULL && prefix->bv_len > 0 ) {
1225 HASH_Update( &HASHcontext,
1226 prefix->bv_val, prefix->bv_len );
1228 HASH_Update( &HASHcontext,
1229 syntax->ssyn_oid, slen );
1230 HASH_Update( &HASHcontext,
1231 mr->smr_oid, mlen );
1232 HASH_Update( &HASHcontext,
1233 value.bv_val, value.bv_len );
1234 HASH_Final( HASHdigest, &HASHcontext );
1236 free( value.bv_val );
1238 ber_dupbv( &keys[i], &digest );
1241 keys[i].bv_val = NULL;
1243 return LDAP_SUCCESS;
1246 /* Index generation function */
1247 static int caseExactIgnoreFilter(
1252 struct berval *prefix,
1259 HASH_CONTEXT HASHcontext;
1260 unsigned char HASHdigest[HASH_BYTES];
1261 struct berval value = { 0, NULL };
1262 struct berval digest;
1264 digest.bv_val = HASHdigest;
1265 digest.bv_len = sizeof(HASHdigest);
1267 slen = syntax->ssyn_oidlen;
1268 mlen = mr->smr_oidlen;
1270 casefold = ( mr != caseExactMatchingRule )
1271 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1273 UTF8bvnormalize( (struct berval *) assertValue, &value, casefold );
1274 /* This usually happens if filter contains bad UTF8 */
1275 if( value.bv_val == NULL ) {
1276 keys = ch_malloc( sizeof( struct berval ) );
1277 keys[0].bv_val = NULL;
1278 return LDAP_SUCCESS;
1281 keys = ch_malloc( sizeof( struct berval ) * 2 );
1283 HASH_Init( &HASHcontext );
1284 if( prefix != NULL && prefix->bv_len > 0 ) {
1285 HASH_Update( &HASHcontext,
1286 prefix->bv_val, prefix->bv_len );
1288 HASH_Update( &HASHcontext,
1289 syntax->ssyn_oid, slen );
1290 HASH_Update( &HASHcontext,
1291 mr->smr_oid, mlen );
1292 HASH_Update( &HASHcontext,
1293 value.bv_val, value.bv_len );
1294 HASH_Final( HASHdigest, &HASHcontext );
1296 ber_dupbv( keys, &digest );
1297 keys[1].bv_val = NULL;
1299 free( value.bv_val );
1302 return LDAP_SUCCESS;
1305 /* Substrings Index generation function */
1306 static int caseExactIgnoreSubstringsIndexer(
1311 struct berval *prefix,
1321 HASH_CONTEXT HASHcontext;
1322 unsigned char HASHdigest[HASH_BYTES];
1323 struct berval digest;
1324 digest.bv_val = HASHdigest;
1325 digest.bv_len = sizeof(HASHdigest);
1329 for( i=0; values[i].bv_val != NULL; i++ ) {
1330 /* empty - just count them */
1333 /* we should have at least one value at this point */
1336 casefold = ( mr != caseExactSubstringsMatchingRule )
1337 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1339 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1340 for( i=0; values[i].bv_val != NULL; i++ ) {
1341 UTF8bvnormalize( &values[i], &nvalues[i], casefold );
1343 nvalues[i].bv_val = NULL;
1346 for( i=0; values[i].bv_val != NULL; i++ ) {
1347 /* count number of indices to generate */
1348 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1352 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1353 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1354 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1355 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1357 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1361 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1362 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1363 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1367 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1368 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1369 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1370 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1372 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1378 /* no keys to generate */
1380 ber_bvarray_free( nvalues );
1381 return LDAP_SUCCESS;
1384 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1386 slen = syntax->ssyn_oidlen;
1387 mlen = mr->smr_oidlen;
1390 for( i=0; values[i].bv_val != NULL; i++ ) {
1393 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1395 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1396 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1398 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1399 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1401 for( j=0; j<max; j++ ) {
1402 HASH_Init( &HASHcontext );
1403 if( prefix != NULL && prefix->bv_len > 0 ) {
1404 HASH_Update( &HASHcontext,
1405 prefix->bv_val, prefix->bv_len );
1408 HASH_Update( &HASHcontext,
1409 &pre, sizeof( pre ) );
1410 HASH_Update( &HASHcontext,
1411 syntax->ssyn_oid, slen );
1412 HASH_Update( &HASHcontext,
1413 mr->smr_oid, mlen );
1414 HASH_Update( &HASHcontext,
1415 &values[i].bv_val[j],
1416 SLAP_INDEX_SUBSTR_MAXLEN );
1417 HASH_Final( HASHdigest, &HASHcontext );
1419 ber_dupbv( &keys[nkeys++], &digest );
1423 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1424 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1426 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1429 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1430 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1431 HASH_Init( &HASHcontext );
1432 if( prefix != NULL && prefix->bv_len > 0 ) {
1433 HASH_Update( &HASHcontext,
1434 prefix->bv_val, prefix->bv_len );
1436 HASH_Update( &HASHcontext,
1437 &pre, sizeof( pre ) );
1438 HASH_Update( &HASHcontext,
1439 syntax->ssyn_oid, slen );
1440 HASH_Update( &HASHcontext,
1441 mr->smr_oid, mlen );
1442 HASH_Update( &HASHcontext,
1443 values[i].bv_val, j );
1444 HASH_Final( HASHdigest, &HASHcontext );
1446 ber_dupbv( &keys[nkeys++], &digest );
1449 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1450 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1451 HASH_Init( &HASHcontext );
1452 if( prefix != NULL && prefix->bv_len > 0 ) {
1453 HASH_Update( &HASHcontext,
1454 prefix->bv_val, prefix->bv_len );
1456 HASH_Update( &HASHcontext,
1457 &pre, sizeof( pre ) );
1458 HASH_Update( &HASHcontext,
1459 syntax->ssyn_oid, slen );
1460 HASH_Update( &HASHcontext,
1461 mr->smr_oid, mlen );
1462 HASH_Update( &HASHcontext,
1463 &values[i].bv_val[values[i].bv_len-j], j );
1464 HASH_Final( HASHdigest, &HASHcontext );
1466 ber_dupbv( &keys[nkeys++], &digest );
1474 keys[nkeys].bv_val = NULL;
1481 ber_bvarray_free( nvalues );
1483 return LDAP_SUCCESS;
1486 static int caseExactIgnoreSubstringsFilter(
1491 struct berval *prefix,
1495 SubstringsAssertion *sa;
1498 ber_len_t nkeys = 0;
1499 size_t slen, mlen, klen;
1501 HASH_CONTEXT HASHcontext;
1502 unsigned char HASHdigest[HASH_BYTES];
1503 struct berval *value;
1504 struct berval digest;
1506 casefold = ( mr != caseExactSubstringsMatchingRule )
1507 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1509 sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
1512 return LDAP_SUCCESS;
1515 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1516 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1521 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1523 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1524 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1525 /* don't bother accounting for stepping */
1526 nkeys += sa->sa_any[i].bv_len -
1527 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1532 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1533 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1539 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1540 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1541 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1544 return LDAP_SUCCESS;
1547 digest.bv_val = HASHdigest;
1548 digest.bv_len = sizeof(HASHdigest);
1550 slen = syntax->ssyn_oidlen;
1551 mlen = mr->smr_oidlen;
1553 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1556 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1557 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1559 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1560 value = &sa->sa_initial;
1562 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1563 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1565 HASH_Init( &HASHcontext );
1566 if( prefix != NULL && prefix->bv_len > 0 ) {
1567 HASH_Update( &HASHcontext,
1568 prefix->bv_val, prefix->bv_len );
1570 HASH_Update( &HASHcontext,
1571 &pre, sizeof( pre ) );
1572 HASH_Update( &HASHcontext,
1573 syntax->ssyn_oid, slen );
1574 HASH_Update( &HASHcontext,
1575 mr->smr_oid, mlen );
1576 HASH_Update( &HASHcontext,
1577 value->bv_val, klen );
1578 HASH_Final( HASHdigest, &HASHcontext );
1580 ber_dupbv( &keys[nkeys++], &digest );
1583 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1585 pre = SLAP_INDEX_SUBSTR_PREFIX;
1586 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1588 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1589 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1593 value = &sa->sa_any[i];
1596 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1597 j += SLAP_INDEX_SUBSTR_STEP )
1599 HASH_Init( &HASHcontext );
1600 if( prefix != NULL && prefix->bv_len > 0 ) {
1601 HASH_Update( &HASHcontext,
1602 prefix->bv_val, prefix->bv_len );
1604 HASH_Update( &HASHcontext,
1605 &pre, sizeof( pre ) );
1606 HASH_Update( &HASHcontext,
1607 syntax->ssyn_oid, slen );
1608 HASH_Update( &HASHcontext,
1609 mr->smr_oid, mlen );
1610 HASH_Update( &HASHcontext,
1611 &value->bv_val[j], klen );
1612 HASH_Final( HASHdigest, &HASHcontext );
1614 ber_dupbv( &keys[nkeys++], &digest );
1620 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1621 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1623 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1624 value = &sa->sa_final;
1626 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1627 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1629 HASH_Init( &HASHcontext );
1630 if( prefix != NULL && prefix->bv_len > 0 ) {
1631 HASH_Update( &HASHcontext,
1632 prefix->bv_val, prefix->bv_len );
1634 HASH_Update( &HASHcontext,
1635 &pre, sizeof( pre ) );
1636 HASH_Update( &HASHcontext,
1637 syntax->ssyn_oid, slen );
1638 HASH_Update( &HASHcontext,
1639 mr->smr_oid, mlen );
1640 HASH_Update( &HASHcontext,
1641 &value->bv_val[value->bv_len-klen], klen );
1642 HASH_Final( HASHdigest, &HASHcontext );
1644 ber_dupbv( &keys[nkeys++], &digest );
1648 keys[nkeys].bv_val = NULL;
1654 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1655 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1656 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1659 return LDAP_SUCCESS;
1668 struct berval *value,
1669 void *assertedValue )
1671 *matchp = UTF8bvnormcmp( value,
1672 (struct berval *) assertedValue,
1673 LDAP_UTF8_CASEFOLD );
1674 return LDAP_SUCCESS;
1677 /* Remove all spaces and '-' characters */
1679 telephoneNumberNormalize(
1682 struct berval *normalized )
1686 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
1688 for( p = val->bv_val; *p; p++ )
1689 if ( ! ( ASCII_SPACE( *p ) || *p == '-' ))
1693 normalized->bv_len = q - normalized->bv_val;
1695 return LDAP_SUCCESS;
1701 struct berval *val )
1705 if( val->bv_len == 0 ) {
1706 /* disallow empty strings */
1707 return LDAP_INVALID_SYNTAX;
1710 if( OID_LEADCHAR(val->bv_val[0]) ) {
1712 for(i=1; i < val->bv_len; i++) {
1713 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1714 if( dot++ ) return 1;
1715 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1718 return LDAP_INVALID_SYNTAX;
1722 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1724 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1725 for(i=1; i < val->bv_len; i++) {
1726 if( !DESC_CHAR(val->bv_val[i] ) ) {
1727 return LDAP_INVALID_SYNTAX;
1731 return LDAP_SUCCESS;
1734 return LDAP_INVALID_SYNTAX;
1743 struct berval *value,
1744 void *assertedValue )
1747 int vsign = 1, avsign = 1; /* default sign = '+' */
1748 struct berval *asserted;
1749 ber_len_t vlen, avlen;
1752 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
1754 vlen = value->bv_len;
1755 if( mr == integerFirstComponentMatchingRule ) {
1756 char *tmp = memchr( v, '$', vlen );
1759 while( vlen && ASCII_SPACE( v[vlen-1] ))
1762 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
1768 /* Do the same with the *assertedValue number */
1769 asserted = (struct berval *) assertedValue;
1770 av = asserted->bv_val;
1771 avlen = asserted->bv_len;
1772 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
1778 match = vsign - avsign;
1780 match = (vlen != avlen
1781 ? ( vlen < avlen ? -1 : 1 )
1782 : memcmp( v, av, vlen ));
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 + 1 );
1858 normalized->bv_val[0] = '-';
1860 AC_MEMCPY( normalized->bv_val + negative, p, len );
1861 normalized->bv_val[len+negative] = '\0';
1864 return LDAP_SUCCESS;
1867 /* Index generation function */
1868 static int integerIndexer(
1873 struct berval *prefix,
1880 HASH_CONTEXT HASHcontext;
1881 unsigned char HASHdigest[HASH_BYTES];
1882 struct berval digest;
1883 digest.bv_val = HASHdigest;
1884 digest.bv_len = sizeof(HASHdigest);
1886 for( i=0; values[i].bv_val != NULL; i++ ) {
1887 /* empty - just count them */
1890 /* we should have at least one value at this point */
1893 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1895 slen = syntax->ssyn_oidlen;
1896 mlen = mr->smr_oidlen;
1898 for( i=0; values[i].bv_val != NULL; i++ ) {
1900 integerNormalize( syntax, &values[i], &norm );
1902 HASH_Init( &HASHcontext );
1903 if( prefix != NULL && prefix->bv_len > 0 ) {
1904 HASH_Update( &HASHcontext,
1905 prefix->bv_val, prefix->bv_len );
1907 HASH_Update( &HASHcontext,
1908 syntax->ssyn_oid, slen );
1909 HASH_Update( &HASHcontext,
1910 mr->smr_oid, mlen );
1911 HASH_Update( &HASHcontext,
1912 norm.bv_val, norm.bv_len );
1913 HASH_Final( HASHdigest, &HASHcontext );
1915 ber_dupbv( &keys[i], &digest );
1916 ch_free( norm.bv_val );
1919 keys[i].bv_val = NULL;
1921 return LDAP_SUCCESS;
1924 /* Index generation function */
1925 static int integerFilter(
1930 struct berval *prefix,
1936 HASH_CONTEXT HASHcontext;
1937 unsigned char HASHdigest[HASH_BYTES];
1939 struct berval digest;
1940 digest.bv_val = HASHdigest;
1941 digest.bv_len = sizeof(HASHdigest);
1943 slen = syntax->ssyn_oidlen;
1944 mlen = mr->smr_oidlen;
1946 integerNormalize( syntax, assertValue, &norm );
1948 keys = ch_malloc( sizeof( struct berval ) * 2 );
1950 HASH_Init( &HASHcontext );
1951 if( prefix != NULL && prefix->bv_len > 0 ) {
1952 HASH_Update( &HASHcontext,
1953 prefix->bv_val, prefix->bv_len );
1955 HASH_Update( &HASHcontext,
1956 syntax->ssyn_oid, slen );
1957 HASH_Update( &HASHcontext,
1958 mr->smr_oid, mlen );
1959 HASH_Update( &HASHcontext,
1960 norm.bv_val, norm.bv_len );
1961 HASH_Final( HASHdigest, &HASHcontext );
1963 ber_dupbv( &keys[0], &digest );
1964 keys[1].bv_val = NULL;
1965 ch_free( norm.bv_val );
1968 return LDAP_SUCCESS;
1973 countryStringValidate(
1975 struct berval *val )
1977 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
1979 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
1980 return LDAP_INVALID_SYNTAX;
1982 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
1983 return LDAP_INVALID_SYNTAX;
1986 return LDAP_SUCCESS;
1990 printableStringValidate(
1992 struct berval *val )
1996 for(i=0; i < val->bv_len; i++) {
1997 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
1998 return LDAP_INVALID_SYNTAX;
2002 return LDAP_SUCCESS;
2006 printablesStringValidate(
2008 struct berval *val )
2012 for(i=0; i < val->bv_len; i++) {
2013 if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
2014 return LDAP_INVALID_SYNTAX;
2018 return LDAP_SUCCESS;
2024 struct berval *val )
2028 for(i=0; i < val->bv_len; i++) {
2029 if( !LDAP_ASCII(val->bv_val[i]) ) {
2030 return LDAP_INVALID_SYNTAX;
2034 return LDAP_SUCCESS;
2041 struct berval *normalized )
2047 /* Ignore initial whitespace */
2048 while ( ASCII_SPACE( *p ) ) {
2052 normalized->bv_val = ch_strdup( p );
2053 p = q = normalized->bv_val;
2056 if ( ASCII_SPACE( *p ) ) {
2059 /* Ignore the extra whitespace */
2060 while ( ASCII_SPACE( *p ) ) {
2068 assert( normalized->bv_val <= p );
2072 * If the string ended in space, backup the pointer one
2073 * position. One is enough because the above loop collapsed
2074 * all whitespace to a single space.
2077 if ( ASCII_SPACE( q[-1] ) ) {
2081 /* null terminate */
2084 normalized->bv_len = q - normalized->bv_val;
2086 return LDAP_SUCCESS;
2095 struct berval *value,
2096 void *assertedValue )
2098 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2101 match = strncmp( value->bv_val,
2102 ((struct berval *) assertedValue)->bv_val,
2107 return LDAP_SUCCESS;
2111 caseExactIA5SubstringsMatch(
2116 struct berval *value,
2117 void *assertedValue )
2120 SubstringsAssertion *sub = assertedValue;
2121 struct berval left = *value;
2125 /* Add up asserted input length */
2126 if( sub->sa_initial.bv_val ) {
2127 inlen += sub->sa_initial.bv_len;
2130 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2131 inlen += sub->sa_any[i].bv_len;
2134 if( sub->sa_final.bv_val ) {
2135 inlen += sub->sa_final.bv_len;
2138 if( sub->sa_initial.bv_val ) {
2139 if( inlen > left.bv_len ) {
2144 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
2145 sub->sa_initial.bv_len );
2151 left.bv_val += sub->sa_initial.bv_len;
2152 left.bv_len -= sub->sa_initial.bv_len;
2153 inlen -= sub->sa_initial.bv_len;
2156 if( sub->sa_final.bv_val ) {
2157 if( inlen > left.bv_len ) {
2162 match = strncmp( sub->sa_final.bv_val,
2163 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2164 sub->sa_final.bv_len );
2170 left.bv_len -= sub->sa_final.bv_len;
2171 inlen -= sub->sa_final.bv_len;
2175 for(i=0; sub->sa_any[i].bv_val; i++) {
2180 if( inlen > left.bv_len ) {
2181 /* not enough length */
2186 if( sub->sa_any[i].bv_len == 0 ) {
2190 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
2197 idx = p - left.bv_val;
2199 if( idx >= left.bv_len ) {
2200 /* this shouldn't happen */
2207 if( sub->sa_any[i].bv_len > left.bv_len ) {
2208 /* not enough left */
2213 match = strncmp( left.bv_val,
2214 sub->sa_any[i].bv_val,
2215 sub->sa_any[i].bv_len );
2223 left.bv_val += sub->sa_any[i].bv_len;
2224 left.bv_len -= sub->sa_any[i].bv_len;
2225 inlen -= sub->sa_any[i].bv_len;
2231 return LDAP_SUCCESS;
2234 /* Index generation function */
2235 static int caseExactIA5Indexer(
2240 struct berval *prefix,
2247 HASH_CONTEXT HASHcontext;
2248 unsigned char HASHdigest[HASH_BYTES];
2249 struct berval digest;
2250 digest.bv_val = HASHdigest;
2251 digest.bv_len = sizeof(HASHdigest);
2253 for( i=0; values[i].bv_val != NULL; i++ ) {
2254 /* empty - just count them */
2257 /* we should have at least one value at this point */
2260 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2262 slen = syntax->ssyn_oidlen;
2263 mlen = mr->smr_oidlen;
2265 for( i=0; values[i].bv_val != NULL; i++ ) {
2266 struct berval *value = &values[i];
2268 HASH_Init( &HASHcontext );
2269 if( prefix != NULL && prefix->bv_len > 0 ) {
2270 HASH_Update( &HASHcontext,
2271 prefix->bv_val, prefix->bv_len );
2273 HASH_Update( &HASHcontext,
2274 syntax->ssyn_oid, slen );
2275 HASH_Update( &HASHcontext,
2276 mr->smr_oid, mlen );
2277 HASH_Update( &HASHcontext,
2278 value->bv_val, value->bv_len );
2279 HASH_Final( HASHdigest, &HASHcontext );
2281 ber_dupbv( &keys[i], &digest );
2284 keys[i].bv_val = NULL;
2286 return LDAP_SUCCESS;
2289 /* Index generation function */
2290 static int caseExactIA5Filter(
2295 struct berval *prefix,
2301 HASH_CONTEXT HASHcontext;
2302 unsigned char HASHdigest[HASH_BYTES];
2303 struct berval *value;
2304 struct berval digest;
2305 digest.bv_val = HASHdigest;
2306 digest.bv_len = sizeof(HASHdigest);
2308 slen = syntax->ssyn_oidlen;
2309 mlen = mr->smr_oidlen;
2311 value = (struct berval *) assertValue;
2313 keys = ch_malloc( sizeof( struct berval ) * 2 );
2315 HASH_Init( &HASHcontext );
2316 if( prefix != NULL && prefix->bv_len > 0 ) {
2317 HASH_Update( &HASHcontext,
2318 prefix->bv_val, prefix->bv_len );
2320 HASH_Update( &HASHcontext,
2321 syntax->ssyn_oid, slen );
2322 HASH_Update( &HASHcontext,
2323 mr->smr_oid, mlen );
2324 HASH_Update( &HASHcontext,
2325 value->bv_val, value->bv_len );
2326 HASH_Final( HASHdigest, &HASHcontext );
2328 ber_dupbv( &keys[0], &digest );
2329 keys[1].bv_val = NULL;
2332 return LDAP_SUCCESS;
2335 /* Substrings Index generation function */
2336 static int caseExactIA5SubstringsIndexer(
2341 struct berval *prefix,
2348 HASH_CONTEXT HASHcontext;
2349 unsigned char HASHdigest[HASH_BYTES];
2350 struct berval digest;
2351 digest.bv_val = HASHdigest;
2352 digest.bv_len = sizeof(HASHdigest);
2354 /* we should have at least one value at this point */
2355 assert( values != NULL && values[0].bv_val != NULL );
2358 for( i=0; values[i].bv_val != NULL; i++ ) {
2359 /* count number of indices to generate */
2360 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2364 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2365 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2366 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2367 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2369 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2373 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2374 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2375 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2379 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2380 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2381 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2382 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2384 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2390 /* no keys to generate */
2392 return LDAP_SUCCESS;
2395 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2397 slen = syntax->ssyn_oidlen;
2398 mlen = mr->smr_oidlen;
2401 for( i=0; values[i].bv_val != NULL; i++ ) {
2403 struct berval *value;
2406 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2408 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2409 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2411 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2412 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2414 for( j=0; j<max; j++ ) {
2415 HASH_Init( &HASHcontext );
2416 if( prefix != NULL && prefix->bv_len > 0 ) {
2417 HASH_Update( &HASHcontext,
2418 prefix->bv_val, prefix->bv_len );
2421 HASH_Update( &HASHcontext,
2422 &pre, sizeof( pre ) );
2423 HASH_Update( &HASHcontext,
2424 syntax->ssyn_oid, slen );
2425 HASH_Update( &HASHcontext,
2426 mr->smr_oid, mlen );
2427 HASH_Update( &HASHcontext,
2429 SLAP_INDEX_SUBSTR_MAXLEN );
2430 HASH_Final( HASHdigest, &HASHcontext );
2432 ber_dupbv( &keys[nkeys++], &digest );
2436 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2437 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2439 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2442 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2443 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2444 HASH_Init( &HASHcontext );
2445 if( prefix != NULL && prefix->bv_len > 0 ) {
2446 HASH_Update( &HASHcontext,
2447 prefix->bv_val, prefix->bv_len );
2449 HASH_Update( &HASHcontext,
2450 &pre, sizeof( pre ) );
2451 HASH_Update( &HASHcontext,
2452 syntax->ssyn_oid, slen );
2453 HASH_Update( &HASHcontext,
2454 mr->smr_oid, mlen );
2455 HASH_Update( &HASHcontext,
2457 HASH_Final( HASHdigest, &HASHcontext );
2459 ber_dupbv( &keys[nkeys++], &digest );
2462 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2463 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2464 HASH_Init( &HASHcontext );
2465 if( prefix != NULL && prefix->bv_len > 0 ) {
2466 HASH_Update( &HASHcontext,
2467 prefix->bv_val, prefix->bv_len );
2469 HASH_Update( &HASHcontext,
2470 &pre, sizeof( pre ) );
2471 HASH_Update( &HASHcontext,
2472 syntax->ssyn_oid, slen );
2473 HASH_Update( &HASHcontext,
2474 mr->smr_oid, mlen );
2475 HASH_Update( &HASHcontext,
2476 &value->bv_val[value->bv_len-j], j );
2477 HASH_Final( HASHdigest, &HASHcontext );
2479 ber_dupbv( &keys[nkeys++], &digest );
2486 keys[nkeys].bv_val = NULL;
2493 return LDAP_SUCCESS;
2496 static int caseExactIA5SubstringsFilter(
2501 struct berval *prefix,
2505 SubstringsAssertion *sa = assertValue;
2507 ber_len_t nkeys = 0;
2508 size_t slen, mlen, klen;
2510 HASH_CONTEXT HASHcontext;
2511 unsigned char HASHdigest[HASH_BYTES];
2512 struct berval *value;
2513 struct berval digest;
2515 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2516 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2521 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2523 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2524 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2525 /* don't bother accounting for stepping */
2526 nkeys += sa->sa_any[i].bv_len -
2527 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2532 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2533 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2540 return LDAP_SUCCESS;
2543 digest.bv_val = HASHdigest;
2544 digest.bv_len = sizeof(HASHdigest);
2546 slen = syntax->ssyn_oidlen;
2547 mlen = mr->smr_oidlen;
2549 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2552 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2553 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2555 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2556 value = &sa->sa_initial;
2558 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2559 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2561 HASH_Init( &HASHcontext );
2562 if( prefix != NULL && prefix->bv_len > 0 ) {
2563 HASH_Update( &HASHcontext,
2564 prefix->bv_val, prefix->bv_len );
2566 HASH_Update( &HASHcontext,
2567 &pre, sizeof( pre ) );
2568 HASH_Update( &HASHcontext,
2569 syntax->ssyn_oid, slen );
2570 HASH_Update( &HASHcontext,
2571 mr->smr_oid, mlen );
2572 HASH_Update( &HASHcontext,
2573 value->bv_val, klen );
2574 HASH_Final( HASHdigest, &HASHcontext );
2576 ber_dupbv( &keys[nkeys++], &digest );
2579 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2581 pre = SLAP_INDEX_SUBSTR_PREFIX;
2582 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2584 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2585 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2589 value = &sa->sa_any[i];
2592 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2593 j += SLAP_INDEX_SUBSTR_STEP )
2595 HASH_Init( &HASHcontext );
2596 if( prefix != NULL && prefix->bv_len > 0 ) {
2597 HASH_Update( &HASHcontext,
2598 prefix->bv_val, prefix->bv_len );
2600 HASH_Update( &HASHcontext,
2601 &pre, sizeof( pre ) );
2602 HASH_Update( &HASHcontext,
2603 syntax->ssyn_oid, slen );
2604 HASH_Update( &HASHcontext,
2605 mr->smr_oid, mlen );
2606 HASH_Update( &HASHcontext,
2607 &value->bv_val[j], klen );
2608 HASH_Final( HASHdigest, &HASHcontext );
2610 ber_dupbv( &keys[nkeys++], &digest );
2615 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2616 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2618 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2619 value = &sa->sa_final;
2621 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2622 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2624 HASH_Init( &HASHcontext );
2625 if( prefix != NULL && prefix->bv_len > 0 ) {
2626 HASH_Update( &HASHcontext,
2627 prefix->bv_val, prefix->bv_len );
2629 HASH_Update( &HASHcontext,
2630 &pre, sizeof( pre ) );
2631 HASH_Update( &HASHcontext,
2632 syntax->ssyn_oid, slen );
2633 HASH_Update( &HASHcontext,
2634 mr->smr_oid, mlen );
2635 HASH_Update( &HASHcontext,
2636 &value->bv_val[value->bv_len-klen], klen );
2637 HASH_Final( HASHdigest, &HASHcontext );
2639 ber_dupbv( &keys[nkeys++], &digest );
2643 keys[nkeys].bv_val = NULL;
2650 return LDAP_SUCCESS;
2659 struct berval *value,
2660 void *assertedValue )
2662 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2664 if( match == 0 && value->bv_len ) {
2665 match = strncasecmp( value->bv_val,
2666 ((struct berval *) assertedValue)->bv_val,
2671 return LDAP_SUCCESS;
2675 caseIgnoreIA5SubstringsMatch(
2680 struct berval *value,
2681 void *assertedValue )
2684 SubstringsAssertion *sub = assertedValue;
2685 struct berval left = *value;
2689 /* Add up asserted input length */
2690 if( sub->sa_initial.bv_val ) {
2691 inlen += sub->sa_initial.bv_len;
2694 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2695 inlen += sub->sa_any[i].bv_len;
2698 if( sub->sa_final.bv_val ) {
2699 inlen += sub->sa_final.bv_len;
2702 if( sub->sa_initial.bv_val ) {
2703 if( inlen > left.bv_len ) {
2708 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
2709 sub->sa_initial.bv_len );
2715 left.bv_val += sub->sa_initial.bv_len;
2716 left.bv_len -= sub->sa_initial.bv_len;
2717 inlen -= sub->sa_initial.bv_len;
2720 if( sub->sa_final.bv_val ) {
2721 if( inlen > left.bv_len ) {
2726 match = strncasecmp( sub->sa_final.bv_val,
2727 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2728 sub->sa_final.bv_len );
2734 left.bv_len -= sub->sa_final.bv_len;
2735 inlen -= sub->sa_final.bv_len;
2739 for(i=0; sub->sa_any[i].bv_val; i++) {
2744 if( inlen > left.bv_len ) {
2745 /* not enough length */
2750 if( sub->sa_any[i].bv_len == 0 ) {
2754 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
2761 assert( idx < left.bv_len );
2762 if( idx >= left.bv_len ) {
2763 /* this shouldn't happen */
2770 if( sub->sa_any[i].bv_len > left.bv_len ) {
2771 /* not enough left */
2776 match = strncasecmp( left.bv_val,
2777 sub->sa_any[i].bv_val,
2778 sub->sa_any[i].bv_len );
2787 left.bv_val += sub->sa_any[i].bv_len;
2788 left.bv_len -= sub->sa_any[i].bv_len;
2789 inlen -= sub->sa_any[i].bv_len;
2795 return LDAP_SUCCESS;
2798 /* Index generation function */
2799 static int caseIgnoreIA5Indexer(
2804 struct berval *prefix,
2809 int rc = LDAP_SUCCESS;
2812 HASH_CONTEXT HASHcontext;
2813 unsigned char HASHdigest[HASH_BYTES];
2814 struct berval digest;
2815 digest.bv_val = HASHdigest;
2816 digest.bv_len = sizeof(HASHdigest);
2818 /* we should have at least one value at this point */
2819 assert( values != NULL && values[0].bv_val != NULL );
2821 for( i=0; values[i].bv_val != NULL; i++ ) {
2822 /* just count them */
2825 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2827 slen = syntax->ssyn_oidlen;
2828 mlen = mr->smr_oidlen;
2830 for( i=0; values[i].bv_val != NULL; i++ ) {
2831 struct berval value;
2833 if( mr->smr_normalize ) {
2834 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
2835 if( rc != LDAP_SUCCESS ) {
2838 } else if ( mr->smr_syntax->ssyn_normalize ) {
2839 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
2840 if( rc != LDAP_SUCCESS ) {
2844 ber_dupbv( &value, &values[i] );
2847 ldap_pvt_str2lower( value.bv_val );
2849 HASH_Init( &HASHcontext );
2850 if( prefix != NULL && prefix->bv_len > 0 ) {
2851 HASH_Update( &HASHcontext,
2852 prefix->bv_val, prefix->bv_len );
2854 HASH_Update( &HASHcontext,
2855 syntax->ssyn_oid, slen );
2856 HASH_Update( &HASHcontext,
2857 mr->smr_oid, mlen );
2858 HASH_Update( &HASHcontext,
2859 value.bv_val, value.bv_len );
2860 HASH_Final( HASHdigest, &HASHcontext );
2862 free( value.bv_val );
2864 ber_dupbv( &keys[i], &digest );
2867 keys[i].bv_val = NULL;
2868 if( rc != LDAP_SUCCESS ) {
2869 ber_bvarray_free( keys );
2876 /* Index generation function */
2877 static int caseIgnoreIA5Filter(
2882 struct berval *prefix,
2888 HASH_CONTEXT HASHcontext;
2889 unsigned char HASHdigest[HASH_BYTES];
2890 struct berval value;
2891 struct berval digest;
2892 digest.bv_val = HASHdigest;
2893 digest.bv_len = sizeof(HASHdigest);
2895 slen = syntax->ssyn_oidlen;
2896 mlen = mr->smr_oidlen;
2898 ber_dupbv( &value, (struct berval *) assertValue );
2899 ldap_pvt_str2lower( value.bv_val );
2901 keys = ch_malloc( sizeof( struct berval ) * 2 );
2903 HASH_Init( &HASHcontext );
2904 if( prefix != NULL && prefix->bv_len > 0 ) {
2905 HASH_Update( &HASHcontext,
2906 prefix->bv_val, prefix->bv_len );
2908 HASH_Update( &HASHcontext,
2909 syntax->ssyn_oid, slen );
2910 HASH_Update( &HASHcontext,
2911 mr->smr_oid, mlen );
2912 HASH_Update( &HASHcontext,
2913 value.bv_val, value.bv_len );
2914 HASH_Final( HASHdigest, &HASHcontext );
2916 ber_dupbv( &keys[0], &digest );
2917 keys[1].bv_val = NULL;
2919 free( value.bv_val );
2923 return LDAP_SUCCESS;
2926 /* Substrings Index generation function */
2927 static int caseIgnoreIA5SubstringsIndexer(
2932 struct berval *prefix,
2939 HASH_CONTEXT HASHcontext;
2940 unsigned char HASHdigest[HASH_BYTES];
2941 struct berval digest;
2942 digest.bv_val = HASHdigest;
2943 digest.bv_len = sizeof(HASHdigest);
2945 /* we should have at least one value at this point */
2946 assert( values != NULL && values[0].bv_val != NULL );
2949 for( i=0; values[i].bv_val != NULL; i++ ) {
2950 /* count number of indices to generate */
2951 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2955 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
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 );
2964 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2965 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2966 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2970 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2971 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2972 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2973 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2975 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2981 /* no keys to generate */
2983 return LDAP_SUCCESS;
2986 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2988 slen = syntax->ssyn_oidlen;
2989 mlen = mr->smr_oidlen;
2992 for( i=0; values[i].bv_val != NULL; i++ ) {
2994 struct berval value;
2996 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2998 ber_dupbv( &value, &values[i] );
2999 ldap_pvt_str2lower( value.bv_val );
3001 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3002 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3004 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3005 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3007 for( j=0; j<max; j++ ) {
3008 HASH_Init( &HASHcontext );
3009 if( prefix != NULL && prefix->bv_len > 0 ) {
3010 HASH_Update( &HASHcontext,
3011 prefix->bv_val, prefix->bv_len );
3014 HASH_Update( &HASHcontext,
3015 &pre, sizeof( pre ) );
3016 HASH_Update( &HASHcontext,
3017 syntax->ssyn_oid, slen );
3018 HASH_Update( &HASHcontext,
3019 mr->smr_oid, mlen );
3020 HASH_Update( &HASHcontext,
3022 SLAP_INDEX_SUBSTR_MAXLEN );
3023 HASH_Final( HASHdigest, &HASHcontext );
3025 ber_dupbv( &keys[nkeys++], &digest );
3029 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3030 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3032 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3035 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3036 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3037 HASH_Init( &HASHcontext );
3038 if( prefix != NULL && prefix->bv_len > 0 ) {
3039 HASH_Update( &HASHcontext,
3040 prefix->bv_val, prefix->bv_len );
3042 HASH_Update( &HASHcontext,
3043 &pre, sizeof( pre ) );
3044 HASH_Update( &HASHcontext,
3045 syntax->ssyn_oid, slen );
3046 HASH_Update( &HASHcontext,
3047 mr->smr_oid, mlen );
3048 HASH_Update( &HASHcontext,
3050 HASH_Final( HASHdigest, &HASHcontext );
3052 ber_dupbv( &keys[nkeys++], &digest );
3055 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3056 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3057 HASH_Init( &HASHcontext );
3058 if( prefix != NULL && prefix->bv_len > 0 ) {
3059 HASH_Update( &HASHcontext,
3060 prefix->bv_val, prefix->bv_len );
3062 HASH_Update( &HASHcontext,
3063 &pre, sizeof( pre ) );
3064 HASH_Update( &HASHcontext,
3065 syntax->ssyn_oid, slen );
3066 HASH_Update( &HASHcontext,
3067 mr->smr_oid, mlen );
3068 HASH_Update( &HASHcontext,
3069 &value.bv_val[value.bv_len-j], j );
3070 HASH_Final( HASHdigest, &HASHcontext );
3072 ber_dupbv( &keys[nkeys++], &digest );
3077 free( value.bv_val );
3081 keys[nkeys].bv_val = NULL;
3088 return LDAP_SUCCESS;
3091 static int caseIgnoreIA5SubstringsFilter(
3096 struct berval *prefix,
3100 SubstringsAssertion *sa = assertValue;
3102 ber_len_t nkeys = 0;
3103 size_t slen, mlen, klen;
3105 HASH_CONTEXT HASHcontext;
3106 unsigned char HASHdigest[HASH_BYTES];
3107 struct berval value;
3108 struct berval digest;
3110 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3111 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3116 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3118 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3119 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3120 /* don't bother accounting for stepping */
3121 nkeys += sa->sa_any[i].bv_len -
3122 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3127 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3128 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3135 return LDAP_SUCCESS;
3138 digest.bv_val = HASHdigest;
3139 digest.bv_len = sizeof(HASHdigest);
3141 slen = syntax->ssyn_oidlen;
3142 mlen = mr->smr_oidlen;
3144 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3147 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3148 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3150 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3151 ber_dupbv( &value, &sa->sa_initial );
3152 ldap_pvt_str2lower( value.bv_val );
3154 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3155 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3157 HASH_Init( &HASHcontext );
3158 if( prefix != NULL && prefix->bv_len > 0 ) {
3159 HASH_Update( &HASHcontext,
3160 prefix->bv_val, prefix->bv_len );
3162 HASH_Update( &HASHcontext,
3163 &pre, sizeof( pre ) );
3164 HASH_Update( &HASHcontext,
3165 syntax->ssyn_oid, slen );
3166 HASH_Update( &HASHcontext,
3167 mr->smr_oid, mlen );
3168 HASH_Update( &HASHcontext,
3169 value.bv_val, klen );
3170 HASH_Final( HASHdigest, &HASHcontext );
3172 free( value.bv_val );
3173 ber_dupbv( &keys[nkeys++], &digest );
3176 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3178 pre = SLAP_INDEX_SUBSTR_PREFIX;
3179 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3181 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3182 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3186 ber_dupbv( &value, &sa->sa_any[i] );
3187 ldap_pvt_str2lower( value.bv_val );
3190 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3191 j += SLAP_INDEX_SUBSTR_STEP )
3193 HASH_Init( &HASHcontext );
3194 if( prefix != NULL && prefix->bv_len > 0 ) {
3195 HASH_Update( &HASHcontext,
3196 prefix->bv_val, prefix->bv_len );
3198 HASH_Update( &HASHcontext,
3199 &pre, sizeof( pre ) );
3200 HASH_Update( &HASHcontext,
3201 syntax->ssyn_oid, slen );
3202 HASH_Update( &HASHcontext,
3203 mr->smr_oid, mlen );
3204 HASH_Update( &HASHcontext,
3205 &value.bv_val[j], klen );
3206 HASH_Final( HASHdigest, &HASHcontext );
3208 ber_dupbv( &keys[nkeys++], &digest );
3211 free( value.bv_val );
3215 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3216 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3218 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3219 ber_dupbv( &value, &sa->sa_final );
3220 ldap_pvt_str2lower( value.bv_val );
3222 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3223 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3225 HASH_Init( &HASHcontext );
3226 if( prefix != NULL && prefix->bv_len > 0 ) {
3227 HASH_Update( &HASHcontext,
3228 prefix->bv_val, prefix->bv_len );
3230 HASH_Update( &HASHcontext,
3231 &pre, sizeof( pre ) );
3232 HASH_Update( &HASHcontext,
3233 syntax->ssyn_oid, slen );
3234 HASH_Update( &HASHcontext,
3235 mr->smr_oid, mlen );
3236 HASH_Update( &HASHcontext,
3237 &value.bv_val[value.bv_len-klen], klen );
3238 HASH_Final( HASHdigest, &HASHcontext );
3240 free( value.bv_val );
3241 ber_dupbv( &keys[nkeys++], &digest );
3245 keys[nkeys].bv_val = NULL;
3252 return LDAP_SUCCESS;
3256 numericStringValidate(
3262 for(i=0; i < in->bv_len; i++) {
3263 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3264 return LDAP_INVALID_SYNTAX;
3268 return LDAP_SUCCESS;
3272 numericStringNormalize(
3275 struct berval *normalized )
3277 /* removal all spaces */
3280 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3283 q = normalized->bv_val;
3286 if ( ASCII_SPACE( *p ) ) {
3287 /* Ignore whitespace */
3294 /* we should have copied no more then is in val */
3295 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3297 /* null terminate */
3300 normalized->bv_len = q - normalized->bv_val;
3302 return LDAP_SUCCESS;
3306 objectIdentifierFirstComponentMatch(
3311 struct berval *value,
3312 void *assertedValue )
3314 int rc = LDAP_SUCCESS;
3316 struct berval *asserted = (struct berval *) assertedValue;
3320 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3321 return LDAP_INVALID_SYNTAX;
3324 /* trim leading white space */
3325 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3329 /* grab next word */
3330 oid.bv_val = &value->bv_val[i];
3331 oid.bv_len = value->bv_len - i;
3332 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3337 /* insert attributeTypes, objectclass check here */
3338 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3339 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3342 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3343 MatchingRule *asserted_mr = mr_bvfind( asserted );
3344 MatchingRule *stored_mr = mr_bvfind( &oid );
3346 if( asserted_mr == NULL ) {
3347 rc = SLAPD_COMPARE_UNDEFINED;
3349 match = asserted_mr != stored_mr;
3352 } else if ( !strcmp( syntax->ssyn_oid,
3353 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3355 AttributeType *asserted_at = at_bvfind( asserted );
3356 AttributeType *stored_at = at_bvfind( &oid );
3358 if( asserted_at == NULL ) {
3359 rc = SLAPD_COMPARE_UNDEFINED;
3361 match = asserted_at != stored_at;
3364 } else if ( !strcmp( syntax->ssyn_oid,
3365 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3367 ObjectClass *asserted_oc = oc_bvfind( asserted );
3368 ObjectClass *stored_oc = oc_bvfind( &oid );
3370 if( asserted_oc == NULL ) {
3371 rc = SLAPD_COMPARE_UNDEFINED;
3373 match = asserted_oc != stored_oc;
3379 LDAP_LOG( CONFIG, ENTRY,
3380 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3381 match, value->bv_val, asserted->bv_val );
3383 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3384 "%d\n\t\"%s\"\n\t\"%s\"\n",
3385 match, value->bv_val, asserted->bv_val );
3389 if( rc == LDAP_SUCCESS ) *matchp = match;
3399 struct berval *value,
3400 void *assertedValue )
3402 long lValue, lAssertedValue;
3404 /* safe to assume integers are NUL terminated? */
3405 lValue = strtoul(value->bv_val, NULL, 10);
3406 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3407 return LDAP_CONSTRAINT_VIOLATION;
3409 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3410 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3411 return LDAP_CONSTRAINT_VIOLATION;
3413 *matchp = (lValue & lAssertedValue);
3414 return LDAP_SUCCESS;
3423 struct berval *value,
3424 void *assertedValue )
3426 long lValue, lAssertedValue;
3428 /* safe to assume integers are NUL terminated? */
3429 lValue = strtoul(value->bv_val, NULL, 10);
3430 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3431 return LDAP_CONSTRAINT_VIOLATION;
3433 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3434 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3435 return LDAP_CONSTRAINT_VIOLATION;
3437 *matchp = (lValue | lAssertedValue);
3438 return LDAP_SUCCESS;
3442 #include <openssl/x509.h>
3443 #include <openssl/err.h>
3444 char digit[] = "0123456789";
3447 * Next function returns a string representation of a ASN1_INTEGER.
3448 * It works for unlimited lengths.
3451 static struct berval *
3452 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3457 /* We work backwards, make it fill from the end of buf */
3458 p = buf + sizeof(buf) - 1;
3461 if ( a == NULL || a->length == 0 ) {
3469 /* We want to preserve the original */
3470 copy = ch_malloc(n*sizeof(unsigned int));
3471 for (i = 0; i<n; i++) {
3472 copy[i] = a->data[i];
3476 * base indicates the index of the most significant
3477 * byte that might be nonzero. When it goes off the
3478 * end, we now there is nothing left to do.
3484 for (i = base; i<n; i++ ) {
3485 copy[i] += carry*256;
3486 carry = copy[i] % 10;
3491 * Way too large, we need to leave
3492 * room for sign if negative
3497 *--p = digit[carry];
3498 if (copy[base] == 0)
3504 if ( a->type == V_ASN1_NEG_INTEGER ) {
3508 return ber_str2bv( p, 0, 1, bv );
3512 * Given a certificate in DER format, extract the corresponding
3513 * assertion value for certificateExactMatch
3516 certificateExactConvert(
3518 struct berval * out )
3521 unsigned char *p = in->bv_val;
3522 struct berval serial;
3523 struct berval issuer_dn;
3525 xcert = d2i_X509(NULL, &p, in->bv_len);
3528 LDAP_LOG( CONFIG, ENTRY,
3529 "certificateExactConvert: error parsing cert: %s\n",
3530 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3532 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3533 "error parsing cert: %s\n",
3534 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3536 return LDAP_INVALID_SYNTAX;
3539 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3541 return LDAP_INVALID_SYNTAX;
3543 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn ) != LDAP_SUCCESS ) {
3545 ber_memfree(serial.bv_val);
3546 return LDAP_INVALID_SYNTAX;
3551 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
3552 out->bv_val = ch_malloc(out->bv_len);
3554 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
3556 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
3558 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
3559 p += issuer_dn.bv_len;
3563 LDAP_LOG( CONFIG, ARGS,
3564 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
3566 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3568 out->bv_val, NULL, NULL );
3571 ber_memfree(serial.bv_val);
3572 ber_memfree(issuer_dn.bv_val);
3574 return LDAP_SUCCESS;
3578 serial_and_issuer_parse(
3579 struct berval *assertion,
3580 struct berval *serial,
3581 struct berval *issuer_dn
3589 begin = assertion->bv_val;
3590 end = assertion->bv_val+assertion->bv_len-1;
3591 for (p=begin; p<=end && *p != '$'; p++)
3594 return LDAP_INVALID_SYNTAX;
3596 /* p now points at the $ sign, now use begin and end to delimit the
3598 while (ASCII_SPACE(*begin))
3601 while (ASCII_SPACE(*end))
3604 bv.bv_len = end-begin+1;
3606 ber_dupbv(serial, &bv);
3608 /* now extract the issuer, remember p was at the dollar sign */
3611 end = assertion->bv_val+assertion->bv_len-1;
3612 while (ASCII_SPACE(*begin))
3614 /* should we trim spaces at the end too? is it safe always? */
3616 bv.bv_len = end-begin+1;
3618 dnNormalize2( NULL, &bv, issuer_dn );
3621 return LDAP_SUCCESS;
3625 certificateExactMatch(
3630 struct berval *value,
3631 void *assertedValue )
3634 unsigned char *p = value->bv_val;
3635 struct berval serial;
3636 struct berval issuer_dn;
3637 struct berval asserted_serial;
3638 struct berval asserted_issuer_dn;
3641 xcert = d2i_X509(NULL, &p, value->bv_len);
3644 LDAP_LOG( CONFIG, ENTRY,
3645 "certificateExactMatch: error parsing cert: %s\n",
3646 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3648 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
3649 "error parsing cert: %s\n",
3650 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3652 return LDAP_INVALID_SYNTAX;
3655 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3656 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
3660 serial_and_issuer_parse(assertedValue,
3662 &asserted_issuer_dn);
3667 slap_schema.si_syn_integer,
3668 slap_schema.si_mr_integerMatch,
3671 if ( ret == LDAP_SUCCESS ) {
3672 if ( *matchp == 0 ) {
3673 /* We need to normalize everything for dnMatch */
3677 slap_schema.si_syn_distinguishedName,
3678 slap_schema.si_mr_distinguishedNameMatch,
3680 &asserted_issuer_dn);
3685 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
3686 "%d\n\t\"%s $ %s\"\n",
3687 *matchp, serial.bv_val, issuer_dn.bv_val );
3688 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
3689 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3692 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3693 "%d\n\t\"%s $ %s\"\n",
3694 *matchp, serial.bv_val, issuer_dn.bv_val );
3695 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3696 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3700 ber_memfree(serial.bv_val);
3701 ber_memfree(issuer_dn.bv_val);
3702 ber_memfree(asserted_serial.bv_val);
3703 ber_memfree(asserted_issuer_dn.bv_val);
3709 * Index generation function
3710 * We just index the serials, in most scenarios the issuer DN is one of
3711 * a very small set of values.
3713 static int certificateExactIndexer(
3718 struct berval *prefix,
3726 struct berval serial;
3728 /* we should have at least one value at this point */
3729 assert( values != NULL && values[0].bv_val != NULL );
3731 for( i=0; values[i].bv_val != NULL; i++ ) {
3732 /* empty -- just count them */
3735 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3737 for( i=0; values[i].bv_val != NULL; i++ ) {
3738 p = values[i].bv_val;
3739 xcert = d2i_X509(NULL, &p, values[i].bv_len);
3742 LDAP_LOG( CONFIG, ENTRY,
3743 "certificateExactIndexer: error parsing cert: %s\n",
3744 ERR_error_string(ERR_get_error(),NULL), 0, 0);
3746 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3747 "error parsing cert: %s\n",
3748 ERR_error_string(ERR_get_error(),NULL),
3751 /* Do we leak keys on error? */
3752 return LDAP_INVALID_SYNTAX;
3755 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3757 integerNormalize( slap_schema.si_syn_integer,
3760 ber_memfree(serial.bv_val);
3762 LDAP_LOG( CONFIG, ENTRY,
3763 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
3765 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3772 keys[i].bv_val = NULL;
3774 return LDAP_SUCCESS;
3777 /* Index generation function */
3778 /* We think this is always called with a value in matching rule syntax */
3779 static int certificateExactFilter(
3784 struct berval *prefix,
3789 struct berval asserted_serial;
3791 serial_and_issuer_parse(assertValue,
3795 keys = ch_malloc( sizeof( struct berval ) * 2 );
3796 integerNormalize( syntax, &asserted_serial, &keys[0] );
3797 keys[1].bv_val = NULL;
3800 ber_memfree(asserted_serial.bv_val);
3801 return LDAP_SUCCESS;
3806 check_time_syntax (struct berval *val,
3810 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3811 static int mdays[2][12] = {
3812 /* non-leap years */
3813 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3815 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3818 int part, c, tzoffset, leapyear = 0 ;
3820 if( val->bv_len == 0 ) {
3821 return LDAP_INVALID_SYNTAX;
3824 p = (char *)val->bv_val;
3825 e = p + val->bv_len;
3827 /* Ignore initial whitespace */
3828 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3832 if (e - p < 13 - (2 * start)) {
3833 return LDAP_INVALID_SYNTAX;
3836 for (part = 0; part < 9; part++) {
3840 for (part = start; part < 7; part++) {
3842 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3849 return LDAP_INVALID_SYNTAX;
3851 if (c < 0 || c > 9) {
3852 return LDAP_INVALID_SYNTAX;
3858 return LDAP_INVALID_SYNTAX;
3860 if (c < 0 || c > 9) {
3861 return LDAP_INVALID_SYNTAX;
3866 if (part == 2 || part == 3) {
3869 if (parts[part] < 0) {
3870 return LDAP_INVALID_SYNTAX;
3872 if (parts[part] > ceiling[part]) {
3873 return LDAP_INVALID_SYNTAX;
3877 /* leapyear check for the Gregorian calendar (year>1581) */
3878 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
3879 ((parts[0] % 4 == 0) && (parts[1] == 0)))
3884 if (parts[3] > mdays[leapyear][parts[2]]) {
3885 return LDAP_INVALID_SYNTAX;
3890 tzoffset = 0; /* UTC */
3891 } else if (c != '+' && c != '-') {
3892 return LDAP_INVALID_SYNTAX;
3896 } else /* c == '+' */ {
3901 return LDAP_INVALID_SYNTAX;
3904 for (part = 7; part < 9; part++) {
3906 if (c < 0 || c > 9) {
3907 return LDAP_INVALID_SYNTAX;
3912 if (c < 0 || c > 9) {
3913 return LDAP_INVALID_SYNTAX;
3917 if (parts[part] < 0 || parts[part] > ceiling[part]) {
3918 return LDAP_INVALID_SYNTAX;
3923 /* Ignore trailing whitespace */
3924 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3928 return LDAP_INVALID_SYNTAX;
3931 switch ( tzoffset ) {
3932 case -1: /* negativ offset to UTC, ie west of Greenwich */
3933 parts[4] += parts[7];
3934 parts[5] += parts[8];
3935 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
3939 c = mdays[leapyear][parts[2]];
3941 if (parts[part] > c) {
3942 parts[part] -= c + 1;
3947 case 1: /* positive offset to UTC, ie east of Greenwich */
3948 parts[4] -= parts[7];
3949 parts[5] -= parts[8];
3950 for (part = 6; --part > 0; ) {
3954 /* first arg to % needs to be non negativ */
3955 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
3957 if (parts[part] < 0) {
3958 parts[part] += c + 1;
3963 case 0: /* already UTC */
3967 return LDAP_SUCCESS;
3970 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
3975 struct berval *normalized )
3979 rc = check_time_syntax(val, 1, parts);
3980 if (rc != LDAP_SUCCESS) {
3984 normalized->bv_val = ch_malloc( 14 );
3985 if ( normalized->bv_val == NULL ) {
3986 return LBER_ERROR_MEMORY;
3989 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
3990 parts[1], parts[2] + 1, parts[3] + 1,
3991 parts[4], parts[5], parts[6] );
3992 normalized->bv_len = 13;
3994 return LDAP_SUCCESS;
3998 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4006 return check_time_syntax(in, 1, parts);
4011 generalizedTimeValidate(
4017 return check_time_syntax(in, 0, parts);
4021 generalizedTimeNormalize(
4024 struct berval *normalized )
4028 rc = check_time_syntax(val, 0, parts);
4029 if (rc != LDAP_SUCCESS) {
4033 normalized->bv_val = ch_malloc( 16 );
4034 if ( normalized->bv_val == NULL ) {
4035 return LBER_ERROR_MEMORY;
4038 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4039 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4040 parts[4], parts[5], parts[6] );
4041 normalized->bv_len = 15;
4043 return LDAP_SUCCESS;
4047 nisNetgroupTripleValidate(
4049 struct berval *val )
4054 if ( val->bv_len == 0 ) {
4055 return LDAP_INVALID_SYNTAX;
4058 p = (char *)val->bv_val;
4059 e = p + val->bv_len;
4061 if ( *p != '(' /*')'*/ ) {
4062 return LDAP_INVALID_SYNTAX;
4065 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4069 return LDAP_INVALID_SYNTAX;
4072 } else if ( !AD_CHAR( *p ) ) {
4073 return LDAP_INVALID_SYNTAX;
4077 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4078 return LDAP_INVALID_SYNTAX;
4084 return LDAP_INVALID_SYNTAX;
4087 return LDAP_SUCCESS;
4091 bootParameterValidate(
4093 struct berval *val )
4097 if ( val->bv_len == 0 ) {
4098 return LDAP_INVALID_SYNTAX;
4101 p = (char *)val->bv_val;
4102 e = p + val->bv_len;
4105 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4106 if ( !AD_CHAR( *p ) ) {
4107 return LDAP_INVALID_SYNTAX;
4112 return LDAP_INVALID_SYNTAX;
4116 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4117 if ( !AD_CHAR( *p ) ) {
4118 return LDAP_INVALID_SYNTAX;
4123 return LDAP_INVALID_SYNTAX;
4127 for ( p++; p < e; p++ ) {
4128 if ( !SLAP_PRINTABLE( *p ) ) {
4129 return LDAP_INVALID_SYNTAX;
4133 return LDAP_SUCCESS;
4136 static struct syntax_defs_rec {
4138 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4139 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4141 slap_syntax_validate_func *sd_validate;
4142 slap_syntax_transform_func *sd_normalize;
4143 slap_syntax_transform_func *sd_pretty;
4144 #ifdef SLAPD_BINARY_CONVERSION
4145 slap_syntax_transform_func *sd_ber2str;
4146 slap_syntax_transform_func *sd_str2ber;
4149 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4150 X_BINARY X_NOT_H_R ")",
4151 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4152 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4153 0, NULL, NULL, NULL},
4154 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4155 0, NULL, NULL, NULL},
4156 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4158 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4159 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4161 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4162 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4163 0, bitStringValidate, bitStringNormalize, NULL },
4164 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4165 0, booleanValidate, NULL, NULL},
4166 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4167 X_BINARY X_NOT_H_R ")",
4168 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4169 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4170 X_BINARY X_NOT_H_R ")",
4171 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4172 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4173 X_BINARY X_NOT_H_R ")",
4174 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4175 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4176 0, countryStringValidate, IA5StringNormalize, NULL},
4177 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4178 0, dnValidate, dnNormalize2, dnPretty2},
4179 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4180 0, NULL, NULL, NULL},
4181 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4182 0, NULL, NULL, NULL},
4183 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4184 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4185 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4186 0, NULL, NULL, NULL},
4187 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4188 0, NULL, NULL, NULL},
4189 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4190 0, NULL, NULL, NULL},
4191 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4192 0, NULL, NULL, NULL},
4193 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4194 0, NULL, NULL, NULL},
4195 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4196 0, printablesStringValidate, telephoneNumberNormalize, NULL},
4197 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4198 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4199 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4200 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4201 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4202 0, NULL, NULL, NULL},
4203 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4204 0, IA5StringValidate, IA5StringNormalize, NULL},
4205 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4206 0, integerValidate, integerNormalize, NULL},
4207 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4208 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4209 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4210 0, NULL, NULL, NULL},
4211 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4212 0, NULL, NULL, NULL},
4213 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4214 0, NULL, NULL, NULL},
4215 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4216 0, NULL, NULL, NULL},
4217 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4218 0, NULL, NULL, NULL},
4219 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4220 0, nameUIDValidate, nameUIDNormalize, NULL},
4221 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4222 0, NULL, NULL, NULL},
4223 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4224 0, numericStringValidate, numericStringNormalize, NULL},
4225 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4226 0, NULL, NULL, NULL},
4227 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4228 0, oidValidate, NULL, NULL},
4229 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4230 0, IA5StringValidate, IA5StringNormalize, NULL},
4231 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4232 0, blobValidate, NULL, NULL},
4233 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4234 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4235 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4236 0, NULL, NULL, NULL},
4237 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4238 0, NULL, NULL, NULL},
4239 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4240 0, printableStringValidate, IA5StringNormalize, NULL},
4241 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4242 X_BINARY X_NOT_H_R ")",
4243 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4244 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4245 X_BINARY X_NOT_H_R ")",
4246 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4247 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4248 0, printableStringValidate, telephoneNumberNormalize, NULL},
4249 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4250 0, NULL, NULL, NULL},
4251 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4252 0, printablesStringValidate, IA5StringNormalize, NULL},
4253 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4254 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4255 0, utcTimeValidate, utcTimeNormalize, NULL},
4257 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4258 0, NULL, NULL, NULL},
4259 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4260 0, NULL, NULL, NULL},
4261 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4262 0, NULL, NULL, NULL},
4263 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4264 0, NULL, NULL, NULL},
4265 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4266 0, NULL, NULL, NULL},
4268 /* RFC 2307 NIS Syntaxes */
4269 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4270 0, nisNetgroupTripleValidate, NULL, NULL},
4271 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4272 0, bootParameterValidate, NULL, NULL},
4276 /* These OIDs are not published yet, but will be in the next
4277 * I-D for PKIX LDAPv3 schema as have been advanced by David
4278 * Chadwick in private mail.
4280 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4281 0, NULL, NULL, NULL},
4284 /* OpenLDAP Experimental Syntaxes */
4285 #ifdef SLAPD_ACI_ENABLED
4286 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4288 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4292 #ifdef SLAPD_AUTHPASSWD
4293 /* needs updating */
4294 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4295 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4298 /* OpenLDAP Void Syntax */
4299 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4300 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4301 {NULL, 0, NULL, NULL, NULL}
4305 * Other matching rules in X.520 that we do not use (yet):
4307 * 2.5.13.9 numericStringOrderingMatch
4308 * 2.5.13.18 octetStringOrderingMatch
4309 * 2.5.13.19 octetStringSubstringsMatch
4310 * 2.5.13.25 uTCTimeMatch
4311 * 2.5.13.26 uTCTimeOrderingMatch
4312 * 2.5.13.31 directoryStringFirstComponentMatch
4313 * 2.5.13.32 wordMatch
4314 * 2.5.13.33 keywordMatch
4315 * 2.5.13.35 certificateMatch
4316 * 2.5.13.36 certificatePairExactMatch
4317 * 2.5.13.37 certificatePairMatch
4318 * 2.5.13.38 certificateListExactMatch
4319 * 2.5.13.39 certificateListMatch
4320 * 2.5.13.40 algorithmIdentifierMatch
4321 * 2.5.13.41 storedPrefixMatch
4322 * 2.5.13.42 attributeCertificateMatch
4323 * 2.5.13.43 readerAndKeyIDMatch
4324 * 2.5.13.44 attributeIntegrityMatch
4326 static struct mrule_defs_rec {
4328 slap_mask_t mrd_usage;
4329 slap_mr_convert_func * mrd_convert;
4330 slap_mr_normalize_func * mrd_normalize;
4331 slap_mr_match_func * mrd_match;
4332 slap_mr_indexer_func * mrd_indexer;
4333 slap_mr_filter_func * mrd_filter;
4335 char * mrd_associated;
4338 * EQUALITY matching rules must be listed after associated APPROX
4339 * matching rules. So, we list all APPROX matching rules first.
4341 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4342 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4343 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4345 directoryStringApproxMatch,
4346 directoryStringApproxIndexer,
4347 directoryStringApproxFilter,
4350 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4351 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4352 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4354 IA5StringApproxMatch,
4355 IA5StringApproxIndexer,
4356 IA5StringApproxFilter,
4360 * Other matching rules
4363 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4364 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4365 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4367 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4370 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4371 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4372 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4374 dnMatch, dnIndexer, dnFilter,
4377 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4378 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4379 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4381 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4382 directoryStringApproxMatchOID },
4384 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4385 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4388 caseIgnoreOrderingMatch, NULL, NULL,
4391 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4392 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4393 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4395 caseExactIgnoreSubstringsMatch,
4396 caseExactIgnoreSubstringsIndexer,
4397 caseExactIgnoreSubstringsFilter,
4400 {"( 2.5.13.5 NAME 'caseExactMatch' "
4401 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4402 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4404 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4405 directoryStringApproxMatchOID },
4407 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4408 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4411 caseExactOrderingMatch, NULL, NULL,
4414 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4415 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4416 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4418 caseExactIgnoreSubstringsMatch,
4419 caseExactIgnoreSubstringsIndexer,
4420 caseExactIgnoreSubstringsFilter,
4423 {"( 2.5.13.8 NAME 'numericStringMatch' "
4424 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4425 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4428 caseIgnoreIA5Indexer,
4429 caseIgnoreIA5Filter,
4432 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4433 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4434 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4436 caseIgnoreIA5SubstringsMatch,
4437 caseIgnoreIA5SubstringsIndexer,
4438 caseIgnoreIA5SubstringsFilter,
4441 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4442 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4443 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4445 caseIgnoreListMatch, NULL, NULL,
4448 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4449 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4450 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4452 caseIgnoreListSubstringsMatch, NULL, NULL,
4455 {"( 2.5.13.13 NAME 'booleanMatch' "
4456 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4457 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4459 booleanMatch, NULL, NULL,
4462 {"( 2.5.13.14 NAME 'integerMatch' "
4463 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4464 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4466 integerMatch, integerIndexer, integerFilter,
4469 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4470 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4473 integerOrderingMatch, NULL, NULL,
4476 {"( 2.5.13.16 NAME 'bitStringMatch' "
4477 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4478 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4480 bitStringMatch, bitStringIndexer, bitStringFilter,
4483 {"( 2.5.13.17 NAME 'octetStringMatch' "
4484 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4485 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4487 octetStringMatch, octetStringIndexer, octetStringFilter,
4490 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4491 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4492 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4494 telephoneNumberMatch,
4495 telephoneNumberIndexer,
4496 telephoneNumberFilter,
4499 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4500 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4501 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4503 telephoneNumberSubstringsMatch,
4504 telephoneNumberSubstringsIndexer,
4505 telephoneNumberSubstringsFilter,
4508 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4509 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4510 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4515 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4516 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4517 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4519 uniqueMemberMatch, NULL, NULL,
4522 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4523 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4524 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4526 protocolInformationMatch, NULL, NULL,
4529 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4530 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4531 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4533 generalizedTimeMatch, NULL, NULL,
4536 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4537 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4540 generalizedTimeOrderingMatch, NULL, NULL,
4543 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4544 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4545 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4547 integerFirstComponentMatch, NULL, NULL,
4550 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4551 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4552 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4554 objectIdentifierFirstComponentMatch, NULL, NULL,
4558 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4559 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4560 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4561 certificateExactConvert, NULL,
4562 certificateExactMatch,
4563 certificateExactIndexer, certificateExactFilter,
4567 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4568 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4569 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4571 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4572 IA5StringApproxMatchOID },
4574 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4575 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4576 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4578 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4579 IA5StringApproxMatchOID },
4581 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4582 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4585 caseIgnoreIA5SubstringsMatch,
4586 caseIgnoreIA5SubstringsIndexer,
4587 caseIgnoreIA5SubstringsFilter,
4590 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4591 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4594 caseExactIA5SubstringsMatch,
4595 caseExactIA5SubstringsIndexer,
4596 caseExactIA5SubstringsFilter,
4599 #ifdef SLAPD_AUTHPASSWD
4600 /* needs updating */
4601 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4602 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4605 authPasswordMatch, NULL, NULL,
4609 #ifdef SLAPD_ACI_ENABLED
4610 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4611 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4614 OpenLDAPaciMatch, NULL, NULL,
4618 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4619 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4622 integerBitAndMatch, NULL, NULL,
4625 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4626 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4629 integerBitOrMatch, NULL, NULL,
4632 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
4636 slap_schema_init( void )
4641 /* we should only be called once (from main) */
4642 assert( schema_init_done == 0 );
4644 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4645 res = register_syntax( syntax_defs[i].sd_desc,
4646 syntax_defs[i].sd_flags,
4647 syntax_defs[i].sd_validate,
4648 syntax_defs[i].sd_normalize,
4649 syntax_defs[i].sd_pretty
4650 #ifdef SLAPD_BINARY_CONVERSION
4652 syntax_defs[i].sd_ber2str,
4653 syntax_defs[i].sd_str2ber
4658 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
4659 syntax_defs[i].sd_desc );
4664 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4665 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
4667 "slap_schema_init: Ingoring unusable matching rule %s\n",
4668 mrule_defs[i].mrd_desc );
4672 res = register_matching_rule(
4673 mrule_defs[i].mrd_desc,
4674 mrule_defs[i].mrd_usage,
4675 mrule_defs[i].mrd_convert,
4676 mrule_defs[i].mrd_normalize,
4677 mrule_defs[i].mrd_match,
4678 mrule_defs[i].mrd_indexer,
4679 mrule_defs[i].mrd_filter,
4680 mrule_defs[i].mrd_associated );
4684 "slap_schema_init: Error registering matching rule %s\n",
4685 mrule_defs[i].mrd_desc );
4690 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4691 *mr_ptr[i].mr = mr_find( mr_ptr[i].oid );
4693 res = slap_schema_load();
4694 schema_init_done = 1;
4699 schema_destroy( void )
4705 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4706 *mr_ptr[i].mr = NULL;