1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
15 #include <ac/string.h>
16 #include <ac/socket.h>
21 #include "ldap_utf8.h"
23 #include "lutil_hash.h"
24 #define HASH_BYTES LUTIL_HASH_BYTES
25 #define HASH_CONTEXT lutil_HASH_CTX
26 #define HASH_Init(c) lutil_HASHInit(c)
27 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
28 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
30 /* recycled validatation routines */
31 #define berValidate blobValidate
33 /* unimplemented pretters */
34 #define integerPretty NULL
36 /* recycled matching routines */
37 #define bitStringMatch octetStringMatch
38 #define numericStringMatch caseIgnoreIA5Match
39 #define objectIdentifierMatch caseIgnoreIA5Match
40 #define telephoneNumberMatch caseIgnoreIA5Match
41 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
42 #define generalizedTimeMatch caseIgnoreIA5Match
43 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
44 #define uniqueMemberMatch dnMatch
46 /* approx matching rules */
47 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
48 #define directoryStringApproxMatch approxMatch
49 #define directoryStringApproxIndexer approxIndexer
50 #define directoryStringApproxFilter approxFilter
51 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
52 #define IA5StringApproxMatch approxMatch
53 #define IA5StringApproxIndexer approxIndexer
54 #define IA5StringApproxFilter approxFilter
56 /* orderring matching rules */
57 #define caseIgnoreOrderingMatch caseIgnoreMatch
58 #define caseExactOrderingMatch caseExactMatch
60 /* unimplemented matching routines */
61 #define caseIgnoreListMatch NULL
62 #define caseIgnoreListSubstringsMatch NULL
63 #define protocolInformationMatch NULL
64 #define integerFirstComponentMatch NULL
66 #define OpenLDAPaciMatch NULL
67 #define authPasswordMatch NULL
69 /* recycled indexing/filtering routines */
70 #define dnIndexer caseExactIgnoreIndexer
71 #define dnFilter caseExactIgnoreFilter
72 #define bitStringFilter octetStringFilter
73 #define bitStringIndexer octetStringIndexer
75 #define telephoneNumberIndexer caseIgnoreIA5Indexer
76 #define telephoneNumberFilter caseIgnoreIA5Filter
77 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
78 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
80 /* must match OIDs below */
81 #define caseExactMatchOID "2.5.13.5"
82 #define caseExactSubstringsMatchOID "2.5.13.7"
84 static char *strcasechr( const char *str, int c )
86 char *lower = strchr( str, TOLOWER(c) );
87 char *upper = strchr( str, TOUPPER(c) );
89 if( lower && upper ) {
90 return lower < upper ? lower : upper;
104 struct berval *value,
105 void *assertedValue )
107 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
110 match = memcmp( value->bv_val,
111 ((struct berval *) assertedValue)->bv_val,
119 /* Index generation function */
120 static int octetStringIndexer(
125 struct berval *prefix,
126 struct berval **values,
127 struct berval ***keysp )
131 struct berval **keys;
132 HASH_CONTEXT HASHcontext;
133 unsigned char HASHdigest[HASH_BYTES];
134 struct berval digest;
135 digest.bv_val = HASHdigest;
136 digest.bv_len = sizeof(HASHdigest);
138 for( i=0; values[i] != NULL; i++ ) {
139 /* just count them */
142 /* we should have at least one value at this point */
145 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
147 slen = syntax->ssyn_oidlen;
148 mlen = mr->smr_oidlen;
150 for( i=0; values[i] != NULL; i++ ) {
151 HASH_Init( &HASHcontext );
152 if( prefix != NULL && prefix->bv_len > 0 ) {
153 HASH_Update( &HASHcontext,
154 prefix->bv_val, prefix->bv_len );
156 HASH_Update( &HASHcontext,
157 syntax->ssyn_oid, slen );
158 HASH_Update( &HASHcontext,
160 HASH_Update( &HASHcontext,
161 values[i]->bv_val, values[i]->bv_len );
162 HASH_Final( HASHdigest, &HASHcontext );
164 keys[i] = ber_bvdup( &digest );
174 /* Index generation function */
175 static int octetStringFilter(
180 struct berval *prefix,
182 struct berval ***keysp )
185 struct berval **keys;
186 HASH_CONTEXT HASHcontext;
187 unsigned char HASHdigest[HASH_BYTES];
188 struct berval *value = (struct berval *) assertValue;
189 struct berval digest;
190 digest.bv_val = HASHdigest;
191 digest.bv_len = sizeof(HASHdigest);
193 slen = syntax->ssyn_oidlen;
194 mlen = mr->smr_oidlen;
196 keys = ch_malloc( sizeof( struct berval * ) * 2 );
198 HASH_Init( &HASHcontext );
199 if( prefix != NULL && prefix->bv_len > 0 ) {
200 HASH_Update( &HASHcontext,
201 prefix->bv_val, prefix->bv_len );
203 HASH_Update( &HASHcontext,
204 syntax->ssyn_oid, slen );
205 HASH_Update( &HASHcontext,
207 HASH_Update( &HASHcontext,
208 value->bv_val, value->bv_len );
209 HASH_Final( HASHdigest, &HASHcontext );
211 keys[0] = ber_bvdup( &digest );
227 if( in->bv_len == 0 ) return LDAP_SUCCESS;
229 dn = ber_bvdup( in );
230 if( !dn ) return LDAP_OTHER;
232 if( dn->bv_val[dn->bv_len-1] == 'B'
233 && dn->bv_val[dn->bv_len-2] == '\'' )
235 /* assume presence of optional UID */
238 for(i=dn->bv_len-3; i>1; i--) {
239 if( dn->bv_val[i] != '0' && dn->bv_val[i] != '1' ) {
243 if( dn->bv_val[i] != '\'' ||
244 dn->bv_val[i-1] != '#' ) {
246 return LDAP_INVALID_SYNTAX;
249 /* trim the UID to allow use of dnValidate */
250 dn->bv_val[i-1] = '\0';
254 rc = dnValidate( NULL, dn );
264 struct berval **normalized )
266 struct berval *out = ber_bvdup( val );
269 if( out->bv_len != 0 ) {
272 ber_len_t uidlen = 0;
274 if( out->bv_val[out->bv_len-1] == '\'' ) {
275 /* assume presence of optional UID */
276 uid = strrchr( out->bv_val, '#' );
280 return LDAP_INVALID_SYNTAX;
283 uidlen = out->bv_len - (uid - out->bv_val);
284 /* temporarily trim the UID */
286 out->bv_len -= uidlen;
289 #ifdef USE_DN_NORMALIZE
290 rc = dnNormalize( NULL, out, normalized );
292 rc = dnPretty( NULL, out, normalized );
295 if( rc != LDAP_SUCCESS ) {
297 return LDAP_INVALID_SYNTAX;
300 dnlen = (*normalized)->bv_len;
303 struct berval *b2 = ch_malloc(sizeof(struct berval));
304 b2->bv_val = ch_malloc(dnlen + uidlen + 1);
305 SAFEMEMCPY( b2->bv_val, (*normalized)->bv_val, dnlen );
307 /* restore the separator */
310 SAFEMEMCPY( (*normalized)->bv_val+dnlen, uid, uidlen );
311 b2->bv_len = dnlen + uidlen;
312 (*normalized)->bv_val[dnlen+uidlen] = '\0';
313 ber_bvfree(*normalized);
327 /* any value allowed */
336 /* any value allowed */
347 /* very unforgiving validation, requires no normalization
348 * before simplistic matching
350 if( in->bv_len < 3 ) {
351 return LDAP_INVALID_SYNTAX;
355 * rfc 2252 section 6.3 Bit String
356 * bitstring = "'" *binary-digit "'"
357 * binary-digit = "0" / "1"
358 * example: '0101111101'B
361 if( in->bv_val[0] != '\'' ||
362 in->bv_val[in->bv_len-2] != '\'' ||
363 in->bv_val[in->bv_len-1] != 'B' )
365 return LDAP_INVALID_SYNTAX;
368 for( i=in->bv_len-3; i>0; i-- ) {
369 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
370 return LDAP_INVALID_SYNTAX;
381 struct berval **normalized )
384 * A normalized bitString is has no extaneous (leading) zero bits.
385 * That is, '00010'B is normalized to '10'B
386 * However, as a special case, '0'B requires no normalization.
388 struct berval *newval;
391 /* start at the first bit */
394 /* Find the first non-zero bit */
395 while ( *p == '0' ) p++;
397 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
400 /* no non-zero bits */
401 newval->bv_val = ch_strdup("\'0\'B");
402 newval->bv_len = sizeof("\'0\'B") - 1;
406 newval->bv_val = ch_malloc( val->bv_len + 1 );
408 newval->bv_val[0] = '\'';
411 for( ; *p != '\0'; p++ ) {
412 newval->bv_val[newval->bv_len++] = *p;
415 newval->bv_val[newval->bv_len] = '\0';
418 *normalized = newval;
423 * Handling boolean syntax and matching is quite rigid.
424 * A more flexible approach would be to allow a variety
425 * of strings to be normalized and prettied into TRUE
433 /* very unforgiving validation, requires no normalization
434 * before simplistic matching
437 if( in->bv_len == 4 ) {
438 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
441 } else if( in->bv_len == 5 ) {
442 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
447 return LDAP_INVALID_SYNTAX;
456 struct berval *value,
457 void *assertedValue )
459 /* simplistic matching allowed by rigid validation */
460 struct berval *asserted = (struct berval *) assertedValue;
461 *matchp = value->bv_len != asserted->bv_len;
472 unsigned char *u = in->bv_val;
474 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
476 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
477 /* get the length indicated by the first byte */
478 len = LDAP_UTF8_CHARLEN( u );
480 /* should not be zero */
481 if( len == 0 ) return LDAP_INVALID_SYNTAX;
483 /* make sure len corresponds with the offset
484 to the next character */
485 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
488 if( count != 0 ) return LDAP_INVALID_SYNTAX;
497 struct berval **normalized )
499 struct berval *newval;
502 newval = ch_malloc( sizeof( struct berval ) );
506 /* Ignore initial whitespace */
507 while ( ldap_utf8_isspace( p ) ) {
513 return LDAP_INVALID_SYNTAX;
516 newval->bv_val = ch_strdup( p );
517 p = q = newval->bv_val;
523 if ( ldap_utf8_isspace( p ) ) {
524 len = LDAP_UTF8_COPY(q,p);
529 /* Ignore the extra whitespace */
530 while ( ldap_utf8_isspace( p ) ) {
534 len = LDAP_UTF8_COPY(q,p);
541 assert( *newval->bv_val );
542 assert( newval->bv_val < p );
545 /* cannot start with a space */
546 assert( !ldap_utf8_isspace(newval->bv_val) );
549 * If the string ended in space, backup the pointer one
550 * position. One is enough because the above loop collapsed
551 * all whitespace to a single space.
558 /* cannot end with a space */
559 assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
564 newval->bv_len = q - newval->bv_val;
565 *normalized = newval;
570 /* Returns Unicode cannonically normalized copy of a substring assertion
571 * Skipping attribute description */
572 static SubstringsAssertion *
573 UTF8SubstringsassertionNormalize(
574 SubstringsAssertion *sa,
577 SubstringsAssertion *nsa;
580 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
585 if( sa->sa_initial != NULL ) {
586 nsa->sa_initial = ber_bvstr( UTF8normalize( sa->sa_initial, casefold ) );
587 if( nsa->sa_initial == NULL ) {
592 if( sa->sa_any != NULL ) {
593 for( i=0; sa->sa_any[i] != NULL; i++ ) {
596 nsa->sa_any = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
597 for( i=0; sa->sa_any[i] != NULL; i++ ) {
598 nsa->sa_any[i] = ber_bvstr( UTF8normalize( sa->sa_any[i], casefold ) );
599 if( nsa->sa_any[i] == NULL ) {
603 nsa->sa_any[i] = NULL;
606 if( sa->sa_final != NULL ) {
607 nsa->sa_final = ber_bvstr( UTF8normalize( sa->sa_final, casefold ) );
608 if( nsa->sa_final == NULL ) {
616 ber_bvfree( nsa->sa_final );
617 ber_bvecfree( nsa->sa_any );
618 ber_bvfree( nsa->sa_initial );
623 /* Strip characters with the 8th bit set */
636 while( *++q & 0x80 ) {
639 p = memmove(p, q, strlen(q) + 1);
647 #ifndef SLAPD_APPROX_OLDSINGLESTRING
649 #if defined(SLAPD_APPROX_INITIALS)
650 #define SLAPD_APPROX_DELIMITER "._ "
651 #define SLAPD_APPROX_WORDLEN 2
653 #define SLAPD_APPROX_DELIMITER " "
654 #define SLAPD_APPROX_WORDLEN 1
663 struct berval *value,
664 void *assertedValue )
666 char *val, *nval, *assertv, **values, **words, *c;
667 int i, count, len, nextchunk=0, nextavail=0;
670 /* Yes, this is necessary */
671 nval = UTF8normalize( value, UTF8_NOCASEFOLD );
676 strip8bitChars( nval );
678 /* Yes, this is necessary */
679 assertv = UTF8normalize( ((struct berval *)assertedValue),
681 if( assertv == NULL ) {
686 strip8bitChars( assertv );
687 avlen = strlen( assertv );
689 /* Isolate how many words there are */
690 for( c=nval,count=1; *c; c++ ) {
691 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
692 if ( c == NULL ) break;
697 /* Get a phonetic copy of each word */
698 words = (char **)ch_malloc( count * sizeof(char *) );
699 values = (char **)ch_malloc( count * sizeof(char *) );
700 for( c=nval,i=0; i<count; i++,c+=strlen(c)+1 ) {
702 values[i] = phonetic(c);
705 /* Work through the asserted value's words, to see if at least some
706 of the words are there, in the same order. */
708 while ( (size_t) nextchunk < avlen ) {
709 len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER);
714 #if defined(SLAPD_APPROX_INITIALS)
715 else if( len == 1 ) {
716 /* Single letter words need to at least match one word's initial */
717 for( i=nextavail; i<count; i++ )
718 if( !strncasecmp( assertv+nextchunk, words[i], 1 )) {
725 /* Isolate the next word in the asserted value and phonetic it */
726 assertv[nextchunk+len] = '\0';
727 val = phonetic( assertv + nextchunk );
729 /* See if this phonetic chunk is in the remaining words of *value */
730 for( i=nextavail; i<count; i++ ){
731 if( !strcmp( val, values[i] ) ){
739 /* This chunk in the asserted value was NOT within the *value. */
745 /* Go on to the next word in the asserted value */
749 /* If some of the words were seen, call it a match */
750 if( nextavail > 0 ) {
759 for( i=0; i<count; i++ ) {
760 ch_free( values[i] );
775 struct berval *prefix,
776 struct berval **values,
777 struct berval ***keysp )
780 int i,j, len, wordcount, keycount=0;
781 struct berval **newkeys, **keys=NULL;
783 for( j=0; values[j] != NULL; j++ ) {
784 /* Yes, this is necessary */
785 val = UTF8normalize( values[j], UTF8_NOCASEFOLD );
786 strip8bitChars( val );
788 /* Isolate how many words there are. There will be a key for each */
789 for( wordcount=0,c=val; *c; c++) {
790 len = strcspn(c, SLAPD_APPROX_DELIMITER);
791 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
793 if (*c == '\0') break;
797 /* Allocate/increase storage to account for new keys */
798 newkeys = (struct berval **)ch_malloc( (keycount + wordcount + 1)
799 * sizeof(struct berval *) );
800 memcpy( newkeys, keys, keycount * sizeof(struct berval *) );
801 if( keys ) ch_free( keys );
804 /* Get a phonetic copy of each word */
805 for( c=val,i=0; i<wordcount; c+=len+1 ) {
807 if( len < SLAPD_APPROX_WORDLEN ) continue;
808 keys[keycount] = (struct berval *)ch_malloc( sizeof(struct berval) );
809 keys[keycount]->bv_val = phonetic( c );
810 keys[keycount]->bv_len = strlen( keys[keycount]->bv_val );
817 keys[keycount] = NULL;
829 struct berval *prefix,
831 struct berval ***keysp )
835 struct berval **keys;
837 /* Yes, this is necessary */
838 val = UTF8normalize( ((struct berval *)assertValue),
841 keys = (struct berval **)ch_malloc( sizeof(struct berval *) );
846 strip8bitChars( val );
848 /* Isolate how many words there are. There will be a key for each */
849 for( count=0,c=val; *c; c++) {
850 len = strcspn(c, SLAPD_APPROX_DELIMITER);
851 if( len >= SLAPD_APPROX_WORDLEN ) count++;
853 if (*c == '\0') break;
857 /* Allocate storage for new keys */
858 keys = (struct berval **)ch_malloc( (count + 1) * sizeof(struct berval *) );
860 /* Get a phonetic copy of each word */
861 for( c=val,i=0; i<count; c+=len+1 ) {
863 if( len < SLAPD_APPROX_WORDLEN ) continue;
864 keys[i] = ber_bvstr( phonetic( c ) );
878 /* No other form of Approximate Matching is defined */
886 struct berval *value,
887 void *assertedValue )
889 char *vapprox, *avapprox;
892 /* Yes, this is necessary */
893 s = UTF8normalize( value, UTF8_NOCASEFOLD );
899 /* Yes, this is necessary */
900 t = UTF8normalize( ((struct berval *)assertedValue),
908 vapprox = phonetic( strip8bitChars( s ) );
909 avapprox = phonetic( strip8bitChars( t ) );
914 *matchp = strcmp( vapprox, avapprox );
928 struct berval *prefix,
929 struct berval **values,
930 struct berval ***keysp )
933 struct berval **keys;
936 for( i=0; values[i] != NULL; i++ ) {
937 /* empty - just count them */
940 /* we should have at least one value at this point */
943 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * (i+1) );
945 /* Copy each value and run it through phonetic() */
946 for( i=0; values[i] != NULL; i++ ) {
947 /* Yes, this is necessary */
948 s = UTF8normalize( values[i], UTF8_NOCASEFOLD );
950 /* strip 8-bit chars and run through phonetic() */
951 keys[i] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
967 struct berval *prefix,
969 struct berval ***keysp )
971 struct berval **keys;
974 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * 2 );
976 /* Yes, this is necessary */
977 s = UTF8normalize( ((struct berval *)assertValue),
982 /* strip 8-bit chars and run through phonetic() */
983 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1000 struct berval *value,
1001 void *assertedValue )
1003 *matchp = UTF8normcmp( value->bv_val,
1004 ((struct berval *) assertedValue)->bv_val,
1006 return LDAP_SUCCESS;
1010 caseExactIgnoreSubstringsMatch(
1015 struct berval *value,
1016 void *assertedValue )
1019 SubstringsAssertion *sub = NULL;
1023 char *nav, casefold;
1025 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1026 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1028 nav = UTF8normalize( value, casefold );
1034 left.bv_len = strlen( nav );
1036 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1042 /* Add up asserted input length */
1043 if( sub->sa_initial ) {
1044 inlen += sub->sa_initial->bv_len;
1047 for(i=0; sub->sa_any[i] != NULL; i++) {
1048 inlen += sub->sa_any[i]->bv_len;
1051 if( sub->sa_final ) {
1052 inlen += sub->sa_final->bv_len;
1055 if( sub->sa_initial ) {
1056 if( inlen > left.bv_len ) {
1061 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
1062 sub->sa_initial->bv_len );
1068 left.bv_val += sub->sa_initial->bv_len;
1069 left.bv_len -= sub->sa_initial->bv_len;
1070 inlen -= sub->sa_initial->bv_len;
1073 if( sub->sa_final ) {
1074 if( inlen > left.bv_len ) {
1079 match = strncmp( sub->sa_final->bv_val,
1080 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
1081 sub->sa_final->bv_len );
1087 left.bv_len -= sub->sa_final->bv_len;
1088 inlen -= sub->sa_final->bv_len;
1092 for(i=0; sub->sa_any[i]; i++) {
1097 if( inlen > left.bv_len ) {
1098 /* not enough length */
1103 if( sub->sa_any[i]->bv_len == 0 ) {
1107 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
1114 idx = p - left.bv_val;
1115 assert( idx < left.bv_len );
1117 if( idx >= left.bv_len ) {
1118 /* this shouldn't happen */
1120 ch_free( sub->sa_final );
1121 ber_bvecfree( sub->sa_any );
1122 ch_free( sub->sa_initial );
1130 if( sub->sa_any[i]->bv_len > left.bv_len ) {
1131 /* not enough left */
1136 match = strncmp( left.bv_val,
1137 sub->sa_any[i]->bv_val,
1138 sub->sa_any[i]->bv_len );
1146 left.bv_val += sub->sa_any[i]->bv_len;
1147 left.bv_len -= sub->sa_any[i]->bv_len;
1148 inlen -= sub->sa_any[i]->bv_len;
1155 ber_bvfree( sub->sa_final );
1156 ber_bvecfree( sub->sa_any );
1157 ber_bvfree( sub->sa_initial );
1161 return LDAP_SUCCESS;
1164 /* Index generation function */
1165 static int caseExactIgnoreIndexer(
1170 struct berval *prefix,
1171 struct berval **values,
1172 struct berval ***keysp )
1177 struct berval **keys;
1178 HASH_CONTEXT HASHcontext;
1179 unsigned char HASHdigest[HASH_BYTES];
1180 struct berval digest;
1181 digest.bv_val = HASHdigest;
1182 digest.bv_len = sizeof(HASHdigest);
1184 for( i=0; values[i] != NULL; i++ ) {
1185 /* empty - just count them */
1188 /* we should have at least one value at this point */
1191 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
1193 slen = syntax->ssyn_oidlen;
1194 mlen = mr->smr_oidlen;
1196 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1197 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1199 for( i=0; values[i] != NULL; i++ ) {
1200 struct berval *value;
1201 value = ber_bvstr( UTF8normalize( values[i],
1204 HASH_Init( &HASHcontext );
1205 if( prefix != NULL && prefix->bv_len > 0 ) {
1206 HASH_Update( &HASHcontext,
1207 prefix->bv_val, prefix->bv_len );
1209 HASH_Update( &HASHcontext,
1210 syntax->ssyn_oid, slen );
1211 HASH_Update( &HASHcontext,
1212 mr->smr_oid, mlen );
1213 HASH_Update( &HASHcontext,
1214 value->bv_val, value->bv_len );
1215 HASH_Final( HASHdigest, &HASHcontext );
1217 ber_bvfree( value );
1219 keys[i] = ber_bvdup( &digest );
1224 return LDAP_SUCCESS;
1227 /* Index generation function */
1228 static int caseExactIgnoreFilter(
1233 struct berval *prefix,
1235 struct berval ***keysp )
1239 struct berval **keys;
1240 HASH_CONTEXT HASHcontext;
1241 unsigned char HASHdigest[HASH_BYTES];
1242 struct berval *value;
1243 struct berval digest;
1244 digest.bv_val = HASHdigest;
1245 digest.bv_len = sizeof(HASHdigest);
1247 slen = syntax->ssyn_oidlen;
1248 mlen = mr->smr_oidlen;
1250 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1251 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1253 value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue),
1255 /* This usually happens if filter contains bad UTF8 */
1256 if( value == NULL ) {
1257 keys = ch_malloc( sizeof( struct berval * ) );
1259 return LDAP_SUCCESS;
1262 keys = ch_malloc( sizeof( struct berval * ) * 2 );
1264 HASH_Init( &HASHcontext );
1265 if( prefix != NULL && prefix->bv_len > 0 ) {
1266 HASH_Update( &HASHcontext,
1267 prefix->bv_val, prefix->bv_len );
1269 HASH_Update( &HASHcontext,
1270 syntax->ssyn_oid, slen );
1271 HASH_Update( &HASHcontext,
1272 mr->smr_oid, mlen );
1273 HASH_Update( &HASHcontext,
1274 value->bv_val, value->bv_len );
1275 HASH_Final( HASHdigest, &HASHcontext );
1277 keys[0] = ber_bvdup( &digest );
1280 ber_bvfree( value );
1283 return LDAP_SUCCESS;
1286 /* Substrings Index generation function */
1287 static int caseExactIgnoreSubstringsIndexer(
1292 struct berval *prefix,
1293 struct berval **values,
1294 struct berval ***keysp )
1299 struct berval **keys;
1300 struct berval **nvalues;
1302 HASH_CONTEXT HASHcontext;
1303 unsigned char HASHdigest[HASH_BYTES];
1304 struct berval digest;
1305 digest.bv_val = HASHdigest;
1306 digest.bv_len = sizeof(HASHdigest);
1310 for( i=0; values[i] != NULL; i++ ) {
1311 /* empty - just count them */
1314 /* we should have at least one value at this point */
1317 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1318 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1320 nvalues = ch_malloc( sizeof( struct berval * ) * (i+1) );
1321 for( i=0; values[i] != NULL; i++ ) {
1322 nvalues[i] = ber_bvstr( UTF8normalize( values[i],
1328 for( i=0; values[i] != NULL; i++ ) {
1329 /* count number of indices to generate */
1330 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1334 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1335 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1336 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1337 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1339 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1343 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1344 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1345 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1349 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1350 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1351 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1352 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1354 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1360 /* no keys to generate */
1362 ber_bvecfree( nvalues );
1363 return LDAP_SUCCESS;
1366 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1368 slen = syntax->ssyn_oidlen;
1369 mlen = mr->smr_oidlen;
1372 for( i=0; values[i] != NULL; i++ ) {
1374 struct berval *value;
1376 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1380 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1381 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1383 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1384 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1386 for( j=0; j<max; j++ ) {
1387 HASH_Init( &HASHcontext );
1388 if( prefix != NULL && prefix->bv_len > 0 ) {
1389 HASH_Update( &HASHcontext,
1390 prefix->bv_val, prefix->bv_len );
1393 HASH_Update( &HASHcontext,
1394 &pre, sizeof( pre ) );
1395 HASH_Update( &HASHcontext,
1396 syntax->ssyn_oid, slen );
1397 HASH_Update( &HASHcontext,
1398 mr->smr_oid, mlen );
1399 HASH_Update( &HASHcontext,
1401 SLAP_INDEX_SUBSTR_MAXLEN );
1402 HASH_Final( HASHdigest, &HASHcontext );
1404 keys[nkeys++] = ber_bvdup( &digest );
1408 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1409 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1411 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1414 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1415 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1416 HASH_Init( &HASHcontext );
1417 if( prefix != NULL && prefix->bv_len > 0 ) {
1418 HASH_Update( &HASHcontext,
1419 prefix->bv_val, prefix->bv_len );
1421 HASH_Update( &HASHcontext,
1422 &pre, sizeof( pre ) );
1423 HASH_Update( &HASHcontext,
1424 syntax->ssyn_oid, slen );
1425 HASH_Update( &HASHcontext,
1426 mr->smr_oid, mlen );
1427 HASH_Update( &HASHcontext,
1429 HASH_Final( HASHdigest, &HASHcontext );
1431 keys[nkeys++] = ber_bvdup( &digest );
1434 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1435 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1436 HASH_Init( &HASHcontext );
1437 if( prefix != NULL && prefix->bv_len > 0 ) {
1438 HASH_Update( &HASHcontext,
1439 prefix->bv_val, prefix->bv_len );
1441 HASH_Update( &HASHcontext,
1442 &pre, sizeof( pre ) );
1443 HASH_Update( &HASHcontext,
1444 syntax->ssyn_oid, slen );
1445 HASH_Update( &HASHcontext,
1446 mr->smr_oid, mlen );
1447 HASH_Update( &HASHcontext,
1448 &value->bv_val[value->bv_len-j], j );
1449 HASH_Final( HASHdigest, &HASHcontext );
1451 keys[nkeys++] = ber_bvdup( &digest );
1466 ber_bvecfree( nvalues );
1468 return LDAP_SUCCESS;
1471 static int caseExactIgnoreSubstringsFilter(
1476 struct berval *prefix,
1478 struct berval ***keysp )
1480 SubstringsAssertion *sa;
1482 ber_len_t nkeys = 0;
1483 size_t slen, mlen, klen;
1484 struct berval **keys;
1485 HASH_CONTEXT HASHcontext;
1486 unsigned char HASHdigest[HASH_BYTES];
1487 struct berval *value;
1488 struct berval digest;
1490 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1491 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1493 sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
1496 return LDAP_SUCCESS;
1499 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1500 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1505 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1507 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1508 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1509 /* don't bother accounting for stepping */
1510 nkeys += sa->sa_any[i]->bv_len -
1511 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1516 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1517 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1523 ber_bvfree( sa->sa_final );
1524 ber_bvecfree( sa->sa_any );
1525 ber_bvfree( sa->sa_initial );
1528 return LDAP_SUCCESS;
1531 digest.bv_val = HASHdigest;
1532 digest.bv_len = sizeof(HASHdigest);
1534 slen = syntax->ssyn_oidlen;
1535 mlen = mr->smr_oidlen;
1537 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1540 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1541 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1543 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1544 value = sa->sa_initial;
1546 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1547 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1549 HASH_Init( &HASHcontext );
1550 if( prefix != NULL && prefix->bv_len > 0 ) {
1551 HASH_Update( &HASHcontext,
1552 prefix->bv_val, prefix->bv_len );
1554 HASH_Update( &HASHcontext,
1555 &pre, sizeof( pre ) );
1556 HASH_Update( &HASHcontext,
1557 syntax->ssyn_oid, slen );
1558 HASH_Update( &HASHcontext,
1559 mr->smr_oid, mlen );
1560 HASH_Update( &HASHcontext,
1561 value->bv_val, klen );
1562 HASH_Final( HASHdigest, &HASHcontext );
1564 keys[nkeys++] = ber_bvdup( &digest );
1567 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1569 pre = SLAP_INDEX_SUBSTR_PREFIX;
1570 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1572 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1573 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1577 value = sa->sa_any[i];
1580 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1581 j += SLAP_INDEX_SUBSTR_STEP )
1583 HASH_Init( &HASHcontext );
1584 if( prefix != NULL && prefix->bv_len > 0 ) {
1585 HASH_Update( &HASHcontext,
1586 prefix->bv_val, prefix->bv_len );
1588 HASH_Update( &HASHcontext,
1589 &pre, sizeof( pre ) );
1590 HASH_Update( &HASHcontext,
1591 syntax->ssyn_oid, slen );
1592 HASH_Update( &HASHcontext,
1593 mr->smr_oid, mlen );
1594 HASH_Update( &HASHcontext,
1595 &value->bv_val[j], klen );
1596 HASH_Final( HASHdigest, &HASHcontext );
1598 keys[nkeys++] = ber_bvdup( &digest );
1604 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1605 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1607 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1608 value = sa->sa_final;
1610 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1611 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1613 HASH_Init( &HASHcontext );
1614 if( prefix != NULL && prefix->bv_len > 0 ) {
1615 HASH_Update( &HASHcontext,
1616 prefix->bv_val, prefix->bv_len );
1618 HASH_Update( &HASHcontext,
1619 &pre, sizeof( pre ) );
1620 HASH_Update( &HASHcontext,
1621 syntax->ssyn_oid, slen );
1622 HASH_Update( &HASHcontext,
1623 mr->smr_oid, mlen );
1624 HASH_Update( &HASHcontext,
1625 &value->bv_val[value->bv_len-klen], klen );
1626 HASH_Final( HASHdigest, &HASHcontext );
1628 keys[nkeys++] = ber_bvdup( &digest );
1638 ber_bvfree( sa->sa_final );
1639 ber_bvecfree( sa->sa_any );
1640 ber_bvfree( sa->sa_initial );
1643 return LDAP_SUCCESS;
1652 struct berval *value,
1653 void *assertedValue )
1655 *matchp = UTF8normcmp( value->bv_val,
1656 ((struct berval *) assertedValue)->bv_val,
1658 return LDAP_SUCCESS;
1664 struct berval *val )
1668 if( val->bv_len == 0 ) {
1669 /* disallow empty strings */
1670 return LDAP_INVALID_SYNTAX;
1673 if( OID_LEADCHAR(val->bv_val[0]) ) {
1675 for(i=1; i < val->bv_len; i++) {
1676 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1677 if( dot++ ) return 1;
1678 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1681 return LDAP_INVALID_SYNTAX;
1685 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1687 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1688 for(i=1; i < val->bv_len; i++) {
1689 if( !DESC_CHAR(val->bv_val[i] ) ) {
1690 return LDAP_INVALID_SYNTAX;
1694 return LDAP_SUCCESS;
1697 return LDAP_INVALID_SYNTAX;
1706 struct berval *value,
1707 void *assertedValue )
1710 int vsign=0, avsign=0;
1711 struct berval *asserted;
1712 ber_len_t vlen, avlen;
1715 /* Start off pessimistic */
1718 /* Skip past leading spaces/zeros, and get the sign of the *value number */
1720 vlen = value->bv_len;
1722 if( ASCII_SPACE(*v) || ( *v == '0' )) {
1723 /* empty -- skip spaces */
1725 else if ( *v == '+' ) {
1728 else if ( *v == '-' ) {
1731 else if ( ASCII_DIGIT(*v) ) {
1732 if ( vsign == 0 ) vsign = 1;
1740 /* Skip past leading spaces/zeros, and get the sign of the *assertedValue
1742 asserted = (struct berval *) assertedValue;
1743 av = asserted->bv_val;
1744 avlen = asserted->bv_len;
1746 if( ASCII_SPACE(*av) || ( *av == '0' )) {
1747 /* empty -- skip spaces */
1749 else if ( *av == '+' ) {
1752 else if ( *av == '-' ) {
1755 else if ( ASCII_DIGIT(*av) ) {
1756 if ( avsign == 0 ) avsign = 1;
1764 /* The two ?sign vars are now one of :
1765 -2 negative non-zero number
1767 0 0 collapse these three to 0
1769 +2 positive non-zero number
1771 if ( abs( vsign ) == 1 ) vsign = 0;
1772 if ( abs( avsign ) == 1 ) avsign = 0;
1774 if( vsign != avsign ) return LDAP_SUCCESS;
1776 /* Check the significant digits */
1777 while( vlen && avlen ) {
1778 if( *v != *av ) break;
1785 /* If all digits compared equal, the numbers are equal */
1786 if(( vlen == 0 ) && ( avlen == 0 )) {
1789 return LDAP_SUCCESS;
1795 struct berval *val )
1799 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1801 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
1802 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1803 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1804 return LDAP_INVALID_SYNTAX;
1807 for( i=1; i < val->bv_len; i++ ) {
1808 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1811 return LDAP_SUCCESS;
1818 struct berval **normalized )
1822 struct berval *newval;
1829 /* Ignore leading spaces */
1830 while ( len && ( *p == ' ' )) {
1837 negative = ( *p == '-' );
1838 if(( *p == '-' ) || ( *p == '+' )) {
1844 /* Ignore leading zeros */
1845 while ( len && ( *p == '0' )) {
1850 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
1852 /* If there are no non-zero digits left, the number is zero, otherwise
1853 allocate space for the number and copy it into the buffer */
1855 newval->bv_val = ch_strdup("0");
1859 newval->bv_len = len+negative;
1860 newval->bv_val = ch_malloc( newval->bv_len );
1862 newval->bv_val[0] = '-';
1864 memcpy( newval->bv_val + negative, p, len );
1867 *normalized = newval;
1868 return LDAP_SUCCESS;
1871 /* Index generation function */
1872 static int integerIndexer(
1877 struct berval *prefix,
1878 struct berval **values,
1879 struct berval ***keysp )
1882 struct berval **keys;
1884 /* we should have at least one value at this point */
1885 assert( values != NULL && values[0] != NULL );
1887 for( i=0; values[i] != NULL; i++ ) {
1888 /* empty -- just count them */
1891 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
1893 for( i=0; values[i] != NULL; i++ ) {
1894 integerNormalize( syntax, values[i], &keys[i] );
1899 return LDAP_SUCCESS;
1902 /* Index generation function */
1903 static int integerFilter(
1908 struct berval *prefix,
1910 struct berval ***keysp )
1912 struct berval **keys;
1914 keys = ch_malloc( sizeof( struct berval * ) * 2 );
1915 integerNormalize( syntax, assertValue, &keys[0] );
1919 return LDAP_SUCCESS;
1924 countryStringValidate(
1926 struct berval *val )
1928 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
1930 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
1931 return LDAP_INVALID_SYNTAX;
1933 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
1934 return LDAP_INVALID_SYNTAX;
1937 return LDAP_SUCCESS;
1941 printableStringValidate(
1943 struct berval *val )
1947 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1949 for(i=0; i < val->bv_len; i++) {
1950 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
1951 return LDAP_INVALID_SYNTAX;
1955 return LDAP_SUCCESS;
1959 printablesStringValidate(
1961 struct berval *val )
1965 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1967 for(i=0; i < val->bv_len; i++) {
1968 if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
1969 return LDAP_INVALID_SYNTAX;
1973 return LDAP_SUCCESS;
1979 struct berval *val )
1983 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1985 for(i=0; i < val->bv_len; i++) {
1986 if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1989 return LDAP_SUCCESS;
1996 struct berval **normalized )
1998 struct berval *newval;
2001 newval = ch_malloc( sizeof( struct berval ) );
2005 /* Ignore initial whitespace */
2006 while ( ASCII_SPACE( *p ) ) {
2012 return LDAP_INVALID_SYNTAX;
2015 newval->bv_val = ch_strdup( p );
2016 p = q = newval->bv_val;
2019 if ( ASCII_SPACE( *p ) ) {
2022 /* Ignore the extra whitespace */
2023 while ( ASCII_SPACE( *p ) ) {
2031 assert( *newval->bv_val );
2032 assert( newval->bv_val < p );
2035 /* cannot start with a space */
2036 assert( !ASCII_SPACE(*newval->bv_val) );
2039 * If the string ended in space, backup the pointer one
2040 * position. One is enough because the above loop collapsed
2041 * all whitespace to a single space.
2044 if ( ASCII_SPACE( q[-1] ) ) {
2048 /* cannot end with a space */
2049 assert( !ASCII_SPACE( q[-1] ) );
2051 /* null terminate */
2054 newval->bv_len = q - newval->bv_val;
2055 *normalized = newval;
2057 return LDAP_SUCCESS;
2066 struct berval *value,
2067 void *assertedValue )
2069 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2072 match = strncmp( value->bv_val,
2073 ((struct berval *) assertedValue)->bv_val,
2078 return LDAP_SUCCESS;
2082 caseExactIA5SubstringsMatch(
2087 struct berval *value,
2088 void *assertedValue )
2091 SubstringsAssertion *sub = assertedValue;
2092 struct berval left = *value;
2096 /* Add up asserted input length */
2097 if( sub->sa_initial ) {
2098 inlen += sub->sa_initial->bv_len;
2101 for(i=0; sub->sa_any[i] != NULL; i++) {
2102 inlen += sub->sa_any[i]->bv_len;
2105 if( sub->sa_final ) {
2106 inlen += sub->sa_final->bv_len;
2109 if( sub->sa_initial ) {
2110 if( inlen > left.bv_len ) {
2115 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
2116 sub->sa_initial->bv_len );
2122 left.bv_val += sub->sa_initial->bv_len;
2123 left.bv_len -= sub->sa_initial->bv_len;
2124 inlen -= sub->sa_initial->bv_len;
2127 if( sub->sa_final ) {
2128 if( inlen > left.bv_len ) {
2133 match = strncmp( sub->sa_final->bv_val,
2134 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2135 sub->sa_final->bv_len );
2141 left.bv_len -= sub->sa_final->bv_len;
2142 inlen -= sub->sa_final->bv_len;
2146 for(i=0; sub->sa_any[i]; i++) {
2151 if( inlen > left.bv_len ) {
2152 /* not enough length */
2157 if( sub->sa_any[i]->bv_len == 0 ) {
2161 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
2168 idx = p - left.bv_val;
2169 assert( idx < left.bv_len );
2171 if( idx >= left.bv_len ) {
2172 /* this shouldn't happen */
2179 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2180 /* not enough left */
2185 match = strncmp( left.bv_val,
2186 sub->sa_any[i]->bv_val,
2187 sub->sa_any[i]->bv_len );
2195 left.bv_val += sub->sa_any[i]->bv_len;
2196 left.bv_len -= sub->sa_any[i]->bv_len;
2197 inlen -= sub->sa_any[i]->bv_len;
2203 return LDAP_SUCCESS;
2206 /* Index generation function */
2207 static int caseExactIA5Indexer(
2212 struct berval *prefix,
2213 struct berval **values,
2214 struct berval ***keysp )
2218 struct berval **keys;
2219 HASH_CONTEXT HASHcontext;
2220 unsigned char HASHdigest[HASH_BYTES];
2221 struct berval digest;
2222 digest.bv_val = HASHdigest;
2223 digest.bv_len = sizeof(HASHdigest);
2225 for( i=0; values[i] != NULL; i++ ) {
2226 /* empty - just count them */
2229 /* we should have at least one value at this point */
2232 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2234 slen = syntax->ssyn_oidlen;
2235 mlen = mr->smr_oidlen;
2237 for( i=0; values[i] != NULL; i++ ) {
2238 struct berval *value = values[i];
2240 HASH_Init( &HASHcontext );
2241 if( prefix != NULL && prefix->bv_len > 0 ) {
2242 HASH_Update( &HASHcontext,
2243 prefix->bv_val, prefix->bv_len );
2245 HASH_Update( &HASHcontext,
2246 syntax->ssyn_oid, slen );
2247 HASH_Update( &HASHcontext,
2248 mr->smr_oid, mlen );
2249 HASH_Update( &HASHcontext,
2250 value->bv_val, value->bv_len );
2251 HASH_Final( HASHdigest, &HASHcontext );
2253 keys[i] = ber_bvdup( &digest );
2258 return LDAP_SUCCESS;
2261 /* Index generation function */
2262 static int caseExactIA5Filter(
2267 struct berval *prefix,
2269 struct berval ***keysp )
2272 struct berval **keys;
2273 HASH_CONTEXT HASHcontext;
2274 unsigned char HASHdigest[HASH_BYTES];
2275 struct berval *value;
2276 struct berval digest;
2277 digest.bv_val = HASHdigest;
2278 digest.bv_len = sizeof(HASHdigest);
2280 slen = syntax->ssyn_oidlen;
2281 mlen = mr->smr_oidlen;
2283 value = (struct berval *) assertValue;
2285 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2287 HASH_Init( &HASHcontext );
2288 if( prefix != NULL && prefix->bv_len > 0 ) {
2289 HASH_Update( &HASHcontext,
2290 prefix->bv_val, prefix->bv_len );
2292 HASH_Update( &HASHcontext,
2293 syntax->ssyn_oid, slen );
2294 HASH_Update( &HASHcontext,
2295 mr->smr_oid, mlen );
2296 HASH_Update( &HASHcontext,
2297 value->bv_val, value->bv_len );
2298 HASH_Final( HASHdigest, &HASHcontext );
2300 keys[0] = ber_bvdup( &digest );
2304 return LDAP_SUCCESS;
2307 /* Substrings Index generation function */
2308 static int caseExactIA5SubstringsIndexer(
2313 struct berval *prefix,
2314 struct berval **values,
2315 struct berval ***keysp )
2319 struct berval **keys;
2320 HASH_CONTEXT HASHcontext;
2321 unsigned char HASHdigest[HASH_BYTES];
2322 struct berval digest;
2323 digest.bv_val = HASHdigest;
2324 digest.bv_len = sizeof(HASHdigest);
2326 /* we should have at least one value at this point */
2327 assert( values != NULL && values[0] != NULL );
2330 for( i=0; values[i] != NULL; i++ ) {
2331 /* count number of indices to generate */
2332 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2336 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2337 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2338 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2339 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2341 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2345 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2346 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2347 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2351 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2352 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2353 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2354 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2356 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2362 /* no keys to generate */
2364 return LDAP_SUCCESS;
2367 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2369 slen = syntax->ssyn_oidlen;
2370 mlen = mr->smr_oidlen;
2373 for( i=0; values[i] != NULL; i++ ) {
2375 struct berval *value;
2378 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2380 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2381 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2383 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2384 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2386 for( j=0; j<max; j++ ) {
2387 HASH_Init( &HASHcontext );
2388 if( prefix != NULL && prefix->bv_len > 0 ) {
2389 HASH_Update( &HASHcontext,
2390 prefix->bv_val, prefix->bv_len );
2393 HASH_Update( &HASHcontext,
2394 &pre, sizeof( pre ) );
2395 HASH_Update( &HASHcontext,
2396 syntax->ssyn_oid, slen );
2397 HASH_Update( &HASHcontext,
2398 mr->smr_oid, mlen );
2399 HASH_Update( &HASHcontext,
2401 SLAP_INDEX_SUBSTR_MAXLEN );
2402 HASH_Final( HASHdigest, &HASHcontext );
2404 keys[nkeys++] = ber_bvdup( &digest );
2408 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2409 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2411 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2414 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2415 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2416 HASH_Init( &HASHcontext );
2417 if( prefix != NULL && prefix->bv_len > 0 ) {
2418 HASH_Update( &HASHcontext,
2419 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 HASH_Final( HASHdigest, &HASHcontext );
2431 keys[nkeys++] = ber_bvdup( &digest );
2434 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2435 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2436 HASH_Init( &HASHcontext );
2437 if( prefix != NULL && prefix->bv_len > 0 ) {
2438 HASH_Update( &HASHcontext,
2439 prefix->bv_val, prefix->bv_len );
2441 HASH_Update( &HASHcontext,
2442 &pre, sizeof( pre ) );
2443 HASH_Update( &HASHcontext,
2444 syntax->ssyn_oid, slen );
2445 HASH_Update( &HASHcontext,
2446 mr->smr_oid, mlen );
2447 HASH_Update( &HASHcontext,
2448 &value->bv_val[value->bv_len-j], j );
2449 HASH_Final( HASHdigest, &HASHcontext );
2451 keys[nkeys++] = ber_bvdup( &digest );
2465 return LDAP_SUCCESS;
2468 static int caseExactIA5SubstringsFilter(
2473 struct berval *prefix,
2475 struct berval ***keysp )
2477 SubstringsAssertion *sa = assertValue;
2479 ber_len_t nkeys = 0;
2480 size_t slen, mlen, klen;
2481 struct berval **keys;
2482 HASH_CONTEXT HASHcontext;
2483 unsigned char HASHdigest[HASH_BYTES];
2484 struct berval *value;
2485 struct berval digest;
2487 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2488 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2493 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2495 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2496 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2497 /* don't bother accounting for stepping */
2498 nkeys += sa->sa_any[i]->bv_len -
2499 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2504 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2505 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2512 return LDAP_SUCCESS;
2515 digest.bv_val = HASHdigest;
2516 digest.bv_len = sizeof(HASHdigest);
2518 slen = syntax->ssyn_oidlen;
2519 mlen = mr->smr_oidlen;
2521 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2524 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2525 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2527 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2528 value = sa->sa_initial;
2530 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2531 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2533 HASH_Init( &HASHcontext );
2534 if( prefix != NULL && prefix->bv_len > 0 ) {
2535 HASH_Update( &HASHcontext,
2536 prefix->bv_val, prefix->bv_len );
2538 HASH_Update( &HASHcontext,
2539 &pre, sizeof( pre ) );
2540 HASH_Update( &HASHcontext,
2541 syntax->ssyn_oid, slen );
2542 HASH_Update( &HASHcontext,
2543 mr->smr_oid, mlen );
2544 HASH_Update( &HASHcontext,
2545 value->bv_val, klen );
2546 HASH_Final( HASHdigest, &HASHcontext );
2548 keys[nkeys++] = ber_bvdup( &digest );
2551 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2553 pre = SLAP_INDEX_SUBSTR_PREFIX;
2554 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2556 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2557 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2561 value = sa->sa_any[i];
2564 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2565 j += SLAP_INDEX_SUBSTR_STEP )
2567 HASH_Init( &HASHcontext );
2568 if( prefix != NULL && prefix->bv_len > 0 ) {
2569 HASH_Update( &HASHcontext,
2570 prefix->bv_val, prefix->bv_len );
2572 HASH_Update( &HASHcontext,
2573 &pre, sizeof( pre ) );
2574 HASH_Update( &HASHcontext,
2575 syntax->ssyn_oid, slen );
2576 HASH_Update( &HASHcontext,
2577 mr->smr_oid, mlen );
2578 HASH_Update( &HASHcontext,
2579 &value->bv_val[j], klen );
2580 HASH_Final( HASHdigest, &HASHcontext );
2582 keys[nkeys++] = ber_bvdup( &digest );
2587 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2588 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2590 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2591 value = sa->sa_final;
2593 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2594 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2596 HASH_Init( &HASHcontext );
2597 if( prefix != NULL && prefix->bv_len > 0 ) {
2598 HASH_Update( &HASHcontext,
2599 prefix->bv_val, prefix->bv_len );
2601 HASH_Update( &HASHcontext,
2602 &pre, sizeof( pre ) );
2603 HASH_Update( &HASHcontext,
2604 syntax->ssyn_oid, slen );
2605 HASH_Update( &HASHcontext,
2606 mr->smr_oid, mlen );
2607 HASH_Update( &HASHcontext,
2608 &value->bv_val[value->bv_len-klen], klen );
2609 HASH_Final( HASHdigest, &HASHcontext );
2611 keys[nkeys++] = ber_bvdup( &digest );
2622 return LDAP_SUCCESS;
2631 struct berval *value,
2632 void *assertedValue )
2634 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2636 if( match == 0 && value->bv_len ) {
2637 match = strncasecmp( value->bv_val,
2638 ((struct berval *) assertedValue)->bv_val,
2643 return LDAP_SUCCESS;
2647 caseIgnoreIA5SubstringsMatch(
2652 struct berval *value,
2653 void *assertedValue )
2656 SubstringsAssertion *sub = assertedValue;
2657 struct berval left = *value;
2661 /* Add up asserted input length */
2662 if( sub->sa_initial ) {
2663 inlen += sub->sa_initial->bv_len;
2666 for(i=0; sub->sa_any[i] != NULL; i++) {
2667 inlen += sub->sa_any[i]->bv_len;
2670 if( sub->sa_final ) {
2671 inlen += sub->sa_final->bv_len;
2674 if( sub->sa_initial ) {
2675 if( inlen > left.bv_len ) {
2680 match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
2681 sub->sa_initial->bv_len );
2687 left.bv_val += sub->sa_initial->bv_len;
2688 left.bv_len -= sub->sa_initial->bv_len;
2689 inlen -= sub->sa_initial->bv_len;
2692 if( sub->sa_final ) {
2693 if( inlen > left.bv_len ) {
2698 match = strncasecmp( sub->sa_final->bv_val,
2699 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2700 sub->sa_final->bv_len );
2706 left.bv_len -= sub->sa_final->bv_len;
2707 inlen -= sub->sa_final->bv_len;
2711 for(i=0; sub->sa_any[i]; i++) {
2716 if( inlen > left.bv_len ) {
2717 /* not enough length */
2722 if( sub->sa_any[i]->bv_len == 0 ) {
2726 p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
2733 idx = p - left.bv_val;
2734 assert( idx < left.bv_len );
2736 if( idx >= left.bv_len ) {
2737 /* this shouldn't happen */
2744 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2745 /* not enough left */
2750 match = strncasecmp( left.bv_val,
2751 sub->sa_any[i]->bv_val,
2752 sub->sa_any[i]->bv_len );
2761 left.bv_val += sub->sa_any[i]->bv_len;
2762 left.bv_len -= sub->sa_any[i]->bv_len;
2763 inlen -= sub->sa_any[i]->bv_len;
2769 return LDAP_SUCCESS;
2772 /* Index generation function */
2773 static int caseIgnoreIA5Indexer(
2778 struct berval *prefix,
2779 struct berval **values,
2780 struct berval ***keysp )
2784 struct berval **keys;
2785 HASH_CONTEXT HASHcontext;
2786 unsigned char HASHdigest[HASH_BYTES];
2787 struct berval digest;
2788 digest.bv_val = HASHdigest;
2789 digest.bv_len = sizeof(HASHdigest);
2791 /* we should have at least one value at this point */
2792 assert( values != NULL && values[0] != NULL );
2794 for( i=0; values[i] != NULL; i++ ) {
2795 /* just count them */
2798 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2800 slen = syntax->ssyn_oidlen;
2801 mlen = mr->smr_oidlen;
2803 for( i=0; values[i] != NULL; i++ ) {
2804 struct berval *value = ber_bvdup( values[i] );
2805 ldap_pvt_str2upper( value->bv_val );
2807 HASH_Init( &HASHcontext );
2808 if( prefix != NULL && prefix->bv_len > 0 ) {
2809 HASH_Update( &HASHcontext,
2810 prefix->bv_val, prefix->bv_len );
2812 HASH_Update( &HASHcontext,
2813 syntax->ssyn_oid, slen );
2814 HASH_Update( &HASHcontext,
2815 mr->smr_oid, mlen );
2816 HASH_Update( &HASHcontext,
2817 value->bv_val, value->bv_len );
2818 HASH_Final( HASHdigest, &HASHcontext );
2820 ber_bvfree( value );
2822 keys[i] = ber_bvdup( &digest );
2827 return LDAP_SUCCESS;
2830 /* Index generation function */
2831 static int caseIgnoreIA5Filter(
2836 struct berval *prefix,
2838 struct berval ***keysp )
2841 struct berval **keys;
2842 HASH_CONTEXT HASHcontext;
2843 unsigned char HASHdigest[HASH_BYTES];
2844 struct berval *value;
2845 struct berval digest;
2846 digest.bv_val = HASHdigest;
2847 digest.bv_len = sizeof(HASHdigest);
2849 slen = syntax->ssyn_oidlen;
2850 mlen = mr->smr_oidlen;
2852 value = ber_bvdup( (struct berval *) assertValue );
2853 ldap_pvt_str2upper( value->bv_val );
2855 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2857 HASH_Init( &HASHcontext );
2858 if( prefix != NULL && prefix->bv_len > 0 ) {
2859 HASH_Update( &HASHcontext,
2860 prefix->bv_val, prefix->bv_len );
2862 HASH_Update( &HASHcontext,
2863 syntax->ssyn_oid, slen );
2864 HASH_Update( &HASHcontext,
2865 mr->smr_oid, mlen );
2866 HASH_Update( &HASHcontext,
2867 value->bv_val, value->bv_len );
2868 HASH_Final( HASHdigest, &HASHcontext );
2870 keys[0] = ber_bvdup( &digest );
2873 ber_bvfree( value );
2877 return LDAP_SUCCESS;
2880 /* Substrings Index generation function */
2881 static int caseIgnoreIA5SubstringsIndexer(
2886 struct berval *prefix,
2887 struct berval **values,
2888 struct berval ***keysp )
2892 struct berval **keys;
2893 HASH_CONTEXT HASHcontext;
2894 unsigned char HASHdigest[HASH_BYTES];
2895 struct berval digest;
2896 digest.bv_val = HASHdigest;
2897 digest.bv_len = sizeof(HASHdigest);
2899 /* we should have at least one value at this point */
2900 assert( values != NULL && values[0] != NULL );
2903 for( i=0; values[i] != NULL; i++ ) {
2904 /* count number of indices to generate */
2905 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2909 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2910 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2911 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2912 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2914 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2918 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2919 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2920 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2924 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2925 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2926 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2927 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2929 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2935 /* no keys to generate */
2937 return LDAP_SUCCESS;
2940 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2942 slen = syntax->ssyn_oidlen;
2943 mlen = mr->smr_oidlen;
2946 for( i=0; values[i] != NULL; i++ ) {
2948 struct berval *value;
2950 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2952 value = ber_bvdup( values[i] );
2953 ldap_pvt_str2upper( value->bv_val );
2955 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2956 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2958 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2959 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2961 for( j=0; j<max; j++ ) {
2962 HASH_Init( &HASHcontext );
2963 if( prefix != NULL && prefix->bv_len > 0 ) {
2964 HASH_Update( &HASHcontext,
2965 prefix->bv_val, prefix->bv_len );
2968 HASH_Update( &HASHcontext,
2969 &pre, sizeof( pre ) );
2970 HASH_Update( &HASHcontext,
2971 syntax->ssyn_oid, slen );
2972 HASH_Update( &HASHcontext,
2973 mr->smr_oid, mlen );
2974 HASH_Update( &HASHcontext,
2976 SLAP_INDEX_SUBSTR_MAXLEN );
2977 HASH_Final( HASHdigest, &HASHcontext );
2979 keys[nkeys++] = ber_bvdup( &digest );
2983 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2984 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2986 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2989 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2990 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2991 HASH_Init( &HASHcontext );
2992 if( prefix != NULL && prefix->bv_len > 0 ) {
2993 HASH_Update( &HASHcontext,
2994 prefix->bv_val, prefix->bv_len );
2996 HASH_Update( &HASHcontext,
2997 &pre, sizeof( pre ) );
2998 HASH_Update( &HASHcontext,
2999 syntax->ssyn_oid, slen );
3000 HASH_Update( &HASHcontext,
3001 mr->smr_oid, mlen );
3002 HASH_Update( &HASHcontext,
3004 HASH_Final( HASHdigest, &HASHcontext );
3006 keys[nkeys++] = ber_bvdup( &digest );
3009 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3010 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3011 HASH_Init( &HASHcontext );
3012 if( prefix != NULL && prefix->bv_len > 0 ) {
3013 HASH_Update( &HASHcontext,
3014 prefix->bv_val, prefix->bv_len );
3016 HASH_Update( &HASHcontext,
3017 &pre, sizeof( pre ) );
3018 HASH_Update( &HASHcontext,
3019 syntax->ssyn_oid, slen );
3020 HASH_Update( &HASHcontext,
3021 mr->smr_oid, mlen );
3022 HASH_Update( &HASHcontext,
3023 &value->bv_val[value->bv_len-j], j );
3024 HASH_Final( HASHdigest, &HASHcontext );
3026 keys[nkeys++] = ber_bvdup( &digest );
3031 ber_bvfree( value );
3042 return LDAP_SUCCESS;
3045 static int caseIgnoreIA5SubstringsFilter(
3050 struct berval *prefix,
3052 struct berval ***keysp )
3054 SubstringsAssertion *sa = assertValue;
3056 ber_len_t nkeys = 0;
3057 size_t slen, mlen, klen;
3058 struct berval **keys;
3059 HASH_CONTEXT HASHcontext;
3060 unsigned char HASHdigest[HASH_BYTES];
3061 struct berval *value;
3062 struct berval digest;
3064 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3065 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3070 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3072 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3073 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3074 /* don't bother accounting for stepping */
3075 nkeys += sa->sa_any[i]->bv_len -
3076 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3081 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3082 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3089 return LDAP_SUCCESS;
3092 digest.bv_val = HASHdigest;
3093 digest.bv_len = sizeof(HASHdigest);
3095 slen = syntax->ssyn_oidlen;
3096 mlen = mr->smr_oidlen;
3098 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
3101 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3102 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3104 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3105 value = ber_bvdup( sa->sa_initial );
3106 ldap_pvt_str2upper( value->bv_val );
3108 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3109 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3111 HASH_Init( &HASHcontext );
3112 if( prefix != NULL && prefix->bv_len > 0 ) {
3113 HASH_Update( &HASHcontext,
3114 prefix->bv_val, prefix->bv_len );
3116 HASH_Update( &HASHcontext,
3117 &pre, sizeof( pre ) );
3118 HASH_Update( &HASHcontext,
3119 syntax->ssyn_oid, slen );
3120 HASH_Update( &HASHcontext,
3121 mr->smr_oid, mlen );
3122 HASH_Update( &HASHcontext,
3123 value->bv_val, klen );
3124 HASH_Final( HASHdigest, &HASHcontext );
3126 ber_bvfree( value );
3127 keys[nkeys++] = ber_bvdup( &digest );
3130 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3132 pre = SLAP_INDEX_SUBSTR_PREFIX;
3133 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3135 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3136 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3140 value = ber_bvdup( sa->sa_any[i] );
3141 ldap_pvt_str2upper( value->bv_val );
3144 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3145 j += SLAP_INDEX_SUBSTR_STEP )
3147 HASH_Init( &HASHcontext );
3148 if( prefix != NULL && prefix->bv_len > 0 ) {
3149 HASH_Update( &HASHcontext,
3150 prefix->bv_val, prefix->bv_len );
3152 HASH_Update( &HASHcontext,
3153 &pre, sizeof( pre ) );
3154 HASH_Update( &HASHcontext,
3155 syntax->ssyn_oid, slen );
3156 HASH_Update( &HASHcontext,
3157 mr->smr_oid, mlen );
3158 HASH_Update( &HASHcontext,
3159 &value->bv_val[j], klen );
3160 HASH_Final( HASHdigest, &HASHcontext );
3162 keys[nkeys++] = ber_bvdup( &digest );
3165 ber_bvfree( value );
3169 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3170 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3172 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3173 value = ber_bvdup( sa->sa_final );
3174 ldap_pvt_str2upper( value->bv_val );
3176 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3177 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3179 HASH_Init( &HASHcontext );
3180 if( prefix != NULL && prefix->bv_len > 0 ) {
3181 HASH_Update( &HASHcontext,
3182 prefix->bv_val, prefix->bv_len );
3184 HASH_Update( &HASHcontext,
3185 &pre, sizeof( pre ) );
3186 HASH_Update( &HASHcontext,
3187 syntax->ssyn_oid, slen );
3188 HASH_Update( &HASHcontext,
3189 mr->smr_oid, mlen );
3190 HASH_Update( &HASHcontext,
3191 &value->bv_val[value->bv_len-klen], klen );
3192 HASH_Final( HASHdigest, &HASHcontext );
3194 ber_bvfree( value );
3195 keys[nkeys++] = ber_bvdup( &digest );
3206 return LDAP_SUCCESS;
3210 numericStringValidate(
3216 for(i=0; i < in->bv_len; i++) {
3217 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3218 return LDAP_INVALID_SYNTAX;
3222 return LDAP_SUCCESS;
3226 numericStringNormalize(
3229 struct berval **normalized )
3231 /* removal all spaces */
3232 struct berval *newval;
3235 newval = ch_malloc( sizeof( struct berval ) );
3236 newval->bv_val = ch_malloc( val->bv_len + 1 );
3242 if ( ASCII_SPACE( *p ) ) {
3243 /* Ignore whitespace */
3250 /* we should have copied no more then is in val */
3251 assert( (q - newval->bv_val) <= (p - val->bv_val) );
3253 /* null terminate */
3256 newval->bv_len = q - newval->bv_val;
3257 *normalized = newval;
3259 return LDAP_SUCCESS;
3263 objectIdentifierFirstComponentMatch(
3268 struct berval *value,
3269 void *assertedValue )
3271 int rc = LDAP_SUCCESS;
3273 struct berval *asserted = (struct berval *) assertedValue;
3277 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3278 return LDAP_INVALID_SYNTAX;
3281 /* trim leading white space */
3282 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3286 /* grab next word */
3287 oid.bv_val = &value->bv_val[i];
3288 oid.bv_len = value->bv_len - i;
3289 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3294 /* insert attributeTypes, objectclass check here */
3295 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3296 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3299 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3300 MatchingRule *asserted_mr = mr_bvfind( asserted );
3301 MatchingRule *stored_mr = mr_bvfind( &oid );
3303 if( asserted_mr == NULL ) {
3304 rc = SLAPD_COMPARE_UNDEFINED;
3306 match = asserted_mr != stored_mr;
3309 } else if ( !strcmp( syntax->ssyn_oid,
3310 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3312 AttributeType *asserted_at = at_bvfind( asserted );
3313 AttributeType *stored_at = at_bvfind( &oid );
3315 if( asserted_at == NULL ) {
3316 rc = SLAPD_COMPARE_UNDEFINED;
3318 match = asserted_at != stored_at;
3321 } else if ( !strcmp( syntax->ssyn_oid,
3322 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3324 ObjectClass *asserted_oc = oc_bvfind( asserted );
3325 ObjectClass *stored_oc = oc_bvfind( &oid );
3327 if( asserted_oc == NULL ) {
3328 rc = SLAPD_COMPARE_UNDEFINED;
3330 match = asserted_oc != stored_oc;
3336 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3337 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3338 match, value->bv_val, asserted->bv_val ));
3340 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3341 "%d\n\t\"%s\"\n\t\"%s\"\n",
3342 match, value->bv_val, asserted->bv_val );
3346 if( rc == LDAP_SUCCESS ) *matchp = match;
3356 struct berval *value,
3357 void *assertedValue )
3359 long lValue, lAssertedValue;
3361 /* safe to assume integers are NUL terminated? */
3362 lValue = strtoul(value->bv_val, NULL, 10);
3363 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3364 return LDAP_CONSTRAINT_VIOLATION;
3366 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3367 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3368 return LDAP_CONSTRAINT_VIOLATION;
3370 *matchp = (lValue & lAssertedValue);
3371 return LDAP_SUCCESS;
3380 struct berval *value,
3381 void *assertedValue )
3383 long lValue, lAssertedValue;
3385 /* safe to assume integers are NUL terminated? */
3386 lValue = strtoul(value->bv_val, NULL, 10);
3387 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3388 return LDAP_CONSTRAINT_VIOLATION;
3390 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3391 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3392 return LDAP_CONSTRAINT_VIOLATION;
3394 *matchp = (lValue | lAssertedValue);
3395 return LDAP_SUCCESS;
3399 #include <openssl/x509.h>
3400 #include <openssl/err.h>
3401 char digit[] = "0123456789";
3404 * Next function returns a string representation of a ASN1_INTEGER.
3405 * It works for unlimited lengths.
3408 static struct berval *
3409 asn1_integer2str(ASN1_INTEGER *a)
3414 /* We work backwards, make it fill from the end of buf */
3415 p = buf + sizeof(buf) - 1;
3418 if ( a == NULL || a->length == 0 ) {
3426 /* We want to preserve the original */
3427 copy = ch_malloc(n*sizeof(unsigned int));
3428 for (i = 0; i<n; i++) {
3429 copy[i] = a->data[i];
3433 * base indicates the index of the most significant
3434 * byte that might be nonzero. When it goes off the
3435 * end, we now there is nothing left to do.
3441 for (i = base; i<n; i++ ) {
3442 copy[i] += carry*256;
3443 carry = copy[i] % 10;
3448 * Way too large, we need to leave
3449 * room for sign if negative
3454 *--p = digit[carry];
3455 if (copy[base] == 0)
3461 if ( a->type == V_ASN1_NEG_INTEGER ) {
3465 return ber_bvstrdup(p);
3468 /* Get a DN in RFC2253 format from a X509_NAME internal struct */
3469 static struct berval *
3470 dn_openssl2ldap(X509_NAME *name)
3472 char issuer_dn[1024];
3475 bio = BIO_new(BIO_s_mem());
3478 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3479 "dn_openssl2ldap: error creating BIO_s_mem: %s\n",
3480 ERR_error_string(ERR_get_error(),NULL)));
3482 Debug( LDAP_DEBUG_ARGS, "dn_openssl2ldap: "
3483 "error creating BIO: %s\n",
3484 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3488 X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253);
3490 BIO_gets(bio, issuer_dn, 1024);
3493 return ber_bvstrdup(issuer_dn);
3497 * Given a certificate in DER format, extract the corresponding
3498 * assertion value for certificateExactMatch
3501 certificateExactConvert(
3503 struct berval ** out )
3506 unsigned char *p = in->bv_val;
3507 struct berval *serial;
3508 struct berval *issuer_dn;
3509 struct berval *bv_tmp;
3511 xcert = d2i_X509(NULL, &p, in->bv_len);
3514 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3515 "certificateExactConvert: error parsing cert: %s\n",
3516 ERR_error_string(ERR_get_error(),NULL)));
3518 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3519 "error parsing cert: %s\n",
3520 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3522 return LDAP_INVALID_SYNTAX;
3525 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3528 return LDAP_INVALID_SYNTAX;
3530 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
3534 return LDAP_INVALID_SYNTAX;
3536 /* Actually, dn_openssl2ldap returns in a normalized format, but
3537 it is different from our normalized format */
3539 if ( dnNormalize(NULL, bv_tmp, &issuer_dn) != LDAP_SUCCESS ) {
3543 return LDAP_INVALID_SYNTAX;
3549 *out = ch_malloc(sizeof(struct berval));
3550 (*out)->bv_len = serial->bv_len + 3 + issuer_dn->bv_len + 1;
3551 (*out)->bv_val = ch_malloc((*out)->bv_len);
3553 AC_MEMCPY(p, serial->bv_val, serial->bv_len);
3554 p += serial->bv_len;
3555 AC_MEMCPY(p, " $ ", 3);
3557 AC_MEMCPY(p, issuer_dn->bv_val, issuer_dn->bv_len);
3558 p += issuer_dn->bv_len;
3562 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3563 "certificateExactConvert: \n %s\n",
3566 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3568 (*out)->bv_val, NULL, NULL );
3572 ber_bvfree(issuer_dn);
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 *serial = ber_bvdup(&bv);
3608 /* now extract the issuer, remember p was at the dollar sign */
3610 end = assertion->bv_val+assertion->bv_len-1;
3611 while (ASCII_SPACE(*begin))
3613 /* should we trim spaces at the end too? is it safe always? */
3615 bv.bv_len = end-begin+1;
3617 dnNormalize( NULL, &bv, issuer_dn );
3619 return LDAP_SUCCESS;
3623 certificateExactMatch(
3628 struct berval *value,
3629 void *assertedValue )
3632 unsigned char *p = value->bv_val;
3633 struct berval *serial;
3634 struct berval *issuer_dn;
3635 struct berval *asserted_serial;
3636 struct berval *asserted_issuer_dn;
3639 xcert = d2i_X509(NULL, &p, value->bv_len);
3642 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3643 "certificateExactMatch: error parsing cert: %s\n",
3644 ERR_error_string(ERR_get_error(),NULL)));
3646 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
3647 "error parsing cert: %s\n",
3648 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3650 return LDAP_INVALID_SYNTAX;
3653 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3654 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
3658 serial_and_issuer_parse(assertedValue,
3660 &asserted_issuer_dn);
3665 slap_schema.si_syn_integer,
3666 slap_schema.si_mr_integerMatch,
3669 if ( ret == LDAP_SUCCESS ) {
3670 if ( *matchp == 0 ) {
3671 /* We need to normalize everything for dnMatch */
3675 slap_schema.si_syn_distinguishedName,
3676 slap_schema.si_mr_distinguishedNameMatch,
3678 asserted_issuer_dn);
3683 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3684 "certificateExactMatch: %d\n %s $ %s\n %s $ %s\n",
3685 *matchp, serial->bv_val, issuer_dn->bv_val,
3686 asserted->serial->bv_val, asserted_issuer_dn->bv_val));
3688 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3689 "%d\n\t\"%s $ %s\"\n",
3690 *matchp, serial->bv_val, issuer_dn->bv_val );
3691 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3692 asserted_serial->bv_val, asserted_issuer_dn->bv_val,
3697 ber_bvfree(issuer_dn);
3698 ber_bvfree(asserted_serial);
3699 ber_bvfree(asserted_issuer_dn);
3705 * Index generation function
3706 * We just index the serials, in most scenarios the issuer DN is one of
3707 * a very small set of values.
3709 static int certificateExactIndexer(
3714 struct berval *prefix,
3715 struct berval **values,
3716 struct berval ***keysp )
3719 struct berval **keys;
3722 struct berval * serial;
3724 /* we should have at least one value at this point */
3725 assert( values != NULL && values[0] != NULL );
3727 for( i=0; values[i] != NULL; i++ ) {
3728 /* empty -- just count them */
3731 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
3733 for( i=0; values[i] != NULL; i++ ) {
3734 p = values[i]->bv_val;
3735 xcert = d2i_X509(NULL, &p, values[i]->bv_len);
3738 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3739 "certificateExactIndexer: error parsing cert: %s\n",
3740 ERR_error_string(ERR_get_error(),NULL)));
3742 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3743 "error parsing cert: %s\n",
3744 ERR_error_string(ERR_get_error(),NULL),
3747 /* Do we leak keys on error? */
3748 return LDAP_INVALID_SYNTAX;
3751 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3753 integerNormalize( slap_schema.si_syn_integer,
3758 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3759 "certificateExactIndexer: returning: %s\n",
3762 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3771 return LDAP_SUCCESS;
3774 /* Index generation function */
3775 /* We think this is always called with a value in matching rule syntax */
3776 static int certificateExactFilter(
3781 struct berval *prefix,
3783 struct berval ***keysp )
3785 struct berval **keys;
3786 struct berval *asserted_serial;
3787 struct berval *asserted_issuer_dn;
3789 serial_and_issuer_parse(assertValue,
3791 &asserted_issuer_dn);
3793 keys = ch_malloc( sizeof( struct berval * ) * 2 );
3794 integerNormalize( syntax, asserted_serial, &keys[0] );
3798 ber_bvfree(asserted_serial);
3799 ber_bvfree(asserted_issuer_dn);
3800 return LDAP_SUCCESS;
3805 check_time_syntax (struct berval *val,
3809 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3810 static int mdays[2][12] = {
3811 /* non-leap years */
3812 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3814 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3817 int part, c, tzoffset, leapyear = 0 ;
3819 if( val->bv_len == 0 ) {
3820 return LDAP_INVALID_SYNTAX;
3823 p = (char *)val->bv_val;
3824 e = p + val->bv_len;
3826 /* Ignore initial whitespace */
3827 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3831 if (e - p < 13 - (2 * start)) {
3832 return LDAP_INVALID_SYNTAX;
3835 for (part = 0; part < 9; part++) {
3839 for (part = start; part < 7; part++) {
3841 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3848 return LDAP_INVALID_SYNTAX;
3850 if (c < 0 || c > 9) {
3851 return LDAP_INVALID_SYNTAX;
3857 return LDAP_INVALID_SYNTAX;
3859 if (c < 0 || c > 9) {
3860 return LDAP_INVALID_SYNTAX;
3865 if (part == 2 || part == 3) {
3868 if (parts[part] < 0) {
3869 return LDAP_INVALID_SYNTAX;
3871 if (parts[part] > ceiling[part]) {
3872 return LDAP_INVALID_SYNTAX;
3876 /* leapyear check for the Gregorian calendar (year>1581) */
3877 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
3878 ((parts[0] % 4 == 0) && (parts[1] == 0)))
3883 if (parts[3] > mdays[leapyear][parts[2]]) {
3884 return LDAP_INVALID_SYNTAX;
3889 tzoffset = 0; /* UTC */
3890 } else if (c != '+' && c != '-') {
3891 return LDAP_INVALID_SYNTAX;
3895 } else /* c == '+' */ {
3900 return LDAP_INVALID_SYNTAX;
3903 for (part = 7; part < 9; part++) {
3905 if (c < 0 || c > 9) {
3906 return LDAP_INVALID_SYNTAX;
3911 if (c < 0 || c > 9) {
3912 return LDAP_INVALID_SYNTAX;
3916 if (parts[part] < 0 || parts[part] > ceiling[part]) {
3917 return LDAP_INVALID_SYNTAX;
3922 /* Ignore trailing whitespace */
3923 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3927 return LDAP_INVALID_SYNTAX;
3930 switch ( tzoffset ) {
3931 case -1: /* negativ offset to UTC, ie west of Greenwich */
3932 parts[4] += parts[7];
3933 parts[5] += parts[8];
3934 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
3938 c = mdays[leapyear][parts[2]];
3940 if (parts[part] > c) {
3941 parts[part] -= c + 1;
3946 case 1: /* positive offset to UTC, ie east of Greenwich */
3947 parts[4] -= parts[7];
3948 parts[5] -= parts[8];
3949 for (part = 6; --part > 0; ) {
3953 /* first arg to % needs to be non negativ */
3954 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
3956 if (parts[part] < 0) {
3957 parts[part] += c + 1;
3962 case 0: /* already UTC */
3966 return LDAP_SUCCESS;
3973 struct berval **normalized )
3978 rc = check_time_syntax(val, 1, parts);
3979 if (rc != LDAP_SUCCESS) {
3984 out = ch_malloc( sizeof(struct berval) );
3986 return LBER_ERROR_MEMORY;
3989 out->bv_val = ch_malloc( 14 );
3990 if ( out->bv_val == NULL ) {
3992 return LBER_ERROR_MEMORY;
3995 sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02dZ",
3996 parts[1], parts[2] + 1, parts[3] + 1,
3997 parts[4], parts[5], parts[6] );
4001 return LDAP_SUCCESS;
4011 return check_time_syntax(in, 1, parts);
4015 generalizedTimeValidate(
4021 return check_time_syntax(in, 0, parts);
4025 generalizedTimeNormalize(
4028 struct berval **normalized )
4033 rc = check_time_syntax(val, 0, parts);
4034 if (rc != LDAP_SUCCESS) {
4039 out = ch_malloc( sizeof(struct berval) );
4041 return LBER_ERROR_MEMORY;
4044 out->bv_val = ch_malloc( 16 );
4045 if ( out->bv_val == NULL ) {
4047 return LBER_ERROR_MEMORY;
4050 sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4051 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4052 parts[4], parts[5], parts[6] );
4056 return LDAP_SUCCESS;
4060 nisNetgroupTripleValidate(
4062 struct berval *val )
4067 if ( val->bv_len == 0 ) {
4068 return LDAP_INVALID_SYNTAX;
4071 p = (char *)val->bv_val;
4072 e = p + val->bv_len;
4074 if ( *p != '(' /*')'*/ ) {
4075 return LDAP_INVALID_SYNTAX;
4078 for ( p++; ( p < e ) && ( *p != ')' ); p++ ) {
4082 return LDAP_INVALID_SYNTAX;
4085 } else if ( !ATTR_CHAR( *p ) ) {
4086 return LDAP_INVALID_SYNTAX;
4090 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4091 return LDAP_INVALID_SYNTAX;
4097 return LDAP_INVALID_SYNTAX;
4100 return LDAP_SUCCESS;
4104 bootParameterValidate(
4106 struct berval *val )
4110 if ( val->bv_len == 0 ) {
4111 return LDAP_INVALID_SYNTAX;
4114 p = (char *)val->bv_val;
4115 e = p + val->bv_len;
4118 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4119 if ( !ATTR_CHAR( *p ) ) {
4120 return LDAP_INVALID_SYNTAX;
4125 return LDAP_INVALID_SYNTAX;
4129 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4130 if ( !ATTR_CHAR( *p ) ) {
4131 return LDAP_INVALID_SYNTAX;
4136 return LDAP_INVALID_SYNTAX;
4140 for ( p++; p < e; p++ ) {
4141 if ( !ATTR_CHAR( *p ) ) {
4142 return LDAP_INVALID_SYNTAX;
4146 return LDAP_SUCCESS;
4149 static struct syntax_defs_rec {
4151 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4152 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4154 slap_syntax_validate_func *sd_validate;
4155 slap_syntax_transform_func *sd_normalize;
4156 slap_syntax_transform_func *sd_pretty;
4157 #ifdef SLAPD_BINARY_CONVERSION
4158 slap_syntax_transform_func *sd_ber2str;
4159 slap_syntax_transform_func *sd_str2ber;
4162 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
4163 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4164 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4165 0, NULL, NULL, NULL},
4166 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4167 0, NULL, NULL, NULL},
4168 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
4169 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4170 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_NOT_H_R ")",
4171 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4172 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4173 0, bitStringValidate, bitStringNormalize, NULL },
4174 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4175 0, booleanValidate, NULL, NULL},
4176 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4177 X_BINARY X_NOT_H_R ")",
4178 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4179 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4180 X_BINARY X_NOT_H_R ")",
4181 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4182 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4183 X_BINARY X_NOT_H_R ")",
4184 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4185 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4186 0, countryStringValidate, IA5StringNormalize, NULL},
4187 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4188 0, dnValidate, dnNormalize, dnPretty},
4189 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4190 0, NULL, NULL, NULL},
4191 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4192 0, NULL, NULL, NULL},
4193 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4194 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4195 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4196 0, NULL, NULL, NULL},
4197 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4198 0, NULL, NULL, NULL},
4199 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4200 0, NULL, NULL, NULL},
4201 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4202 0, NULL, NULL, NULL},
4203 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4204 0, NULL, NULL, NULL},
4205 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4206 0, printablesStringValidate, IA5StringNormalize, NULL},
4207 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4208 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4209 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4210 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4211 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4212 0, NULL, NULL, NULL},
4213 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4214 0, IA5StringValidate, IA5StringNormalize, NULL},
4215 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4216 0, integerValidate, integerNormalize, NULL},
4217 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4218 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4219 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4220 0, NULL, NULL, NULL},
4221 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4222 0, NULL, NULL, NULL},
4223 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4224 0, NULL, NULL, NULL},
4225 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4226 0, NULL, NULL, NULL},
4227 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4228 0, NULL, NULL, NULL},
4229 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4230 0, nameUIDValidate, nameUIDNormalize, NULL},
4231 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4232 0, NULL, NULL, NULL},
4233 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4234 0, numericStringValidate, numericStringNormalize, NULL},
4235 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4236 0, NULL, NULL, NULL},
4237 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4238 0, oidValidate, NULL, NULL},
4239 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4240 0, IA5StringValidate, IA5StringNormalize, NULL},
4241 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4242 0, blobValidate, NULL, NULL},
4243 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4244 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4245 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4246 0, NULL, NULL, NULL},
4247 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4248 0, NULL, NULL, NULL},
4249 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4250 0, printableStringValidate, IA5StringNormalize, NULL},
4251 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4252 X_BINARY X_NOT_H_R ")",
4253 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4254 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4255 0, printableStringValidate, IA5StringNormalize, NULL},
4256 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4257 0, NULL, NULL, NULL},
4258 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4259 0, printablesStringValidate, IA5StringNormalize, NULL},
4260 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4261 0, utcTimeValidate, utcTimeNormalize, NULL},
4262 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4263 0, NULL, NULL, NULL},
4264 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4265 0, NULL, NULL, NULL},
4266 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4267 0, NULL, NULL, NULL},
4268 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4269 0, NULL, NULL, NULL},
4270 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4271 0, NULL, NULL, NULL},
4273 /* RFC 2307 NIS Syntaxes */
4274 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4275 0, nisNetgroupTripleValidate, NULL, NULL},
4276 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4277 0, bootParameterValidate, NULL, NULL},
4281 /* These OIDs are not published yet, but will be in the next
4282 * I-D for PKIX LDAPv3 schema as have been advanced by David
4283 * Chadwick in private mail.
4285 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4286 0, NULL, NULL, NULL},
4289 /* OpenLDAP Experimental Syntaxes */
4290 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4292 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4295 /* needs updating */
4296 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4297 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4299 /* OpenLDAP Void Syntax */
4300 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4301 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4302 {NULL, 0, NULL, NULL, NULL}
4306 * Other matching rules in X.520 that we do not use (yet):
4308 * 2.5.13.9 numericStringOrderingMatch
4309 * 2.5.13.15 integerOrderingMatch
4310 * 2.5.13.18 octetStringOrderingMatch
4311 * 2.5.13.19 octetStringSubstringsMatch
4312 * 2.5.13.25 uTCTimeMatch
4313 * 2.5.13.26 uTCTimeOrderingMatch
4314 * 2.5.13.31 directoryStringFirstComponentMatch
4315 * 2.5.13.32 wordMatch
4316 * 2.5.13.33 keywordMatch
4317 * 2.5.13.35 certificateMatch
4318 * 2.5.13.36 certificatePairExactMatch
4319 * 2.5.13.37 certificatePairMatch
4320 * 2.5.13.38 certificateListExactMatch
4321 * 2.5.13.39 certificateListMatch
4322 * 2.5.13.40 algorithmIdentifierMatch
4323 * 2.5.13.41 storedPrefixMatch
4324 * 2.5.13.42 attributeCertificateMatch
4325 * 2.5.13.43 readerAndKeyIDMatch
4326 * 2.5.13.44 attributeIntegrityMatch
4328 static struct mrule_defs_rec {
4330 slap_mask_t mrd_usage;
4331 slap_mr_convert_func * mrd_convert;
4332 slap_mr_normalize_func * mrd_normalize;
4333 slap_mr_match_func * mrd_match;
4334 slap_mr_indexer_func * mrd_indexer;
4335 slap_mr_filter_func * mrd_filter;
4337 char * mrd_associated;
4340 * EQUALITY matching rules must be listed after associated APPROX
4341 * matching rules. So, we list all APPROX matching rules first.
4343 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4344 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4345 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4347 directoryStringApproxMatch,
4348 directoryStringApproxIndexer,
4349 directoryStringApproxFilter,
4352 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4353 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4354 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4356 IA5StringApproxMatch,
4357 IA5StringApproxIndexer,
4358 IA5StringApproxFilter,
4362 * Other matching rules
4365 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4366 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4367 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4369 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4372 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4373 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4374 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4376 dnMatch, dnIndexer, dnFilter,
4379 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4380 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4381 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4383 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4384 directoryStringApproxMatchOID },
4386 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4387 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4390 caseIgnoreOrderingMatch, NULL, NULL,
4393 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4394 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4395 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4397 caseExactIgnoreSubstringsMatch,
4398 caseExactIgnoreSubstringsIndexer,
4399 caseExactIgnoreSubstringsFilter,
4402 {"( 2.5.13.5 NAME 'caseExactMatch' "
4403 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4404 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4406 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4407 directoryStringApproxMatchOID },
4409 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4410 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4413 caseExactOrderingMatch, NULL, NULL,
4416 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4417 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4418 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4420 caseExactIgnoreSubstringsMatch,
4421 caseExactIgnoreSubstringsIndexer,
4422 caseExactIgnoreSubstringsFilter,
4425 {"( 2.5.13.8 NAME 'numericStringMatch' "
4426 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4427 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4430 caseIgnoreIA5Indexer,
4431 caseIgnoreIA5Filter,
4434 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4435 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4436 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4438 caseIgnoreIA5SubstringsMatch,
4439 caseIgnoreIA5SubstringsIndexer,
4440 caseIgnoreIA5SubstringsFilter,
4443 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4444 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4445 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4447 caseIgnoreListMatch, NULL, NULL,
4450 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4451 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4452 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4454 caseIgnoreListSubstringsMatch, NULL, NULL,
4457 {"( 2.5.13.13 NAME 'booleanMatch' "
4458 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4459 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4461 booleanMatch, NULL, NULL,
4464 {"( 2.5.13.14 NAME 'integerMatch' "
4465 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4466 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4468 integerMatch, integerIndexer, integerFilter,
4471 {"( 2.5.13.16 NAME 'bitStringMatch' "
4472 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4473 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4475 bitStringMatch, bitStringIndexer, bitStringFilter,
4478 {"( 2.5.13.17 NAME 'octetStringMatch' "
4479 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4480 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4482 octetStringMatch, octetStringIndexer, octetStringFilter,
4485 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4486 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4487 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4489 telephoneNumberMatch,
4490 telephoneNumberIndexer,
4491 telephoneNumberFilter,
4494 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4495 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4496 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4498 telephoneNumberSubstringsMatch,
4499 telephoneNumberSubstringsIndexer,
4500 telephoneNumberSubstringsFilter,
4503 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4504 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4505 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4510 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4511 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4512 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4514 uniqueMemberMatch, NULL, NULL,
4517 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4518 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4519 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4521 protocolInformationMatch, NULL, NULL,
4524 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4525 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4526 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4528 generalizedTimeMatch, NULL, NULL,
4531 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4532 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4535 generalizedTimeOrderingMatch, NULL, NULL,
4538 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4539 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4540 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4542 integerFirstComponentMatch, NULL, NULL,
4545 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4546 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4547 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4549 objectIdentifierFirstComponentMatch, NULL, NULL,
4553 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4554 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4555 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4556 certificateExactConvert, NULL,
4557 certificateExactMatch,
4558 certificateExactIndexer, certificateExactFilter,
4562 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4563 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4564 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4566 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4567 IA5StringApproxMatchOID },
4569 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4570 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4571 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4573 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4574 IA5StringApproxMatchOID },
4576 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4577 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4580 caseIgnoreIA5SubstringsMatch,
4581 caseIgnoreIA5SubstringsIndexer,
4582 caseIgnoreIA5SubstringsFilter,
4585 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4586 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4589 caseExactIA5SubstringsMatch,
4590 caseExactIA5SubstringsIndexer,
4591 caseExactIA5SubstringsFilter,
4594 /* needs updating */
4595 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4596 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4599 authPasswordMatch, NULL, NULL,
4602 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4603 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4606 OpenLDAPaciMatch, NULL, NULL,
4609 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4610 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4613 integerBitAndMatch, NULL, NULL,
4616 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4617 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4620 integerBitOrMatch, NULL, NULL,
4623 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
4632 /* we should only be called once (from main) */
4633 assert( schema_init_done == 0 );
4635 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4636 res = register_syntax( syntax_defs[i].sd_desc,
4637 syntax_defs[i].sd_flags,
4638 syntax_defs[i].sd_validate,
4639 syntax_defs[i].sd_normalize,
4640 syntax_defs[i].sd_pretty
4641 #ifdef SLAPD_BINARY_CONVERSION
4643 syntax_defs[i].sd_ber2str,
4644 syntax_defs[i].sd_str2ber
4649 fprintf( stderr, "schema_init: Error registering syntax %s\n",
4650 syntax_defs[i].sd_desc );
4655 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4656 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
4658 "schema_init: Ingoring unusable matching rule %s\n",
4659 mrule_defs[i].mrd_desc );
4663 res = register_matching_rule(
4664 mrule_defs[i].mrd_desc,
4665 mrule_defs[i].mrd_usage,
4666 mrule_defs[i].mrd_convert,
4667 mrule_defs[i].mrd_normalize,
4668 mrule_defs[i].mrd_match,
4669 mrule_defs[i].mrd_indexer,
4670 mrule_defs[i].mrd_filter,
4671 mrule_defs[i].mrd_associated );
4675 "schema_init: Error registering matching rule %s\n",
4676 mrule_defs[i].mrd_desc );
4680 schema_init_done = 1;
4681 return LDAP_SUCCESS;
4685 schema_destroy( void )