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 = strlen( syntax->ssyn_oid );
148 mlen = strlen( mr->smr_oid );
150 for( i=0; values[i] != NULL; i++ ) {
151 HASH_Init( &HASHcontext );
152 if( prefix != NULL && prefix->bv_len > 0 ) {
153 HASH_Update( &HASHcontext,
154 prefix->bv_val, prefix->bv_len );
156 HASH_Update( &HASHcontext,
157 syntax->ssyn_oid, slen );
158 HASH_Update( &HASHcontext,
160 HASH_Update( &HASHcontext,
161 values[i]->bv_val, values[i]->bv_len );
162 HASH_Final( HASHdigest, &HASHcontext );
164 keys[i] = ber_bvdup( &digest );
174 /* Index generation function */
175 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 = strlen( syntax->ssyn_oid );
194 mlen = strlen( mr->smr_oid );
196 keys = ch_malloc( sizeof( struct berval * ) * 2 );
198 HASH_Init( &HASHcontext );
199 if( prefix != NULL && prefix->bv_len > 0 ) {
200 HASH_Update( &HASHcontext,
201 prefix->bv_val, prefix->bv_len );
203 HASH_Update( &HASHcontext,
204 syntax->ssyn_oid, slen );
205 HASH_Update( &HASHcontext,
207 HASH_Update( &HASHcontext,
208 value->bv_val, value->bv_len );
209 HASH_Final( HASHdigest, &HASHcontext );
211 keys[0] = ber_bvdup( &digest );
227 if( in->bv_len == 0 ) return LDAP_SUCCESS;
229 dn = ber_bvdup( in );
231 if( dn->bv_val[dn->bv_len-1] == '\'' ) {
232 /* assume presence of optional UID */
235 for(i=dn->bv_len-2; i>2; i--) {
236 if( dn->bv_val[i] != '0' && dn->bv_val[i] != '1' ) {
240 if( dn->bv_val[i] != '\'' ||
241 dn->bv_val[i-1] != 'B' ||
242 dn->bv_val[i-2] != '#' ) {
244 return LDAP_INVALID_SYNTAX;
247 /* trim the UID to allow use of dn_validate */
248 dn->bv_val[i-2] = '\0';
251 /* FIXME: should use dnValidate */
252 rc = dn_validate( dn->bv_val ) == NULL
253 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
263 struct berval **normalized )
265 struct berval *out = ber_bvdup( val );
267 if( out->bv_len != 0 ) {
271 ber_len_t uidlen = 0;
273 if( out->bv_val[out->bv_len-1] == '\'' ) {
274 /* assume presence of optional UID */
275 uid = strrchr( out->bv_val, '#' );
279 return LDAP_INVALID_SYNTAX;
282 uidlen = out->bv_len - (out->bv_val - uid);
283 /* temporarily trim the UID */
287 /* FIXME: should use dnNormalize */
288 #ifdef USE_DN_NORMALIZE
289 dn = dn_normalize( out->bv_val );
291 dn = dn_validate( out->bv_val );
296 return LDAP_INVALID_SYNTAX;
302 /* restore the separator */
305 SAFEMEMCPY( &dn[dnlen], uid, uidlen );
309 out->bv_len = dnlen + uidlen;
321 /* any value allowed */
330 /* any value allowed */
341 /* very unforgiving validation, requires no normalization
342 * before simplistic matching
344 if( in->bv_len < 3 ) {
345 return LDAP_INVALID_SYNTAX;
349 * rfc 2252 section 6.3 Bit String
350 * bitstring = "'" *binary-digit "'"
351 * binary-digit = "0" / "1"
352 * example: '0101111101'B
355 if( in->bv_val[0] != '\'' ||
356 in->bv_val[in->bv_len-2] != '\'' ||
357 in->bv_val[in->bv_len-1] != 'B' )
359 return LDAP_INVALID_SYNTAX;
362 for( i=in->bv_len-3; i>0; i-- ) {
363 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
364 return LDAP_INVALID_SYNTAX;
375 struct berval **normalized )
378 * A normalized bitString is has no extaneous (leading) zero bits.
379 * That is, '00010'B is normalized to '10'B
380 * However, as a special case, '0'B requires no normalization.
382 struct berval *newval;
385 /* start at the first bit */
388 /* Find the first non-zero bit */
389 while ( *p == '0' ) p++;
391 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
394 /* no non-zero bits */
395 newval->bv_val = ch_strdup("\'0\'B");
396 newval->bv_len = sizeof("\'0\'B") - 1;
400 newval->bv_val = ch_malloc( val->bv_len + 1 );
402 newval->bv_val[0] = '\'';
405 for( ; *p != '\0'; p++ ) {
406 newval->bv_val[newval->bv_len++] = *p;
409 newval->bv_val[newval->bv_len] = '\0';
412 *normalized = newval;
417 * Handling boolean syntax and matching is quite rigid.
418 * A more flexible approach would be to allow a variety
419 * of strings to be normalized and prettied into TRUE
427 /* very unforgiving validation, requires no normalization
428 * before simplistic matching
431 if( in->bv_len == 4 ) {
432 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
435 } else if( in->bv_len == 5 ) {
436 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
441 return LDAP_INVALID_SYNTAX;
450 struct berval *value,
451 void *assertedValue )
453 /* simplistic matching allowed by rigid validation */
454 struct berval *asserted = (struct berval *) assertedValue;
455 *matchp = value->bv_len != asserted->bv_len;
466 unsigned char *u = in->bv_val;
468 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
470 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
471 /* get the length indicated by the first byte */
472 len = LDAP_UTF8_CHARLEN( u );
474 /* should not be zero */
475 if( len == 0 ) return LDAP_INVALID_SYNTAX;
477 /* make sure len corresponds with the offset
478 to the next character */
479 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
482 if( count != 0 ) return LDAP_INVALID_SYNTAX;
491 struct berval **normalized )
493 struct berval *newval;
496 newval = ch_malloc( sizeof( struct berval ) );
500 /* Ignore initial whitespace */
501 while ( ldap_utf8_isspace( p ) ) {
507 return LDAP_INVALID_SYNTAX;
510 newval->bv_val = ch_strdup( p );
511 p = q = newval->bv_val;
517 if ( ldap_utf8_isspace( p ) ) {
518 len = LDAP_UTF8_COPY(q,p);
523 /* Ignore the extra whitespace */
524 while ( ldap_utf8_isspace( p ) ) {
528 len = LDAP_UTF8_COPY(q,p);
535 assert( *newval->bv_val );
536 assert( newval->bv_val < p );
539 /* cannot start with a space */
540 assert( !ldap_utf8_isspace(newval->bv_val) );
543 * If the string ended in space, backup the pointer one
544 * position. One is enough because the above loop collapsed
545 * all whitespace to a single space.
552 /* cannot end with a space */
553 assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
558 newval->bv_len = q - newval->bv_val;
559 *normalized = newval;
564 /* Returns Unicode cannonically normalized copy of a substring assertion
565 * Skipping attribute description */
566 static SubstringsAssertion *
567 UTF8SubstringsassertionNormalize(
568 SubstringsAssertion *sa,
571 SubstringsAssertion *nsa;
574 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
579 if( sa->sa_initial != NULL ) {
580 nsa->sa_initial = ber_bvstr( UTF8normalize( sa->sa_initial, casefold ) );
581 if( nsa->sa_initial == NULL ) {
586 if( sa->sa_any != NULL ) {
587 for( i=0; sa->sa_any[i] != NULL; i++ ) {
590 nsa->sa_any = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
591 for( i=0; sa->sa_any[i] != NULL; i++ ) {
592 nsa->sa_any[i] = ber_bvstr( UTF8normalize( sa->sa_any[i], casefold ) );
593 if( nsa->sa_any[i] == NULL ) {
597 nsa->sa_any[i] = NULL;
600 if( sa->sa_final != NULL ) {
601 nsa->sa_final = ber_bvstr( UTF8normalize( sa->sa_final, casefold ) );
602 if( nsa->sa_final == NULL ) {
610 ber_bvfree( nsa->sa_final );
611 ber_bvecfree( nsa->sa_any );
612 ber_bvfree( nsa->sa_initial );
617 /* Strip characters with the 8th bit set */
630 while( *++q & 0x80 ) {
633 p = memmove(p, q, strlen(q) + 1);
641 #ifndef SLAPD_APPROX_OLDSINGLESTRING
643 #if defined(SLAPD_APPROX_INITIALS)
644 #define SLAPD_APPROX_DELIMITER "._ "
645 #define SLAPD_APPROX_WORDLEN 2
647 #define SLAPD_APPROX_DELIMITER " "
648 #define SLAPD_APPROX_WORDLEN 1
657 struct berval *value,
658 void *assertedValue )
660 char *val, *nval, *assertv, **values, **words, *c;
661 int i, count, len, nextchunk=0, nextavail=0;
664 /* Yes, this is necessary */
665 nval = UTF8normalize( value, UTF8_NOCASEFOLD );
670 strip8bitChars( nval );
672 /* Yes, this is necessary */
673 assertv = UTF8normalize( ((struct berval *)assertedValue),
675 if( assertv == NULL ) {
680 strip8bitChars( assertv );
681 avlen = strlen( assertv );
683 /* Isolate how many words there are */
684 for( c=nval,count=1; *c; c++ ) {
685 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
686 if ( c == NULL ) break;
691 /* Get a phonetic copy of each word */
692 words = (char **)ch_malloc( count * sizeof(char *) );
693 values = (char **)ch_malloc( count * sizeof(char *) );
694 for( c=nval,i=0; i<count; i++,c+=strlen(c)+1 ) {
696 values[i] = phonetic(c);
699 /* Work through the asserted value's words, to see if at least some
700 of the words are there, in the same order. */
702 while ( (size_t) nextchunk < avlen ) {
703 len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER);
708 #if defined(SLAPD_APPROX_INITIALS)
709 else if( len == 1 ) {
710 /* Single letter words need to at least match one word's initial */
711 for( i=nextavail; i<count; i++ )
712 if( !strncasecmp( assertv+nextchunk, words[i], 1 )) {
719 /* Isolate the next word in the asserted value and phonetic it */
720 assertv[nextchunk+len] = '\0';
721 val = phonetic( assertv + nextchunk );
723 /* See if this phonetic chunk is in the remaining words of *value */
724 for( i=nextavail; i<count; i++ ){
725 if( !strcmp( val, values[i] ) ){
733 /* This chunk in the asserted value was NOT within the *value. */
739 /* Go on to the next word in the asserted value */
743 /* If some of the words were seen, call it a match */
744 if( nextavail > 0 ) {
753 for( i=0; i<count; i++ ) {
754 ch_free( values[i] );
769 struct berval *prefix,
770 struct berval **values,
771 struct berval ***keysp )
774 int i,j, len, wordcount, keycount=0;
775 struct berval **newkeys, **keys=NULL;
777 for( j=0; values[j] != NULL; j++ ) {
778 /* Yes, this is necessary */
779 val = UTF8normalize( values[j], UTF8_NOCASEFOLD );
780 strip8bitChars( val );
782 /* Isolate how many words there are. There will be a key for each */
783 for( wordcount=0,c=val; *c; c++) {
784 len = strcspn(c, SLAPD_APPROX_DELIMITER);
785 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
787 if (*c == '\0') break;
791 /* Allocate/increase storage to account for new keys */
792 newkeys = (struct berval **)ch_malloc( (keycount + wordcount + 1)
793 * sizeof(struct berval *) );
794 memcpy( newkeys, keys, keycount * sizeof(struct berval *) );
795 if( keys ) ch_free( keys );
798 /* Get a phonetic copy of each word */
799 for( c=val,i=0; i<wordcount; c+=len+1 ) {
801 if( len < SLAPD_APPROX_WORDLEN ) continue;
802 keys[keycount] = (struct berval *)ch_malloc( sizeof(struct berval) );
803 keys[keycount]->bv_val = phonetic( c );
804 keys[keycount]->bv_len = strlen( keys[keycount]->bv_val );
811 keys[keycount] = NULL;
823 struct berval *prefix,
825 struct berval ***keysp )
829 struct berval **keys;
831 /* Yes, this is necessary */
832 val = UTF8normalize( ((struct berval *)assertValue),
835 keys = (struct berval **)ch_malloc( sizeof(struct berval *) );
840 strip8bitChars( val );
842 /* Isolate how many words there are. There will be a key for each */
843 for( count=0,c=val; *c; c++) {
844 len = strcspn(c, SLAPD_APPROX_DELIMITER);
845 if( len >= SLAPD_APPROX_WORDLEN ) count++;
847 if (*c == '\0') break;
851 /* Allocate storage for new keys */
852 keys = (struct berval **)ch_malloc( (count + 1) * sizeof(struct berval *) );
854 /* Get a phonetic copy of each word */
855 for( c=val,i=0; i<count; c+=len+1 ) {
857 if( len < SLAPD_APPROX_WORDLEN ) continue;
858 keys[i] = ber_bvstr( phonetic( c ) );
872 /* No other form of Approximate Matching is defined */
880 struct berval *value,
881 void *assertedValue )
883 char *vapprox, *avapprox;
886 /* Yes, this is necessary */
887 s = UTF8normalize( value, UTF8_NOCASEFOLD );
893 /* Yes, this is necessary */
894 t = UTF8normalize( ((struct berval *)assertedValue),
902 vapprox = phonetic( strip8bitChars( s ) );
903 avapprox = phonetic( strip8bitChars( t ) );
908 *matchp = strcmp( vapprox, avapprox );
922 struct berval *prefix,
923 struct berval **values,
924 struct berval ***keysp )
927 struct berval **keys;
930 for( i=0; values[i] != NULL; i++ ) {
931 /* empty - just count them */
934 /* we should have at least one value at this point */
937 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * (i+1) );
939 /* Copy each value and run it through phonetic() */
940 for( i=0; values[i] != NULL; i++ ) {
941 /* Yes, this is necessary */
942 s = UTF8normalize( values[i], UTF8_NOCASEFOLD );
944 /* strip 8-bit chars and run through phonetic() */
945 keys[i] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
961 struct berval *prefix,
963 struct berval ***keysp )
965 struct berval **keys;
968 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * 2 );
970 /* Yes, this is necessary */
971 s = UTF8normalize( ((struct berval *)assertValue),
976 /* strip 8-bit chars and run through phonetic() */
977 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
994 struct berval *value,
995 void *assertedValue )
997 *matchp = UTF8normcmp( value->bv_val,
998 ((struct berval *) assertedValue)->bv_val,
1000 return LDAP_SUCCESS;
1004 caseExactIgnoreSubstringsMatch(
1009 struct berval *value,
1010 void *assertedValue )
1013 SubstringsAssertion *sub = NULL;
1017 char *nav, casefold;
1019 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1020 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1022 nav = UTF8normalize( value, casefold );
1028 left.bv_len = strlen( nav );
1030 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1036 /* Add up asserted input length */
1037 if( sub->sa_initial ) {
1038 inlen += sub->sa_initial->bv_len;
1041 for(i=0; sub->sa_any[i] != NULL; i++) {
1042 inlen += sub->sa_any[i]->bv_len;
1045 if( sub->sa_final ) {
1046 inlen += sub->sa_final->bv_len;
1049 if( sub->sa_initial ) {
1050 if( inlen > left.bv_len ) {
1055 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
1056 sub->sa_initial->bv_len );
1062 left.bv_val += sub->sa_initial->bv_len;
1063 left.bv_len -= sub->sa_initial->bv_len;
1064 inlen -= sub->sa_initial->bv_len;
1067 if( sub->sa_final ) {
1068 if( inlen > left.bv_len ) {
1073 match = strncmp( sub->sa_final->bv_val,
1074 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
1075 sub->sa_final->bv_len );
1081 left.bv_len -= sub->sa_final->bv_len;
1082 inlen -= sub->sa_final->bv_len;
1086 for(i=0; sub->sa_any[i]; i++) {
1091 if( inlen > left.bv_len ) {
1092 /* not enough length */
1097 if( sub->sa_any[i]->bv_len == 0 ) {
1101 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
1108 idx = p - left.bv_val;
1109 assert( idx < left.bv_len );
1111 if( idx >= left.bv_len ) {
1112 /* this shouldn't happen */
1114 ch_free( sub->sa_final );
1115 ber_bvecfree( sub->sa_any );
1116 ch_free( sub->sa_initial );
1124 if( sub->sa_any[i]->bv_len > left.bv_len ) {
1125 /* not enough left */
1130 match = strncmp( left.bv_val,
1131 sub->sa_any[i]->bv_val,
1132 sub->sa_any[i]->bv_len );
1140 left.bv_val += sub->sa_any[i]->bv_len;
1141 left.bv_len -= sub->sa_any[i]->bv_len;
1142 inlen -= sub->sa_any[i]->bv_len;
1149 ber_bvfree( sub->sa_final );
1150 ber_bvecfree( sub->sa_any );
1151 ber_bvfree( sub->sa_initial );
1155 return LDAP_SUCCESS;
1158 /* Index generation function */
1159 static int caseExactIgnoreIndexer(
1164 struct berval *prefix,
1165 struct berval **values,
1166 struct berval ***keysp )
1171 struct berval **keys;
1172 HASH_CONTEXT HASHcontext;
1173 unsigned char HASHdigest[HASH_BYTES];
1174 struct berval digest;
1175 digest.bv_val = HASHdigest;
1176 digest.bv_len = sizeof(HASHdigest);
1178 for( i=0; values[i] != NULL; i++ ) {
1179 /* empty - just count them */
1182 /* we should have at least one value at this point */
1185 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
1187 slen = strlen( syntax->ssyn_oid );
1188 mlen = strlen( mr->smr_oid );
1190 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1191 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1193 for( i=0; values[i] != NULL; i++ ) {
1194 struct berval *value;
1195 value = ber_bvstr( UTF8normalize( values[i],
1198 HASH_Init( &HASHcontext );
1199 if( prefix != NULL && prefix->bv_len > 0 ) {
1200 HASH_Update( &HASHcontext,
1201 prefix->bv_val, prefix->bv_len );
1203 HASH_Update( &HASHcontext,
1204 syntax->ssyn_oid, slen );
1205 HASH_Update( &HASHcontext,
1206 mr->smr_oid, mlen );
1207 HASH_Update( &HASHcontext,
1208 value->bv_val, value->bv_len );
1209 HASH_Final( HASHdigest, &HASHcontext );
1211 ber_bvfree( value );
1213 keys[i] = ber_bvdup( &digest );
1218 return LDAP_SUCCESS;
1221 /* Index generation function */
1222 static int caseExactIgnoreFilter(
1227 struct berval *prefix,
1229 struct berval ***keysp )
1233 struct berval **keys;
1234 HASH_CONTEXT HASHcontext;
1235 unsigned char HASHdigest[HASH_BYTES];
1236 struct berval *value;
1237 struct berval digest;
1238 digest.bv_val = HASHdigest;
1239 digest.bv_len = sizeof(HASHdigest);
1241 slen = strlen( syntax->ssyn_oid );
1242 mlen = strlen( mr->smr_oid );
1244 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1245 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1247 value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue),
1249 /* This usually happens if filter contains bad UTF8 */
1250 if( value == NULL ) {
1251 keys = ch_malloc( sizeof( struct berval * ) );
1253 return LDAP_SUCCESS;
1256 keys = ch_malloc( sizeof( struct berval * ) * 2 );
1258 HASH_Init( &HASHcontext );
1259 if( prefix != NULL && prefix->bv_len > 0 ) {
1260 HASH_Update( &HASHcontext,
1261 prefix->bv_val, prefix->bv_len );
1263 HASH_Update( &HASHcontext,
1264 syntax->ssyn_oid, slen );
1265 HASH_Update( &HASHcontext,
1266 mr->smr_oid, mlen );
1267 HASH_Update( &HASHcontext,
1268 value->bv_val, value->bv_len );
1269 HASH_Final( HASHdigest, &HASHcontext );
1271 keys[0] = ber_bvdup( &digest );
1274 ber_bvfree( value );
1277 return LDAP_SUCCESS;
1280 /* Substrings Index generation function */
1281 static int caseExactIgnoreSubstringsIndexer(
1286 struct berval *prefix,
1287 struct berval **values,
1288 struct berval ***keysp )
1293 struct berval **keys;
1294 struct berval **nvalues;
1296 HASH_CONTEXT HASHcontext;
1297 unsigned char HASHdigest[HASH_BYTES];
1298 struct berval digest;
1299 digest.bv_val = HASHdigest;
1300 digest.bv_len = sizeof(HASHdigest);
1304 for( i=0; values[i] != NULL; i++ ) {
1305 /* empty - just count them */
1308 /* we should have at least one value at this point */
1311 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1312 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1314 nvalues = ch_malloc( sizeof( struct berval * ) * (i+1) );
1315 for( i=0; values[i] != NULL; i++ ) {
1316 nvalues[i] = ber_bvstr( UTF8normalize( values[i],
1322 for( i=0; values[i] != NULL; i++ ) {
1323 /* count number of indices to generate */
1324 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1328 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1329 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1330 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1331 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1333 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1337 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1338 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1339 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1343 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1344 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1345 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1346 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1348 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1354 /* no keys to generate */
1356 ber_bvecfree( nvalues );
1357 return LDAP_SUCCESS;
1360 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1362 slen = strlen( syntax->ssyn_oid );
1363 mlen = strlen( mr->smr_oid );
1366 for( i=0; values[i] != NULL; i++ ) {
1368 struct berval *value;
1370 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1374 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1375 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1377 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1378 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1380 for( j=0; j<max; j++ ) {
1381 HASH_Init( &HASHcontext );
1382 if( prefix != NULL && prefix->bv_len > 0 ) {
1383 HASH_Update( &HASHcontext,
1384 prefix->bv_val, prefix->bv_len );
1387 HASH_Update( &HASHcontext,
1388 &pre, sizeof( pre ) );
1389 HASH_Update( &HASHcontext,
1390 syntax->ssyn_oid, slen );
1391 HASH_Update( &HASHcontext,
1392 mr->smr_oid, mlen );
1393 HASH_Update( &HASHcontext,
1395 SLAP_INDEX_SUBSTR_MAXLEN );
1396 HASH_Final( HASHdigest, &HASHcontext );
1398 keys[nkeys++] = ber_bvdup( &digest );
1402 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1403 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1405 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1408 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1409 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1410 HASH_Init( &HASHcontext );
1411 if( prefix != NULL && prefix->bv_len > 0 ) {
1412 HASH_Update( &HASHcontext,
1413 prefix->bv_val, prefix->bv_len );
1415 HASH_Update( &HASHcontext,
1416 &pre, sizeof( pre ) );
1417 HASH_Update( &HASHcontext,
1418 syntax->ssyn_oid, slen );
1419 HASH_Update( &HASHcontext,
1420 mr->smr_oid, mlen );
1421 HASH_Update( &HASHcontext,
1423 HASH_Final( HASHdigest, &HASHcontext );
1425 keys[nkeys++] = ber_bvdup( &digest );
1428 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1429 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1430 HASH_Init( &HASHcontext );
1431 if( prefix != NULL && prefix->bv_len > 0 ) {
1432 HASH_Update( &HASHcontext,
1433 prefix->bv_val, prefix->bv_len );
1435 HASH_Update( &HASHcontext,
1436 &pre, sizeof( pre ) );
1437 HASH_Update( &HASHcontext,
1438 syntax->ssyn_oid, slen );
1439 HASH_Update( &HASHcontext,
1440 mr->smr_oid, mlen );
1441 HASH_Update( &HASHcontext,
1442 &value->bv_val[value->bv_len-j], j );
1443 HASH_Final( HASHdigest, &HASHcontext );
1445 keys[nkeys++] = ber_bvdup( &digest );
1460 ber_bvecfree( nvalues );
1462 return LDAP_SUCCESS;
1465 static int caseExactIgnoreSubstringsFilter(
1470 struct berval *prefix,
1472 struct berval ***keysp )
1474 SubstringsAssertion *sa;
1476 ber_len_t nkeys = 0;
1477 size_t slen, mlen, klen;
1478 struct berval **keys;
1479 HASH_CONTEXT HASHcontext;
1480 unsigned char HASHdigest[HASH_BYTES];
1481 struct berval *value;
1482 struct berval digest;
1484 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1485 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1487 sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
1490 return LDAP_SUCCESS;
1493 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1494 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1499 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1501 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1502 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1503 /* don't bother accounting for stepping */
1504 nkeys += sa->sa_any[i]->bv_len -
1505 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1510 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1511 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1517 ber_bvfree( sa->sa_final );
1518 ber_bvecfree( sa->sa_any );
1519 ber_bvfree( sa->sa_initial );
1522 return LDAP_SUCCESS;
1525 digest.bv_val = HASHdigest;
1526 digest.bv_len = sizeof(HASHdigest);
1528 slen = strlen( syntax->ssyn_oid );
1529 mlen = strlen( mr->smr_oid );
1531 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1534 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1535 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1537 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1538 value = sa->sa_initial;
1540 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1541 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1543 HASH_Init( &HASHcontext );
1544 if( prefix != NULL && prefix->bv_len > 0 ) {
1545 HASH_Update( &HASHcontext,
1546 prefix->bv_val, prefix->bv_len );
1548 HASH_Update( &HASHcontext,
1549 &pre, sizeof( pre ) );
1550 HASH_Update( &HASHcontext,
1551 syntax->ssyn_oid, slen );
1552 HASH_Update( &HASHcontext,
1553 mr->smr_oid, mlen );
1554 HASH_Update( &HASHcontext,
1555 value->bv_val, klen );
1556 HASH_Final( HASHdigest, &HASHcontext );
1558 keys[nkeys++] = ber_bvdup( &digest );
1561 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1563 pre = SLAP_INDEX_SUBSTR_PREFIX;
1564 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1566 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1567 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1571 value = sa->sa_any[i];
1574 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1575 j += SLAP_INDEX_SUBSTR_STEP )
1577 HASH_Init( &HASHcontext );
1578 if( prefix != NULL && prefix->bv_len > 0 ) {
1579 HASH_Update( &HASHcontext,
1580 prefix->bv_val, prefix->bv_len );
1582 HASH_Update( &HASHcontext,
1583 &pre, sizeof( pre ) );
1584 HASH_Update( &HASHcontext,
1585 syntax->ssyn_oid, slen );
1586 HASH_Update( &HASHcontext,
1587 mr->smr_oid, mlen );
1588 HASH_Update( &HASHcontext,
1589 &value->bv_val[j], klen );
1590 HASH_Final( HASHdigest, &HASHcontext );
1592 keys[nkeys++] = ber_bvdup( &digest );
1598 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1599 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1601 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1602 value = sa->sa_final;
1604 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1605 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1607 HASH_Init( &HASHcontext );
1608 if( prefix != NULL && prefix->bv_len > 0 ) {
1609 HASH_Update( &HASHcontext,
1610 prefix->bv_val, prefix->bv_len );
1612 HASH_Update( &HASHcontext,
1613 &pre, sizeof( pre ) );
1614 HASH_Update( &HASHcontext,
1615 syntax->ssyn_oid, slen );
1616 HASH_Update( &HASHcontext,
1617 mr->smr_oid, mlen );
1618 HASH_Update( &HASHcontext,
1619 &value->bv_val[value->bv_len-klen], klen );
1620 HASH_Final( HASHdigest, &HASHcontext );
1622 keys[nkeys++] = ber_bvdup( &digest );
1632 ber_bvfree( sa->sa_final );
1633 ber_bvecfree( sa->sa_any );
1634 ber_bvfree( sa->sa_initial );
1637 return LDAP_SUCCESS;
1646 struct berval *value,
1647 void *assertedValue )
1649 *matchp = UTF8normcmp( value->bv_val,
1650 ((struct berval *) assertedValue)->bv_val,
1652 return LDAP_SUCCESS;
1658 struct berval *val )
1662 if( val->bv_len == 0 ) {
1663 /* disallow empty strings */
1664 return LDAP_INVALID_SYNTAX;
1667 if( OID_LEADCHAR(val->bv_val[0]) ) {
1669 for(i=1; i < val->bv_len; i++) {
1670 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1671 if( dot++ ) return 1;
1672 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1675 return LDAP_INVALID_SYNTAX;
1679 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1681 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1682 for(i=1; i < val->bv_len; i++) {
1683 if( !DESC_CHAR(val->bv_val[i] ) ) {
1684 return LDAP_INVALID_SYNTAX;
1688 return LDAP_SUCCESS;
1691 return LDAP_INVALID_SYNTAX;
1700 struct berval *value,
1701 void *assertedValue )
1704 int vsign=0, avsign=0;
1705 struct berval *asserted;
1706 ber_len_t vlen, avlen;
1709 /* Start off pessimistic */
1712 /* Skip past leading spaces/zeros, and get the sign of the *value number */
1714 vlen = value->bv_len;
1716 if( ASCII_SPACE(*v) || ( *v == '0' )) {
1717 /* empty -- skip spaces */
1719 else if ( *v == '+' ) {
1722 else if ( *v == '-' ) {
1725 else if ( ASCII_DIGIT(*v) ) {
1726 if ( vsign == 0 ) vsign = 1;
1734 /* Skip past leading spaces/zeros, and get the sign of the *assertedValue
1736 asserted = (struct berval *) assertedValue;
1737 av = asserted->bv_val;
1738 avlen = asserted->bv_len;
1740 if( ASCII_SPACE(*av) || ( *av == '0' )) {
1741 /* empty -- skip spaces */
1743 else if ( *av == '+' ) {
1746 else if ( *av == '-' ) {
1749 else if ( ASCII_DIGIT(*av) ) {
1750 if ( avsign == 0 ) avsign = 1;
1758 /* The two ?sign vars are now one of :
1759 -2 negative non-zero number
1761 0 0 collapse these three to 0
1763 +2 positive non-zero number
1765 if ( abs( vsign ) == 1 ) vsign = 0;
1766 if ( abs( avsign ) == 1 ) avsign = 0;
1768 if( vsign != avsign ) return LDAP_SUCCESS;
1770 /* Check the significant digits */
1771 while( vlen && avlen ) {
1772 if( *v != *av ) break;
1779 /* If all digits compared equal, the numbers are equal */
1780 if(( vlen == 0 ) && ( avlen == 0 )) {
1783 return LDAP_SUCCESS;
1789 struct berval *val )
1793 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1795 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
1796 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1797 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1798 return LDAP_INVALID_SYNTAX;
1801 for( i=1; i < val->bv_len; i++ ) {
1802 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1805 return LDAP_SUCCESS;
1812 struct berval **normalized )
1816 struct berval *newval;
1823 /* Ignore leading spaces */
1824 while ( len && ( *p == ' ' )) {
1831 negative = ( *p == '-' );
1832 if(( *p == '-' ) || ( *p == '+' )) {
1838 /* Ignore leading zeros */
1839 while ( len && ( *p == '0' )) {
1844 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
1846 /* If there are no non-zero digits left, the number is zero, otherwise
1847 allocate space for the number and copy it into the buffer */
1849 newval->bv_val = ch_strdup("0");
1853 newval->bv_len = len+negative;
1854 newval->bv_val = ch_malloc( newval->bv_len );
1856 newval->bv_val[0] = '-';
1858 memcpy( newval->bv_val + negative, p, len );
1861 *normalized = newval;
1862 return LDAP_SUCCESS;
1865 /* Index generation function */
1866 static int integerIndexer(
1871 struct berval *prefix,
1872 struct berval **values,
1873 struct berval ***keysp )
1876 struct berval **keys;
1878 /* we should have at least one value at this point */
1879 assert( values != NULL && values[0] != NULL );
1881 for( i=0; values[i] != NULL; i++ ) {
1882 /* empty -- just count them */
1885 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
1887 for( i=0; values[i] != NULL; i++ ) {
1888 integerNormalize( syntax, values[i], &keys[i] );
1893 return LDAP_SUCCESS;
1896 /* Index generation function */
1897 static int integerFilter(
1902 struct berval *prefix,
1904 struct berval ***keysp )
1906 struct berval **keys;
1908 keys = ch_malloc( sizeof( struct berval * ) * 2 );
1909 integerNormalize( syntax, assertValue, &keys[0] );
1913 return LDAP_SUCCESS;
1918 countryStringValidate(
1920 struct berval *val )
1922 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
1924 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
1925 return LDAP_INVALID_SYNTAX;
1927 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
1928 return LDAP_INVALID_SYNTAX;
1931 return LDAP_SUCCESS;
1935 printableStringValidate(
1937 struct berval *val )
1941 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1943 for(i=0; i < val->bv_len; i++) {
1944 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
1945 return LDAP_INVALID_SYNTAX;
1949 return LDAP_SUCCESS;
1953 printablesStringValidate(
1955 struct berval *val )
1959 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1961 for(i=0; i < val->bv_len; i++) {
1962 if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
1963 return LDAP_INVALID_SYNTAX;
1967 return LDAP_SUCCESS;
1973 struct berval *val )
1977 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1979 for(i=0; i < val->bv_len; i++) {
1980 if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1983 return LDAP_SUCCESS;
1990 struct berval **normalized )
1992 struct berval *newval;
1995 newval = ch_malloc( sizeof( struct berval ) );
1999 /* Ignore initial whitespace */
2000 while ( ASCII_SPACE( *p ) ) {
2006 return LDAP_INVALID_SYNTAX;
2009 newval->bv_val = ch_strdup( p );
2010 p = q = newval->bv_val;
2013 if ( ASCII_SPACE( *p ) ) {
2016 /* Ignore the extra whitespace */
2017 while ( ASCII_SPACE( *p ) ) {
2025 assert( *newval->bv_val );
2026 assert( newval->bv_val < p );
2029 /* cannot start with a space */
2030 assert( !ASCII_SPACE(*newval->bv_val) );
2033 * If the string ended in space, backup the pointer one
2034 * position. One is enough because the above loop collapsed
2035 * all whitespace to a single space.
2038 if ( ASCII_SPACE( q[-1] ) ) {
2042 /* cannot end with a space */
2043 assert( !ASCII_SPACE( q[-1] ) );
2045 /* null terminate */
2048 newval->bv_len = q - newval->bv_val;
2049 *normalized = newval;
2051 return LDAP_SUCCESS;
2060 struct berval *value,
2061 void *assertedValue )
2063 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2066 match = strncmp( value->bv_val,
2067 ((struct berval *) assertedValue)->bv_val,
2072 return LDAP_SUCCESS;
2076 caseExactIA5SubstringsMatch(
2081 struct berval *value,
2082 void *assertedValue )
2085 SubstringsAssertion *sub = assertedValue;
2086 struct berval left = *value;
2090 /* Add up asserted input length */
2091 if( sub->sa_initial ) {
2092 inlen += sub->sa_initial->bv_len;
2095 for(i=0; sub->sa_any[i] != NULL; i++) {
2096 inlen += sub->sa_any[i]->bv_len;
2099 if( sub->sa_final ) {
2100 inlen += sub->sa_final->bv_len;
2103 if( sub->sa_initial ) {
2104 if( inlen > left.bv_len ) {
2109 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
2110 sub->sa_initial->bv_len );
2116 left.bv_val += sub->sa_initial->bv_len;
2117 left.bv_len -= sub->sa_initial->bv_len;
2118 inlen -= sub->sa_initial->bv_len;
2121 if( sub->sa_final ) {
2122 if( inlen > left.bv_len ) {
2127 match = strncmp( sub->sa_final->bv_val,
2128 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2129 sub->sa_final->bv_len );
2135 left.bv_len -= sub->sa_final->bv_len;
2136 inlen -= sub->sa_final->bv_len;
2140 for(i=0; sub->sa_any[i]; i++) {
2145 if( inlen > left.bv_len ) {
2146 /* not enough length */
2151 if( sub->sa_any[i]->bv_len == 0 ) {
2155 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
2162 idx = p - left.bv_val;
2163 assert( idx < left.bv_len );
2165 if( idx >= left.bv_len ) {
2166 /* this shouldn't happen */
2173 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2174 /* not enough left */
2179 match = strncmp( left.bv_val,
2180 sub->sa_any[i]->bv_val,
2181 sub->sa_any[i]->bv_len );
2189 left.bv_val += sub->sa_any[i]->bv_len;
2190 left.bv_len -= sub->sa_any[i]->bv_len;
2191 inlen -= sub->sa_any[i]->bv_len;
2197 return LDAP_SUCCESS;
2200 /* Index generation function */
2201 static int caseExactIA5Indexer(
2206 struct berval *prefix,
2207 struct berval **values,
2208 struct berval ***keysp )
2212 struct berval **keys;
2213 HASH_CONTEXT HASHcontext;
2214 unsigned char HASHdigest[HASH_BYTES];
2215 struct berval digest;
2216 digest.bv_val = HASHdigest;
2217 digest.bv_len = sizeof(HASHdigest);
2219 for( i=0; values[i] != NULL; i++ ) {
2220 /* empty - just count them */
2223 /* we should have at least one value at this point */
2226 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2228 slen = strlen( syntax->ssyn_oid );
2229 mlen = strlen( mr->smr_oid );
2231 for( i=0; values[i] != NULL; i++ ) {
2232 struct berval *value = values[i];
2234 HASH_Init( &HASHcontext );
2235 if( prefix != NULL && prefix->bv_len > 0 ) {
2236 HASH_Update( &HASHcontext,
2237 prefix->bv_val, prefix->bv_len );
2239 HASH_Update( &HASHcontext,
2240 syntax->ssyn_oid, slen );
2241 HASH_Update( &HASHcontext,
2242 mr->smr_oid, mlen );
2243 HASH_Update( &HASHcontext,
2244 value->bv_val, value->bv_len );
2245 HASH_Final( HASHdigest, &HASHcontext );
2247 keys[i] = ber_bvdup( &digest );
2252 return LDAP_SUCCESS;
2255 /* Index generation function */
2256 static int caseExactIA5Filter(
2261 struct berval *prefix,
2263 struct berval ***keysp )
2266 struct berval **keys;
2267 HASH_CONTEXT HASHcontext;
2268 unsigned char HASHdigest[HASH_BYTES];
2269 struct berval *value;
2270 struct berval digest;
2271 digest.bv_val = HASHdigest;
2272 digest.bv_len = sizeof(HASHdigest);
2274 slen = strlen( syntax->ssyn_oid );
2275 mlen = strlen( mr->smr_oid );
2277 value = (struct berval *) assertValue;
2279 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2281 HASH_Init( &HASHcontext );
2282 if( prefix != NULL && prefix->bv_len > 0 ) {
2283 HASH_Update( &HASHcontext,
2284 prefix->bv_val, prefix->bv_len );
2286 HASH_Update( &HASHcontext,
2287 syntax->ssyn_oid, slen );
2288 HASH_Update( &HASHcontext,
2289 mr->smr_oid, mlen );
2290 HASH_Update( &HASHcontext,
2291 value->bv_val, value->bv_len );
2292 HASH_Final( HASHdigest, &HASHcontext );
2294 keys[0] = ber_bvdup( &digest );
2298 return LDAP_SUCCESS;
2301 /* Substrings Index generation function */
2302 static int caseExactIA5SubstringsIndexer(
2307 struct berval *prefix,
2308 struct berval **values,
2309 struct berval ***keysp )
2313 struct berval **keys;
2314 HASH_CONTEXT HASHcontext;
2315 unsigned char HASHdigest[HASH_BYTES];
2316 struct berval digest;
2317 digest.bv_val = HASHdigest;
2318 digest.bv_len = sizeof(HASHdigest);
2320 /* we should have at least one value at this point */
2321 assert( values != NULL && values[0] != NULL );
2324 for( i=0; values[i] != NULL; i++ ) {
2325 /* count number of indices to generate */
2326 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2330 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2331 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2332 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2333 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2335 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2339 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2340 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2341 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2345 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2346 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2347 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2348 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2350 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2356 /* no keys to generate */
2358 return LDAP_SUCCESS;
2361 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2363 slen = strlen( syntax->ssyn_oid );
2364 mlen = strlen( mr->smr_oid );
2367 for( i=0; values[i] != NULL; i++ ) {
2369 struct berval *value;
2372 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2374 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2375 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2377 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2378 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2380 for( j=0; j<max; j++ ) {
2381 HASH_Init( &HASHcontext );
2382 if( prefix != NULL && prefix->bv_len > 0 ) {
2383 HASH_Update( &HASHcontext,
2384 prefix->bv_val, prefix->bv_len );
2387 HASH_Update( &HASHcontext,
2388 &pre, sizeof( pre ) );
2389 HASH_Update( &HASHcontext,
2390 syntax->ssyn_oid, slen );
2391 HASH_Update( &HASHcontext,
2392 mr->smr_oid, mlen );
2393 HASH_Update( &HASHcontext,
2395 SLAP_INDEX_SUBSTR_MAXLEN );
2396 HASH_Final( HASHdigest, &HASHcontext );
2398 keys[nkeys++] = ber_bvdup( &digest );
2402 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2403 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2405 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2408 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2409 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2410 HASH_Init( &HASHcontext );
2411 if( prefix != NULL && prefix->bv_len > 0 ) {
2412 HASH_Update( &HASHcontext,
2413 prefix->bv_val, prefix->bv_len );
2415 HASH_Update( &HASHcontext,
2416 &pre, sizeof( pre ) );
2417 HASH_Update( &HASHcontext,
2418 syntax->ssyn_oid, slen );
2419 HASH_Update( &HASHcontext,
2420 mr->smr_oid, mlen );
2421 HASH_Update( &HASHcontext,
2423 HASH_Final( HASHdigest, &HASHcontext );
2425 keys[nkeys++] = ber_bvdup( &digest );
2428 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2429 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2430 HASH_Init( &HASHcontext );
2431 if( prefix != NULL && prefix->bv_len > 0 ) {
2432 HASH_Update( &HASHcontext,
2433 prefix->bv_val, prefix->bv_len );
2435 HASH_Update( &HASHcontext,
2436 &pre, sizeof( pre ) );
2437 HASH_Update( &HASHcontext,
2438 syntax->ssyn_oid, slen );
2439 HASH_Update( &HASHcontext,
2440 mr->smr_oid, mlen );
2441 HASH_Update( &HASHcontext,
2442 &value->bv_val[value->bv_len-j], j );
2443 HASH_Final( HASHdigest, &HASHcontext );
2445 keys[nkeys++] = ber_bvdup( &digest );
2459 return LDAP_SUCCESS;
2462 static int caseExactIA5SubstringsFilter(
2467 struct berval *prefix,
2469 struct berval ***keysp )
2471 SubstringsAssertion *sa = assertValue;
2473 ber_len_t nkeys = 0;
2474 size_t slen, mlen, klen;
2475 struct berval **keys;
2476 HASH_CONTEXT HASHcontext;
2477 unsigned char HASHdigest[HASH_BYTES];
2478 struct berval *value;
2479 struct berval digest;
2481 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2482 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2487 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2489 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2490 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2491 /* don't bother accounting for stepping */
2492 nkeys += sa->sa_any[i]->bv_len -
2493 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2498 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2499 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2506 return LDAP_SUCCESS;
2509 digest.bv_val = HASHdigest;
2510 digest.bv_len = sizeof(HASHdigest);
2512 slen = strlen( syntax->ssyn_oid );
2513 mlen = strlen( mr->smr_oid );
2515 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2518 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2519 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2521 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2522 value = sa->sa_initial;
2524 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2525 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2527 HASH_Init( &HASHcontext );
2528 if( prefix != NULL && prefix->bv_len > 0 ) {
2529 HASH_Update( &HASHcontext,
2530 prefix->bv_val, prefix->bv_len );
2532 HASH_Update( &HASHcontext,
2533 &pre, sizeof( pre ) );
2534 HASH_Update( &HASHcontext,
2535 syntax->ssyn_oid, slen );
2536 HASH_Update( &HASHcontext,
2537 mr->smr_oid, mlen );
2538 HASH_Update( &HASHcontext,
2539 value->bv_val, klen );
2540 HASH_Final( HASHdigest, &HASHcontext );
2542 keys[nkeys++] = ber_bvdup( &digest );
2545 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2547 pre = SLAP_INDEX_SUBSTR_PREFIX;
2548 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2550 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2551 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2555 value = sa->sa_any[i];
2558 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2559 j += SLAP_INDEX_SUBSTR_STEP )
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[j], klen );
2574 HASH_Final( HASHdigest, &HASHcontext );
2576 keys[nkeys++] = ber_bvdup( &digest );
2581 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2582 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2584 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2585 value = sa->sa_final;
2587 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2588 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2590 HASH_Init( &HASHcontext );
2591 if( prefix != NULL && prefix->bv_len > 0 ) {
2592 HASH_Update( &HASHcontext,
2593 prefix->bv_val, prefix->bv_len );
2595 HASH_Update( &HASHcontext,
2596 &pre, sizeof( pre ) );
2597 HASH_Update( &HASHcontext,
2598 syntax->ssyn_oid, slen );
2599 HASH_Update( &HASHcontext,
2600 mr->smr_oid, mlen );
2601 HASH_Update( &HASHcontext,
2602 &value->bv_val[value->bv_len-klen], klen );
2603 HASH_Final( HASHdigest, &HASHcontext );
2605 keys[nkeys++] = ber_bvdup( &digest );
2616 return LDAP_SUCCESS;
2625 struct berval *value,
2626 void *assertedValue )
2628 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2630 if( match == 0 && value->bv_len ) {
2631 match = strncasecmp( value->bv_val,
2632 ((struct berval *) assertedValue)->bv_val,
2637 return LDAP_SUCCESS;
2641 caseIgnoreIA5SubstringsMatch(
2646 struct berval *value,
2647 void *assertedValue )
2650 SubstringsAssertion *sub = assertedValue;
2651 struct berval left = *value;
2655 /* Add up asserted input length */
2656 if( sub->sa_initial ) {
2657 inlen += sub->sa_initial->bv_len;
2660 for(i=0; sub->sa_any[i] != NULL; i++) {
2661 inlen += sub->sa_any[i]->bv_len;
2664 if( sub->sa_final ) {
2665 inlen += sub->sa_final->bv_len;
2668 if( sub->sa_initial ) {
2669 if( inlen > left.bv_len ) {
2674 match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
2675 sub->sa_initial->bv_len );
2681 left.bv_val += sub->sa_initial->bv_len;
2682 left.bv_len -= sub->sa_initial->bv_len;
2683 inlen -= sub->sa_initial->bv_len;
2686 if( sub->sa_final ) {
2687 if( inlen > left.bv_len ) {
2692 match = strncasecmp( sub->sa_final->bv_val,
2693 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2694 sub->sa_final->bv_len );
2700 left.bv_len -= sub->sa_final->bv_len;
2701 inlen -= sub->sa_final->bv_len;
2705 for(i=0; sub->sa_any[i]; i++) {
2710 if( inlen > left.bv_len ) {
2711 /* not enough length */
2716 if( sub->sa_any[i]->bv_len == 0 ) {
2720 p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
2727 idx = p - left.bv_val;
2728 assert( idx < left.bv_len );
2730 if( idx >= left.bv_len ) {
2731 /* this shouldn't happen */
2738 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2739 /* not enough left */
2744 match = strncasecmp( left.bv_val,
2745 sub->sa_any[i]->bv_val,
2746 sub->sa_any[i]->bv_len );
2755 left.bv_val += sub->sa_any[i]->bv_len;
2756 left.bv_len -= sub->sa_any[i]->bv_len;
2757 inlen -= sub->sa_any[i]->bv_len;
2763 return LDAP_SUCCESS;
2766 /* Index generation function */
2767 static int caseIgnoreIA5Indexer(
2772 struct berval *prefix,
2773 struct berval **values,
2774 struct berval ***keysp )
2778 struct berval **keys;
2779 HASH_CONTEXT HASHcontext;
2780 unsigned char HASHdigest[HASH_BYTES];
2781 struct berval digest;
2782 digest.bv_val = HASHdigest;
2783 digest.bv_len = sizeof(HASHdigest);
2785 /* we should have at least one value at this point */
2786 assert( values != NULL && values[0] != NULL );
2788 for( i=0; values[i] != NULL; i++ ) {
2789 /* just count them */
2792 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2794 slen = strlen( syntax->ssyn_oid );
2795 mlen = strlen( mr->smr_oid );
2797 for( i=0; values[i] != NULL; i++ ) {
2798 struct berval *value = ber_bvdup( values[i] );
2799 ldap_pvt_str2upper( value->bv_val );
2801 HASH_Init( &HASHcontext );
2802 if( prefix != NULL && prefix->bv_len > 0 ) {
2803 HASH_Update( &HASHcontext,
2804 prefix->bv_val, prefix->bv_len );
2806 HASH_Update( &HASHcontext,
2807 syntax->ssyn_oid, slen );
2808 HASH_Update( &HASHcontext,
2809 mr->smr_oid, mlen );
2810 HASH_Update( &HASHcontext,
2811 value->bv_val, value->bv_len );
2812 HASH_Final( HASHdigest, &HASHcontext );
2814 ber_bvfree( value );
2816 keys[i] = ber_bvdup( &digest );
2821 return LDAP_SUCCESS;
2824 /* Index generation function */
2825 static int caseIgnoreIA5Filter(
2830 struct berval *prefix,
2832 struct berval ***keysp )
2835 struct berval **keys;
2836 HASH_CONTEXT HASHcontext;
2837 unsigned char HASHdigest[HASH_BYTES];
2838 struct berval *value;
2839 struct berval digest;
2840 digest.bv_val = HASHdigest;
2841 digest.bv_len = sizeof(HASHdigest);
2843 slen = strlen( syntax->ssyn_oid );
2844 mlen = strlen( mr->smr_oid );
2846 value = ber_bvdup( (struct berval *) assertValue );
2847 ldap_pvt_str2upper( value->bv_val );
2849 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2851 HASH_Init( &HASHcontext );
2852 if( prefix != NULL && prefix->bv_len > 0 ) {
2853 HASH_Update( &HASHcontext,
2854 prefix->bv_val, prefix->bv_len );
2856 HASH_Update( &HASHcontext,
2857 syntax->ssyn_oid, slen );
2858 HASH_Update( &HASHcontext,
2859 mr->smr_oid, mlen );
2860 HASH_Update( &HASHcontext,
2861 value->bv_val, value->bv_len );
2862 HASH_Final( HASHdigest, &HASHcontext );
2864 keys[0] = ber_bvdup( &digest );
2867 ber_bvfree( value );
2871 return LDAP_SUCCESS;
2874 /* Substrings Index generation function */
2875 static int caseIgnoreIA5SubstringsIndexer(
2880 struct berval *prefix,
2881 struct berval **values,
2882 struct berval ***keysp )
2886 struct berval **keys;
2887 HASH_CONTEXT HASHcontext;
2888 unsigned char HASHdigest[HASH_BYTES];
2889 struct berval digest;
2890 digest.bv_val = HASHdigest;
2891 digest.bv_len = sizeof(HASHdigest);
2893 /* we should have at least one value at this point */
2894 assert( values != NULL && values[0] != NULL );
2897 for( i=0; values[i] != NULL; i++ ) {
2898 /* count number of indices to generate */
2899 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2903 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2904 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2905 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2906 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2908 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2912 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2913 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2914 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2918 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2919 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2920 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2921 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2923 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2929 /* no keys to generate */
2931 return LDAP_SUCCESS;
2934 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2936 slen = strlen( syntax->ssyn_oid );
2937 mlen = strlen( mr->smr_oid );
2940 for( i=0; values[i] != NULL; i++ ) {
2942 struct berval *value;
2944 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2946 value = ber_bvdup( values[i] );
2947 ldap_pvt_str2upper( value->bv_val );
2949 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2950 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2952 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2953 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2955 for( j=0; j<max; j++ ) {
2956 HASH_Init( &HASHcontext );
2957 if( prefix != NULL && prefix->bv_len > 0 ) {
2958 HASH_Update( &HASHcontext,
2959 prefix->bv_val, prefix->bv_len );
2962 HASH_Update( &HASHcontext,
2963 &pre, sizeof( pre ) );
2964 HASH_Update( &HASHcontext,
2965 syntax->ssyn_oid, slen );
2966 HASH_Update( &HASHcontext,
2967 mr->smr_oid, mlen );
2968 HASH_Update( &HASHcontext,
2970 SLAP_INDEX_SUBSTR_MAXLEN );
2971 HASH_Final( HASHdigest, &HASHcontext );
2973 keys[nkeys++] = ber_bvdup( &digest );
2977 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2978 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2980 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2983 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2984 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2985 HASH_Init( &HASHcontext );
2986 if( prefix != NULL && prefix->bv_len > 0 ) {
2987 HASH_Update( &HASHcontext,
2988 prefix->bv_val, prefix->bv_len );
2990 HASH_Update( &HASHcontext,
2991 &pre, sizeof( pre ) );
2992 HASH_Update( &HASHcontext,
2993 syntax->ssyn_oid, slen );
2994 HASH_Update( &HASHcontext,
2995 mr->smr_oid, mlen );
2996 HASH_Update( &HASHcontext,
2998 HASH_Final( HASHdigest, &HASHcontext );
3000 keys[nkeys++] = ber_bvdup( &digest );
3003 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3004 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3005 HASH_Init( &HASHcontext );
3006 if( prefix != NULL && prefix->bv_len > 0 ) {
3007 HASH_Update( &HASHcontext,
3008 prefix->bv_val, prefix->bv_len );
3010 HASH_Update( &HASHcontext,
3011 &pre, sizeof( pre ) );
3012 HASH_Update( &HASHcontext,
3013 syntax->ssyn_oid, slen );
3014 HASH_Update( &HASHcontext,
3015 mr->smr_oid, mlen );
3016 HASH_Update( &HASHcontext,
3017 &value->bv_val[value->bv_len-j], j );
3018 HASH_Final( HASHdigest, &HASHcontext );
3020 keys[nkeys++] = ber_bvdup( &digest );
3025 ber_bvfree( value );
3036 return LDAP_SUCCESS;
3039 static int caseIgnoreIA5SubstringsFilter(
3044 struct berval *prefix,
3046 struct berval ***keysp )
3048 SubstringsAssertion *sa = assertValue;
3050 ber_len_t nkeys = 0;
3051 size_t slen, mlen, klen;
3052 struct berval **keys;
3053 HASH_CONTEXT HASHcontext;
3054 unsigned char HASHdigest[HASH_BYTES];
3055 struct berval *value;
3056 struct berval digest;
3058 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3059 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3064 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3066 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3067 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3068 /* don't bother accounting for stepping */
3069 nkeys += sa->sa_any[i]->bv_len -
3070 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3075 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3076 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3083 return LDAP_SUCCESS;
3086 digest.bv_val = HASHdigest;
3087 digest.bv_len = sizeof(HASHdigest);
3089 slen = strlen( syntax->ssyn_oid );
3090 mlen = strlen( mr->smr_oid );
3092 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
3095 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3096 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3098 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3099 value = ber_bvdup( sa->sa_initial );
3100 ldap_pvt_str2upper( value->bv_val );
3102 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3103 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3105 HASH_Init( &HASHcontext );
3106 if( prefix != NULL && prefix->bv_len > 0 ) {
3107 HASH_Update( &HASHcontext,
3108 prefix->bv_val, prefix->bv_len );
3110 HASH_Update( &HASHcontext,
3111 &pre, sizeof( pre ) );
3112 HASH_Update( &HASHcontext,
3113 syntax->ssyn_oid, slen );
3114 HASH_Update( &HASHcontext,
3115 mr->smr_oid, mlen );
3116 HASH_Update( &HASHcontext,
3117 value->bv_val, klen );
3118 HASH_Final( HASHdigest, &HASHcontext );
3120 ber_bvfree( value );
3121 keys[nkeys++] = ber_bvdup( &digest );
3124 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3126 pre = SLAP_INDEX_SUBSTR_PREFIX;
3127 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3129 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3130 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3134 value = ber_bvdup( sa->sa_any[i] );
3135 ldap_pvt_str2upper( value->bv_val );
3138 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3139 j += SLAP_INDEX_SUBSTR_STEP )
3141 HASH_Init( &HASHcontext );
3142 if( prefix != NULL && prefix->bv_len > 0 ) {
3143 HASH_Update( &HASHcontext,
3144 prefix->bv_val, prefix->bv_len );
3146 HASH_Update( &HASHcontext,
3147 &pre, sizeof( pre ) );
3148 HASH_Update( &HASHcontext,
3149 syntax->ssyn_oid, slen );
3150 HASH_Update( &HASHcontext,
3151 mr->smr_oid, mlen );
3152 HASH_Update( &HASHcontext,
3153 &value->bv_val[j], klen );
3154 HASH_Final( HASHdigest, &HASHcontext );
3156 keys[nkeys++] = ber_bvdup( &digest );
3159 ber_bvfree( value );
3163 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3164 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3166 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3167 value = ber_bvdup( sa->sa_final );
3168 ldap_pvt_str2upper( value->bv_val );
3170 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3171 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3173 HASH_Init( &HASHcontext );
3174 if( prefix != NULL && prefix->bv_len > 0 ) {
3175 HASH_Update( &HASHcontext,
3176 prefix->bv_val, prefix->bv_len );
3178 HASH_Update( &HASHcontext,
3179 &pre, sizeof( pre ) );
3180 HASH_Update( &HASHcontext,
3181 syntax->ssyn_oid, slen );
3182 HASH_Update( &HASHcontext,
3183 mr->smr_oid, mlen );
3184 HASH_Update( &HASHcontext,
3185 &value->bv_val[value->bv_len-klen], klen );
3186 HASH_Final( HASHdigest, &HASHcontext );
3188 ber_bvfree( value );
3189 keys[nkeys++] = ber_bvdup( &digest );
3200 return LDAP_SUCCESS;
3204 numericStringValidate(
3210 for(i=0; i < in->bv_len; i++) {
3211 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3212 return LDAP_INVALID_SYNTAX;
3216 return LDAP_SUCCESS;
3220 numericStringNormalize(
3223 struct berval **normalized )
3225 /* removal all spaces */
3226 struct berval *newval;
3229 newval = ch_malloc( sizeof( struct berval ) );
3230 newval->bv_val = ch_malloc( val->bv_len + 1 );
3236 if ( ASCII_SPACE( *p ) ) {
3237 /* Ignore whitespace */
3244 /* we should have copied no more then is in val */
3245 assert( (q - newval->bv_val) <= (p - val->bv_val) );
3247 /* null terminate */
3250 newval->bv_len = q - newval->bv_val;
3251 *normalized = newval;
3253 return LDAP_SUCCESS;
3257 objectIdentifierFirstComponentMatch(
3262 struct berval *value,
3263 void *assertedValue )
3265 int rc = LDAP_SUCCESS;
3267 struct berval *asserted = (struct berval *) assertedValue;
3271 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3272 return LDAP_INVALID_SYNTAX;
3275 /* trim leading white space */
3276 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3280 /* grab next word */
3281 oid.bv_val = &value->bv_val[i];
3282 oid.bv_len = value->bv_len - i;
3283 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3288 /* insert attributeTypes, objectclass check here */
3289 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3290 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3293 char *stored = ch_malloc( oid.bv_len + 1 );
3294 AC_MEMCPY( stored, oid.bv_val, oid.bv_len );
3295 stored[oid.bv_len] = '\0';
3297 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3298 MatchingRule *asserted_mr = mr_find( asserted->bv_val );
3299 MatchingRule *stored_mr = mr_find( stored );
3301 if( asserted_mr == NULL ) {
3302 rc = SLAPD_COMPARE_UNDEFINED;
3304 match = asserted_mr != stored_mr;
3307 } else if ( !strcmp( syntax->ssyn_oid,
3308 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3310 AttributeType *asserted_at = at_find( asserted->bv_val );
3311 AttributeType *stored_at = at_find( stored );
3313 if( asserted_at == NULL ) {
3314 rc = SLAPD_COMPARE_UNDEFINED;
3316 match = asserted_at != stored_at;
3319 } else if ( !strcmp( syntax->ssyn_oid,
3320 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3322 ObjectClass *asserted_oc = oc_find( asserted->bv_val );
3323 ObjectClass *stored_oc = oc_find( stored );
3325 if( asserted_oc == NULL ) {
3326 rc = SLAPD_COMPARE_UNDEFINED;
3328 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 q = ch_malloc( (end-begin+1)+1 );
3605 AC_MEMCPY( q, begin, end-begin+1 );
3606 q[end-begin+1] = '\0';
3607 *serial = ber_bvstr(q);
3609 /* 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 q = ch_malloc( (end-begin+1)+1 );
3617 AC_MEMCPY( q, begin, end-begin+1 );
3618 q[end-begin+1] = '\0';
3619 *issuer_dn = ber_bvstr(dn_normalize(q));
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(( "schema", LDAP_LEVEL_ENTRY,
3645 "certificateExactMatch: error parsing cert: %s\n",
3646 ERR_error_string(ERR_get_error(),NULL)));
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 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3656 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
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(( "schema", LDAP_LEVEL_ENTRY,
3686 "certificateExactMatch: %d\n %s $ %s\n %s $ %s\n",
3687 *matchp, serial->bv_val, issuer_dn->bv_val,
3688 asserted->serial->bv_val, asserted_issuer_dn->bv_val));
3690 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3691 "%d\n\t\"%s $ %s\"\n",
3692 *matchp, serial->bv_val, issuer_dn->bv_val );
3693 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3694 asserted_serial->bv_val, asserted_issuer_dn->bv_val,
3699 ber_bvfree(issuer_dn);
3700 ber_bvfree(asserted_serial);
3701 ber_bvfree(asserted_issuer_dn);
3707 * Index generation function
3708 * We just index the serials, in most scenarios the issuer DN is one of
3709 * a very small set of values.
3711 static int certificateExactIndexer(
3716 struct berval *prefix,
3717 struct berval **values,
3718 struct berval ***keysp )
3721 struct berval **keys;
3724 struct berval * serial;
3726 /* we should have at least one value at this point */
3727 assert( values != NULL && values[0] != NULL );
3729 for( i=0; values[i] != NULL; i++ ) {
3730 /* empty -- just count them */
3733 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
3735 for( i=0; values[i] != NULL; i++ ) {
3736 p = values[i]->bv_val;
3737 xcert = d2i_X509(NULL, &p, values[i]->bv_len);
3740 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3741 "certificateExactIndexer: error parsing cert: %s\n",
3742 ERR_error_string(ERR_get_error(),NULL)));
3744 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3745 "error parsing cert: %s\n",
3746 ERR_error_string(ERR_get_error(),NULL),
3749 /* Do we leak keys on error? */
3750 return LDAP_INVALID_SYNTAX;
3753 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3755 integerNormalize( slap_schema.si_syn_integer,
3760 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3761 "certificateExactIndexer: returning: %s\n",
3764 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3773 return LDAP_SUCCESS;
3776 /* Index generation function */
3777 /* We think this is always called with a value in matching rule syntax */
3778 static int certificateExactFilter(
3783 struct berval *prefix,
3785 struct berval ***keysp )
3787 struct berval **keys;
3788 struct berval *asserted_serial;
3789 struct berval *asserted_issuer_dn;
3791 serial_and_issuer_parse(assertValue,
3793 &asserted_issuer_dn);
3795 keys = ch_malloc( sizeof( struct berval * ) * 2 );
3796 integerNormalize( syntax, asserted_serial, &keys[0] );
3800 ber_bvfree(asserted_serial);
3801 ber_bvfree(asserted_issuer_dn);
3802 return LDAP_SUCCESS;
3807 check_time_syntax (struct berval *val,
3811 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3812 static int mdays[2][12] = {
3813 /* non-leap years */
3814 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3816 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3819 int part, c, tzoffset, leapyear = 0 ;
3821 if( val->bv_len == 0 ) {
3822 return LDAP_INVALID_SYNTAX;
3825 p = (char *)val->bv_val;
3826 e = p + val->bv_len;
3828 /* Ignore initial whitespace */
3829 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3833 if (e - p < 13 - (2 * start)) {
3834 return LDAP_INVALID_SYNTAX;
3837 for (part = 0; part < 9; part++) {
3841 for (part = start; part < 7; part++) {
3843 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3850 return LDAP_INVALID_SYNTAX;
3852 if (c < 0 || c > 9) {
3853 return LDAP_INVALID_SYNTAX;
3859 return LDAP_INVALID_SYNTAX;
3861 if (c < 0 || c > 9) {
3862 return LDAP_INVALID_SYNTAX;
3867 if (part == 2 || part == 3) {
3870 if (parts[part] < 0) {
3871 return LDAP_INVALID_SYNTAX;
3873 if (parts[part] > ceiling[part]) {
3874 return LDAP_INVALID_SYNTAX;
3878 /* leapyear check for the Gregorian calendar (year>1581) */
3879 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
3880 ((parts[0] % 4 == 0) && (parts[1] == 0)))
3885 if (parts[3] > mdays[leapyear][parts[2]]) {
3886 return LDAP_INVALID_SYNTAX;
3891 tzoffset = 0; /* UTC */
3892 } else if (c != '+' && c != '-') {
3893 return LDAP_INVALID_SYNTAX;
3897 } else /* c == '+' */ {
3902 return LDAP_INVALID_SYNTAX;
3905 for (part = 7; part < 9; part++) {
3907 if (c < 0 || c > 9) {
3908 return LDAP_INVALID_SYNTAX;
3913 if (c < 0 || c > 9) {
3914 return LDAP_INVALID_SYNTAX;
3918 if (parts[part] < 0 || parts[part] > ceiling[part]) {
3919 return LDAP_INVALID_SYNTAX;
3924 /* Ignore trailing whitespace */
3925 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3929 return LDAP_INVALID_SYNTAX;
3932 switch ( tzoffset ) {
3933 case -1: /* negativ offset to UTC, ie west of Greenwich */
3934 parts[4] += parts[7];
3935 parts[5] += parts[8];
3936 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
3940 c = mdays[leapyear][parts[2]];
3942 if (parts[part] > c) {
3943 parts[part] -= c + 1;
3948 case 1: /* positive offset to UTC, ie east of Greenwich */
3949 parts[4] -= parts[7];
3950 parts[5] -= parts[8];
3951 for (part = 6; --part > 0; ) {
3955 /* first arg to % needs to be non negativ */
3956 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
3958 if (parts[part] < 0) {
3959 parts[part] += c + 1;
3964 case 0: /* already UTC */
3968 return LDAP_SUCCESS;
3975 struct berval **normalized )
3980 rc = check_time_syntax(val, 1, parts);
3981 if (rc != LDAP_SUCCESS) {
3986 out = ch_malloc( sizeof(struct berval) );
3988 return LBER_ERROR_MEMORY;
3991 out->bv_val = ch_malloc( 14 );
3992 if ( out->bv_val == NULL ) {
3994 return LBER_ERROR_MEMORY;
3997 sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02dZ",
3998 parts[1], parts[2] + 1, parts[3] + 1,
3999 parts[4], parts[5], parts[6] );
4003 return LDAP_SUCCESS;
4013 return check_time_syntax(in, 1, parts);
4017 generalizedTimeValidate(
4023 return check_time_syntax(in, 0, parts);
4027 generalizedTimeNormalize(
4030 struct berval **normalized )
4035 rc = check_time_syntax(val, 0, parts);
4036 if (rc != LDAP_SUCCESS) {
4041 out = ch_malloc( sizeof(struct berval) );
4043 return LBER_ERROR_MEMORY;
4046 out->bv_val = ch_malloc( 16 );
4047 if ( out->bv_val == NULL ) {
4049 return LBER_ERROR_MEMORY;
4052 sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4053 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4054 parts[4], parts[5], parts[6] );
4058 return LDAP_SUCCESS;
4062 nisNetgroupTripleValidate(
4064 struct berval *val )
4069 if ( val->bv_len == 0 ) {
4070 return LDAP_INVALID_SYNTAX;
4073 p = (char *)val->bv_val;
4074 e = p + val->bv_len;
4076 if ( *p != '(' /*')'*/ ) {
4077 return LDAP_INVALID_SYNTAX;
4080 for ( p++; ( p < e ) && ( *p != ')' ); p++ ) {
4084 return LDAP_INVALID_SYNTAX;
4087 } else if ( !ATTR_CHAR( *p ) ) {
4088 return LDAP_INVALID_SYNTAX;
4092 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4093 return LDAP_INVALID_SYNTAX;
4099 return LDAP_INVALID_SYNTAX;
4102 return LDAP_SUCCESS;
4106 bootParameterValidate(
4108 struct berval *val )
4112 if ( val->bv_len == 0 ) {
4113 return LDAP_INVALID_SYNTAX;
4116 p = (char *)val->bv_val;
4117 e = p + val->bv_len;
4120 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4121 if ( !ATTR_CHAR( *p ) ) {
4122 return LDAP_INVALID_SYNTAX;
4127 return LDAP_INVALID_SYNTAX;
4131 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4132 if ( !ATTR_CHAR( *p ) ) {
4133 return LDAP_INVALID_SYNTAX;
4138 return LDAP_INVALID_SYNTAX;
4142 for ( p++; p < e; p++ ) {
4143 if ( !ATTR_CHAR( *p ) ) {
4144 return LDAP_INVALID_SYNTAX;
4148 return LDAP_SUCCESS;
4151 static struct syntax_defs_rec {
4153 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4154 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4156 slap_syntax_validate_func *sd_validate;
4157 slap_syntax_transform_func *sd_normalize;
4158 slap_syntax_transform_func *sd_pretty;
4159 #ifdef SLAPD_BINARY_CONVERSION
4160 slap_syntax_transform_func *sd_ber2str;
4161 slap_syntax_transform_func *sd_str2ber;
4164 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
4165 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4166 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4167 0, NULL, NULL, NULL},
4168 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4169 0, NULL, NULL, NULL},
4170 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
4171 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4172 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_NOT_H_R ")",
4173 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4174 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4175 0, bitStringValidate, bitStringNormalize, NULL },
4176 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4177 0, booleanValidate, NULL, NULL},
4178 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4179 X_BINARY X_NOT_H_R ")",
4180 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4181 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4182 X_BINARY X_NOT_H_R ")",
4183 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4184 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4185 X_BINARY X_NOT_H_R ")",
4186 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4187 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4188 0, countryStringValidate, IA5StringNormalize, NULL},
4189 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4190 0, dnValidate, dnNormalize, dnPretty},
4191 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4192 0, NULL, NULL, NULL},
4193 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4194 0, NULL, NULL, NULL},
4195 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4196 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4197 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4198 0, NULL, NULL, NULL},
4199 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4200 0, NULL, NULL, NULL},
4201 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4202 0, NULL, NULL, NULL},
4203 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4204 0, NULL, NULL, NULL},
4205 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4206 0, NULL, NULL, NULL},
4207 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4208 0, printablesStringValidate, IA5StringNormalize, NULL},
4209 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4210 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4211 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4212 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4213 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4214 0, NULL, NULL, NULL},
4215 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4216 0, IA5StringValidate, IA5StringNormalize, NULL},
4217 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4218 0, integerValidate, integerNormalize, NULL},
4219 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4220 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4221 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4222 0, NULL, NULL, NULL},
4223 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4224 0, NULL, NULL, NULL},
4225 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4226 0, NULL, NULL, NULL},
4227 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4228 0, NULL, NULL, NULL},
4229 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4230 0, NULL, NULL, NULL},
4231 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4232 0, nameUIDValidate, nameUIDNormalize, NULL},
4233 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4234 0, NULL, NULL, NULL},
4235 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4236 0, numericStringValidate, numericStringNormalize, NULL},
4237 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4238 0, NULL, NULL, NULL},
4239 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4240 0, oidValidate, NULL, NULL},
4241 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4242 0, IA5StringValidate, IA5StringNormalize, NULL},
4243 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4244 0, blobValidate, NULL, NULL},
4245 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4246 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4247 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4248 0, NULL, NULL, NULL},
4249 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4250 0, NULL, NULL, NULL},
4251 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4252 0, printableStringValidate, IA5StringNormalize, NULL},
4253 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4254 X_BINARY X_NOT_H_R ")",
4255 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4256 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4257 0, printableStringValidate, IA5StringNormalize, NULL},
4258 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4259 0, NULL, NULL, NULL},
4260 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4261 0, printablesStringValidate, IA5StringNormalize, NULL},
4262 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4263 0, utcTimeValidate, utcTimeNormalize, NULL},
4264 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4265 0, NULL, NULL, NULL},
4266 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4267 0, NULL, NULL, NULL},
4268 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4269 0, NULL, NULL, NULL},
4270 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4271 0, NULL, NULL, NULL},
4272 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4273 0, NULL, NULL, NULL},
4275 /* RFC 2307 NIS Syntaxes */
4276 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4277 0, nisNetgroupTripleValidate, NULL, NULL},
4278 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4279 0, bootParameterValidate, NULL, NULL},
4283 /* These OIDs are not published yet, but will be in the next
4284 * I-D for PKIX LDAPv3 schema as have been advanced by David
4285 * Chadwick in private mail.
4287 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4288 0, NULL, NULL, NULL},
4291 /* OpenLDAP Experimental Syntaxes */
4292 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4294 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4297 /* needs updating */
4298 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4299 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4301 /* OpenLDAP Void Syntax */
4302 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4303 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4304 {NULL, 0, NULL, NULL, NULL}
4308 * Other matching rules in X.520 that we do not use (yet):
4310 * 2.5.13.9 numericStringOrderingMatch
4311 * 2.5.13.15 integerOrderingMatch
4312 * 2.5.13.18 octetStringOrderingMatch
4313 * 2.5.13.19 octetStringSubstringsMatch
4314 * 2.5.13.25 uTCTimeMatch
4315 * 2.5.13.26 uTCTimeOrderingMatch
4316 * 2.5.13.31 directoryStringFirstComponentMatch
4317 * 2.5.13.32 wordMatch
4318 * 2.5.13.33 keywordMatch
4319 * 2.5.13.35 certificateMatch
4320 * 2.5.13.36 certificatePairExactMatch
4321 * 2.5.13.37 certificatePairMatch
4322 * 2.5.13.38 certificateListExactMatch
4323 * 2.5.13.39 certificateListMatch
4324 * 2.5.13.40 algorithmIdentifierMatch
4325 * 2.5.13.41 storedPrefixMatch
4326 * 2.5.13.42 attributeCertificateMatch
4327 * 2.5.13.43 readerAndKeyIDMatch
4328 * 2.5.13.44 attributeIntegrityMatch
4330 static struct mrule_defs_rec {
4332 slap_mask_t mrd_usage;
4333 slap_mr_convert_func * mrd_convert;
4334 slap_mr_normalize_func * mrd_normalize;
4335 slap_mr_match_func * mrd_match;
4336 slap_mr_indexer_func * mrd_indexer;
4337 slap_mr_filter_func * mrd_filter;
4339 char * mrd_associated;
4342 * EQUALITY matching rules must be listed after associated APPROX
4343 * matching rules. So, we list all APPROX matching rules first.
4345 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4346 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4347 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4349 directoryStringApproxMatch,
4350 directoryStringApproxIndexer,
4351 directoryStringApproxFilter,
4354 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4355 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4356 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4358 IA5StringApproxMatch,
4359 IA5StringApproxIndexer,
4360 IA5StringApproxFilter,
4364 * Other matching rules
4367 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4368 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4369 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4371 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4374 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4375 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4376 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4378 dnMatch, dnIndexer, dnFilter,
4381 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4382 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4383 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4385 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4386 directoryStringApproxMatchOID },
4388 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4389 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4392 caseIgnoreOrderingMatch, NULL, NULL,
4395 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4396 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4397 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4399 caseExactIgnoreSubstringsMatch,
4400 caseExactIgnoreSubstringsIndexer,
4401 caseExactIgnoreSubstringsFilter,
4404 {"( 2.5.13.5 NAME 'caseExactMatch' "
4405 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4406 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4408 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4409 directoryStringApproxMatchOID },
4411 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4412 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4415 caseExactOrderingMatch, NULL, NULL,
4418 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4419 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4420 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4422 caseExactIgnoreSubstringsMatch,
4423 caseExactIgnoreSubstringsIndexer,
4424 caseExactIgnoreSubstringsFilter,
4427 {"( 2.5.13.8 NAME 'numericStringMatch' "
4428 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4429 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4432 caseIgnoreIA5Indexer,
4433 caseIgnoreIA5Filter,
4436 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4437 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4438 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4440 caseIgnoreIA5SubstringsMatch,
4441 caseIgnoreIA5SubstringsIndexer,
4442 caseIgnoreIA5SubstringsFilter,
4445 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4446 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4447 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4449 caseIgnoreListMatch, NULL, NULL,
4452 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4453 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4454 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4456 caseIgnoreListSubstringsMatch, NULL, NULL,
4459 {"( 2.5.13.13 NAME 'booleanMatch' "
4460 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4461 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4463 booleanMatch, NULL, NULL,
4466 {"( 2.5.13.14 NAME 'integerMatch' "
4467 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4468 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4470 integerMatch, integerIndexer, integerFilter,
4473 {"( 2.5.13.16 NAME 'bitStringMatch' "
4474 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4475 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4477 bitStringMatch, bitStringIndexer, bitStringFilter,
4480 {"( 2.5.13.17 NAME 'octetStringMatch' "
4481 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4482 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4484 octetStringMatch, octetStringIndexer, octetStringFilter,
4487 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4488 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4489 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4491 telephoneNumberMatch,
4492 telephoneNumberIndexer,
4493 telephoneNumberFilter,
4496 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4497 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4498 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4500 telephoneNumberSubstringsMatch,
4501 telephoneNumberSubstringsIndexer,
4502 telephoneNumberSubstringsFilter,
4505 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4506 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4507 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4512 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4513 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4514 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4516 uniqueMemberMatch, NULL, NULL,
4519 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4520 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4521 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4523 protocolInformationMatch, NULL, NULL,
4526 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4527 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4528 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4530 generalizedTimeMatch, NULL, NULL,
4533 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4534 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4537 generalizedTimeOrderingMatch, NULL, NULL,
4540 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4541 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4542 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4544 integerFirstComponentMatch, NULL, NULL,
4547 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4548 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4549 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4551 objectIdentifierFirstComponentMatch, NULL, NULL,
4555 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4556 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4557 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4558 certificateExactConvert, NULL,
4559 certificateExactMatch,
4560 certificateExactIndexer, certificateExactFilter,
4564 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4565 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4566 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4568 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4569 IA5StringApproxMatchOID },
4571 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4572 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4573 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4575 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4576 IA5StringApproxMatchOID },
4578 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4579 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4582 caseIgnoreIA5SubstringsMatch,
4583 caseIgnoreIA5SubstringsIndexer,
4584 caseIgnoreIA5SubstringsFilter,
4587 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4588 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4591 caseExactIA5SubstringsMatch,
4592 caseExactIA5SubstringsIndexer,
4593 caseExactIA5SubstringsFilter,
4596 /* needs updating */
4597 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4598 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4601 authPasswordMatch, NULL, NULL,
4604 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4605 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4608 OpenLDAPaciMatch, NULL, NULL,
4611 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4612 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4615 integerBitAndMatch, NULL, NULL,
4618 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4619 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4622 integerBitOrMatch, NULL, NULL,
4625 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
4634 /* we should only be called once (from main) */
4635 assert( schema_init_done == 0 );
4637 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4638 res = register_syntax( syntax_defs[i].sd_desc,
4639 syntax_defs[i].sd_flags,
4640 syntax_defs[i].sd_validate,
4641 syntax_defs[i].sd_normalize,
4642 syntax_defs[i].sd_pretty
4643 #ifdef SLAPD_BINARY_CONVERSION
4645 syntax_defs[i].sd_ber2str,
4646 syntax_defs[i].sd_str2ber
4651 fprintf( stderr, "schema_init: Error registering syntax %s\n",
4652 syntax_defs[i].sd_desc );
4657 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4658 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
4660 "schema_init: Ingoring unusable matching rule %s\n",
4661 mrule_defs[i].mrd_desc );
4665 res = register_matching_rule(
4666 mrule_defs[i].mrd_desc,
4667 mrule_defs[i].mrd_usage,
4668 mrule_defs[i].mrd_convert,
4669 mrule_defs[i].mrd_normalize,
4670 mrule_defs[i].mrd_match,
4671 mrule_defs[i].mrd_indexer,
4672 mrule_defs[i].mrd_filter,
4673 mrule_defs[i].mrd_associated );
4677 "schema_init: Error registering matching rule %s\n",
4678 mrule_defs[i].mrd_desc );
4682 schema_init_done = 1;
4683 return LDAP_SUCCESS;
4687 schema_destroy( void )