1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
15 #include <ac/string.h>
16 #include <ac/socket.h>
21 #include "ldap_utf8.h"
23 #include "lutil_hash.h"
24 /* We should replace MD5 with a faster hash */
25 #define HASH_BYTES LUTIL_HASH_BYTES
26 #define HASH_CONTEXT lutil_HASH_CTX
27 #define HASH_Init(c) lutil_HASHInit(c)
28 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
29 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
31 /* recycled validatation routines */
32 #define berValidate blobValidate
34 /* unimplemented pretters */
36 #define integerPretty NULL
38 /* recycled matching routines */
39 #define bitStringMatch octetStringMatch
40 #define integerMatch caseIgnoreIA5Match
41 #define numericStringMatch caseIgnoreIA5Match
42 #define objectIdentifierMatch caseIgnoreIA5Match
43 #define telephoneNumberMatch caseIgnoreIA5Match
44 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
45 #define generalizedTimeMatch caseIgnoreIA5Match
46 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
47 #define uniqueMemberMatch dnMatch
49 /* approx matching rules */
50 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
51 #define directoryStringApproxMatch approxMatch
52 #define directoryStringApproxIndexer approxIndexer
53 #define directoryStringApproxFilter approxFilter
54 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
55 #define IA5StringApproxMatch approxMatch
56 #define IA5StringApproxIndexer approxIndexer
57 #define IA5StringApproxFilter approxFilter
59 /* orderring matching rules */
60 #define caseIgnoreOrderingMatch caseIgnoreMatch
61 #define caseExactOrderingMatch caseExactMatch
63 /* unimplemented matching routines */
64 #define caseIgnoreListMatch NULL
65 #define caseIgnoreListSubstringsMatch NULL
66 #define protocolInformationMatch NULL
67 #define integerFirstComponentMatch NULL
69 #define OpenLDAPaciMatch NULL
70 #define authPasswordMatch NULL
72 /* recycled indexing/filtering routines */
73 #define dnIndexer caseExactIgnoreIndexer
74 #define dnFilter caseExactIgnoreFilter
75 #define integerIndexer caseIgnoreIA5Indexer
76 #define integerFilter caseIgnoreIA5Filter
78 #define telephoneNumberIndexer caseIgnoreIA5Indexer
79 #define telephoneNumberFilter caseIgnoreIA5Filter
80 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
81 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
83 /* must match OIDs below */
84 #define caseExactMatchOID "2.5.13.5"
85 #define caseExactSubstringsMatchOID "2.5.13.7"
87 static char *strcasechr( const char *str, int c )
89 char *lower = strchr( str, TOLOWER(c) );
90 char *upper = strchr( str, TOUPPER(c) );
92 if( lower && upper ) {
93 return lower < upper ? lower : upper;
107 struct berval *value,
108 void *assertedValue )
110 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
113 match = memcmp( value->bv_val,
114 ((struct berval *) assertedValue)->bv_val,
122 /* Index generation function */
123 int octetStringIndexer(
128 struct berval *prefix,
129 struct berval **values,
130 struct berval ***keysp )
134 struct berval **keys;
135 HASH_CONTEXT HASHcontext;
136 unsigned char HASHdigest[HASH_BYTES];
137 struct berval digest;
138 digest.bv_val = HASHdigest;
139 digest.bv_len = sizeof(HASHdigest);
141 for( i=0; values[i] != NULL; i++ ) {
142 /* just count them */
145 /* we should have at least one value at this point */
148 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
150 slen = strlen( syntax->ssyn_oid );
151 mlen = strlen( mr->smr_oid );
153 for( i=0; values[i] != NULL; i++ ) {
154 HASH_Init( &HASHcontext );
155 if( prefix != NULL && prefix->bv_len > 0 ) {
156 HASH_Update( &HASHcontext,
157 prefix->bv_val, prefix->bv_len );
159 HASH_Update( &HASHcontext,
160 syntax->ssyn_oid, slen );
161 HASH_Update( &HASHcontext,
163 HASH_Update( &HASHcontext,
164 values[i]->bv_val, values[i]->bv_len );
165 HASH_Final( HASHdigest, &HASHcontext );
167 keys[i] = ber_bvdup( &digest );
177 /* Index generation function */
178 int octetStringFilter(
183 struct berval *prefix,
185 struct berval ***keysp )
188 struct berval **keys;
189 HASH_CONTEXT HASHcontext;
190 unsigned char HASHdigest[HASH_BYTES];
191 struct berval *value = (struct berval *) assertValue;
192 struct berval digest;
193 digest.bv_val = HASHdigest;
194 digest.bv_len = sizeof(HASHdigest);
196 slen = strlen( syntax->ssyn_oid );
197 mlen = strlen( mr->smr_oid );
199 keys = ch_malloc( sizeof( struct berval * ) * 2 );
201 HASH_Init( &HASHcontext );
202 if( prefix != NULL && prefix->bv_len > 0 ) {
203 HASH_Update( &HASHcontext,
204 prefix->bv_val, prefix->bv_len );
206 HASH_Update( &HASHcontext,
207 syntax->ssyn_oid, slen );
208 HASH_Update( &HASHcontext,
210 HASH_Update( &HASHcontext,
211 value->bv_val, value->bv_len );
212 HASH_Final( HASHdigest, &HASHcontext );
214 keys[0] = ber_bvdup( &digest );
230 if( in->bv_len == 0 ) return LDAP_SUCCESS;
232 dn = ch_strdup( in->bv_val );
235 return LDAP_INVALID_SYNTAX;
237 } else if ( strlen( in->bv_val ) != in->bv_len ) {
238 rc = LDAP_INVALID_SYNTAX;
240 } else if ( dn_validate( dn ) == NULL ) {
241 rc = LDAP_INVALID_SYNTAX;
255 struct berval **normalized )
259 if ( val->bv_len != 0 ) {
261 out = ber_bvstr( UTF8normalize( val->bv_val, UTF8_CASEFOLD ) );
263 dn = dn_validate( out->bv_val );
267 return LDAP_INVALID_SYNTAX;
271 out->bv_len = strlen( dn );
273 out = ber_bvdup( val );
286 struct berval *value,
287 void *assertedValue )
290 struct berval *asserted = (struct berval *) assertedValue;
292 match = value->bv_len - asserted->bv_len;
295 #ifdef USE_DN_NORMALIZE
296 match = strcmp( value->bv_val, asserted->bv_val );
298 match = strcasecmp( value->bv_val, asserted->bv_val );
303 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
304 "dnMatch: %d\n %s\n %s\n", match,
305 value->bv_val, asserted->bv_val ));
307 Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
308 match, value->bv_val, asserted->bv_val );
324 if( in->bv_len == 0 ) return LDAP_SUCCESS;
326 dn = ber_bvdup( in );
328 if( dn->bv_val[dn->bv_len-1] == '\'' ) {
329 /* assume presence of optional UID */
332 for(i=dn->bv_len-2; i>2; i--) {
333 if( dn->bv_val[i] != '0' && dn->bv_val[i] != '1' ) {
337 if( dn->bv_val[i] != '\'' ) {
338 return LDAP_INVALID_SYNTAX;
340 if( dn->bv_val[i-1] != 'B' ) {
341 return LDAP_INVALID_SYNTAX;
343 if( dn->bv_val[i-2] != '#' ) {
344 return LDAP_INVALID_SYNTAX;
347 /* trim the UID to allow use of dn_validate */
348 dn->bv_val[i-2] = '\0';
351 rc = dn_validate( dn->bv_val ) == NULL
352 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
362 struct berval **normalized )
364 struct berval *out = ber_bvdup( val );
366 if( out->bv_len != 0 ) {
370 ber_len_t uidlen = 0;
372 if( out->bv_val[out->bv_len-1] == '\'' ) {
373 /* assume presence of optional UID */
374 uid = strrchr( out->bv_val, '#' );
378 return LDAP_INVALID_SYNTAX;
381 uidlen = out->bv_len - (out->bv_val - uid);
382 /* temporarily trim the UID */
386 #ifdef USE_DN_NORMALIZE
387 dn = dn_normalize( out->bv_val );
389 dn = dn_validate( out->bv_val );
394 return LDAP_INVALID_SYNTAX;
400 /* restore the separator */
403 SAFEMEMCPY( &dn[dnlen], uid, uidlen );
407 out->bv_len = dnlen + uidlen;
419 /* any value allowed */
428 /* any value allowed */
439 /* very unforgiving validation, requires no normalization
440 * before simplistic matching
442 if( in->bv_len < 3 ) {
443 return LDAP_INVALID_SYNTAX;
446 if( in->bv_val[0] != 'B' ||
447 in->bv_val[1] != '\'' ||
448 in->bv_val[in->bv_len-1] != '\'' )
450 return LDAP_INVALID_SYNTAX;
453 for( i=in->bv_len-2; i>1; i-- ) {
454 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
455 return LDAP_INVALID_SYNTAX;
463 * Handling boolean syntax and matching is quite rigid.
464 * A more flexible approach would be to allow a variety
465 * of strings to be normalized and prettied into TRUE
473 /* very unforgiving validation, requires no normalization
474 * before simplistic matching
477 if( in->bv_len == 4 ) {
478 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
481 } else if( in->bv_len == 5 ) {
482 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
487 return LDAP_INVALID_SYNTAX;
496 struct berval *value,
497 void *assertedValue )
499 /* simplistic matching allowed by rigid validation */
500 struct berval *asserted = (struct berval *) assertedValue;
501 *matchp = value->bv_len != asserted->bv_len;
512 unsigned char *u = in->bv_val;
514 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
516 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
517 /* get the length indicated by the first byte */
518 len = LDAP_UTF8_CHARLEN( u );
520 /* should not be zero */
521 if( len == 0 ) return LDAP_INVALID_SYNTAX;
523 /* make sure len corresponds with the offset
524 to the next character */
525 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
528 if( count != 0 ) return LDAP_INVALID_SYNTAX;
537 struct berval **normalized )
539 struct berval *newval;
542 newval = ch_malloc( sizeof( struct berval ) );
546 /* Ignore initial whitespace */
547 while ( ldap_utf8_isspace( p ) ) {
553 return LDAP_INVALID_SYNTAX;
556 newval->bv_val = ch_strdup( p );
557 p = q = newval->bv_val;
563 if ( ldap_utf8_isspace( p ) ) {
564 len = LDAP_UTF8_COPY(q,p);
569 /* Ignore the extra whitespace */
570 while ( ldap_utf8_isspace( p ) ) {
574 len = LDAP_UTF8_COPY(q,p);
581 assert( *newval->bv_val );
582 assert( newval->bv_val < p );
585 /* cannot start with a space */
586 assert( !ldap_utf8_isspace(newval->bv_val) );
589 * If the string ended in space, backup the pointer one
590 * position. One is enough because the above loop collapsed
591 * all whitespace to a single space.
598 /* cannot end with a space */
599 assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
604 newval->bv_len = q - newval->bv_val;
605 *normalized = newval;
610 /* Returns Unicode cannonically normalized copy of a substring assertion
611 * Skipping attribute description */
612 SubstringsAssertion *
613 UTF8SubstringsassertionNormalize(
614 SubstringsAssertion *sa,
617 SubstringsAssertion *nsa;
620 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
625 if( sa->sa_initial != NULL ) {
626 nsa->sa_initial = ber_bvstr( UTF8normalize( sa->sa_initial->bv_val, casefold ) );
627 if( nsa->sa_initial == NULL ) {
632 if( sa->sa_any != NULL ) {
633 for( i=0; sa->sa_any[i] != NULL; i++ ) {
636 nsa->sa_any = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
637 for( i=0; sa->sa_any[i] != NULL; i++ ) {
638 nsa->sa_any[i] = ber_bvstr( UTF8normalize( sa->sa_any[i]->bv_val, casefold ) );
639 if( nsa->sa_any[i] == NULL ) {
643 nsa->sa_any[i] = NULL;
646 if( sa->sa_final != NULL ) {
647 nsa->sa_final = ber_bvstr( UTF8normalize( sa->sa_final->bv_val, casefold ) );
648 if( nsa->sa_final == NULL ) {
656 ch_free( nsa->sa_final );
657 ber_bvecfree( nsa->sa_any );
658 ch_free( nsa->sa_initial );
663 /* Strip characters with the 8th bit set */
676 while( *++q & 0x80 ) {
679 p = memmove(p, q, strlen(q) + 1);
687 #ifndef SLAPD_APPROX_OLDSINGLESTRING
689 #if defined(SLAPD_APPROX_INITIALS)
690 #define SLAPD_APPROX_DELIMITER "._ "
691 #define SLAPD_APPROX_WORDLEN 2
693 #define SLAPD_APPROX_DELIMITER " "
694 #define SLAPD_APPROX_WORDLEN 1
703 struct berval *value,
704 void *assertedValue )
706 char *val, *assertv, **values, **words, *c;
707 int i, count, len, nextchunk=0, nextavail=0;
710 /* Yes, this is necessary */
711 val = UTF8normalize( value->bv_val, UTF8_NOCASEFOLD );
716 strip8bitChars( val );
718 /* Yes, this is necessary */
719 assertv = UTF8normalize( ((struct berval *)assertedValue)->bv_val,
721 if( assertv == NULL ) {
726 strip8bitChars( assertv );
727 avlen = strlen( assertv );
729 /* Isolate how many words there are */
730 for( c=val,count=1; *c; c++ ) {
731 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
732 if ( c == NULL ) break;
737 /* Get a phonetic copy of each word */
738 words = (char **)ch_malloc( count * sizeof(char *) );
739 values = (char **)ch_malloc( count * sizeof(char *) );
740 for( c=val,i=0; i<count; i++,c+=strlen(c)+1 ) {
742 values[i] = phonetic(c);
745 /* Work through the asserted value's words, to see if at least some
746 of the words are there, in the same order. */
748 while ( nextchunk < avlen ) {
749 len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER);
754 #if defined(SLAPD_APPROX_INITIALS)
755 else if( len == 1 ) {
756 /* Single letter words need to at least match one word's initial */
757 for( i=nextavail; i<count; i++ )
758 if( !strncasecmp( assertv+nextchunk, words[i], 1 )) {
765 /* Isolate the next word in the asserted value and phonetic it */
766 assertv[nextchunk+len] = '\0';
767 val = phonetic( assertv + nextchunk );
769 /* See if this phonetic chunk is in the remaining words of *value */
770 for( i=nextavail; i<count; i++ ){
771 if( !strcmp( val, values[i] ) ){
778 /* This chunk in the asserted value was NOT within the *value. */
784 /* Go on to the next word in the asserted value */
788 /* If some of the words were seen, call it a match */
789 if( nextavail > 0 ) {
798 for( i=0; i<count; i++ ) {
799 ch_free( values[i] );
814 struct berval *prefix,
815 struct berval **values,
816 struct berval ***keysp )
819 int i,j, len, wordcount, keycount=0;
820 struct berval **newkeys, **keys=NULL;
822 for( j=0; values[j] != NULL; j++ ) {
823 /* Yes, this is necessary */
824 val = UTF8normalize( values[j]->bv_val, UTF8_NOCASEFOLD );
825 strip8bitChars( val );
827 /* Isolate how many words there are. There will be a key for each */
828 for( wordcount=0,c=val; *c; c++) {
829 len = strcspn(c, SLAPD_APPROX_DELIMITER);
830 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
832 if (*c == '\0') break;
836 /* Allocate/increase storage to account for new keys */
837 newkeys = (struct berval **)ch_malloc( (keycount + wordcount + 1)
838 * sizeof(struct berval *) );
839 memcpy( newkeys, keys, keycount * sizeof(struct berval *) );
840 if( keys ) ch_free( keys );
843 /* Get a phonetic copy of each word */
844 for( c=val,i=0; i<wordcount; c+=len+1 ) {
846 if( len < SLAPD_APPROX_WORDLEN ) continue;
847 keys[keycount] = (struct berval *)ch_malloc( sizeof(struct berval) );
848 keys[keycount]->bv_val = phonetic( c );
849 keys[keycount]->bv_len = strlen( keys[keycount]->bv_val );
856 keys[keycount] = NULL;
868 struct berval *prefix,
870 struct berval ***keysp )
874 struct berval **keys;
876 /* Yes, this is necessary */
877 val = UTF8normalize( ((struct berval *)assertValue)->bv_val,
880 keys = (struct berval **)ch_malloc( sizeof(struct berval *) );
885 strip8bitChars( val );
887 /* Isolate how many words there are. There will be a key for each */
888 for( count=0,c=val; *c; c++) {
889 len = strcspn(c, SLAPD_APPROX_DELIMITER);
890 if( len >= SLAPD_APPROX_WORDLEN ) count++;
892 if (*c == '\0') break;
896 /* Allocate storage for new keys */
897 keys = (struct berval **)ch_malloc( (count + 1) * sizeof(struct berval *) );
899 /* Get a phonetic copy of each word */
900 for( c=val,i=0; i<count; c+=len+1 ) {
902 if( len < SLAPD_APPROX_WORDLEN ) continue;
903 keys[i] = ber_bvstr( phonetic( c ) );
917 /* No other form of Approximate Matching is defined */
925 struct berval *value,
926 void *assertedValue )
928 char *vapprox, *avapprox;
931 /* Yes, this is necessary */
932 s = UTF8normalize( value->bv_val, UTF8_NOCASEFOLD );
938 /* Yes, this is necessary */
939 t = UTF8normalize( ((struct berval *)assertedValue)->bv_val,
947 vapprox = phonetic( strip8bitChars( s ) );
948 avapprox = phonetic( strip8bitChars( t ) );
953 *matchp = strcmp( vapprox, avapprox );
967 struct berval *prefix,
968 struct berval **values,
969 struct berval ***keysp )
972 struct berval **keys;
975 for( i=0; values[i] != NULL; i++ ) {
976 /* empty - just count them */
979 /* we should have at least one value at this point */
982 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * (i+1) );
984 /* Copy each value and run it through phonetic() */
985 for( i=0; values[i] != NULL; i++ ) {
986 /* Yes, this is necessary */
987 s = UTF8normalize( values[i]->bv_val, UTF8_NOCASEFOLD );
989 /* strip 8-bit chars and run through phonetic() */
990 keys[i] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1006 struct berval *prefix,
1008 struct berval ***keysp )
1010 struct berval **keys;
1013 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * 2 );
1015 /* Yes, this is necessary */
1016 s = UTF8normalize( ((struct berval *)assertValue)->bv_val,
1021 /* strip 8-bit chars and run through phonetic() */
1022 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1028 return LDAP_SUCCESS;
1039 struct berval *value,
1040 void *assertedValue )
1042 *matchp = UTF8normcmp( value->bv_val,
1043 ((struct berval *) assertedValue)->bv_val,
1045 return LDAP_SUCCESS;
1049 caseExactIgnoreSubstringsMatch(
1054 struct berval *value,
1055 void *assertedValue )
1058 SubstringsAssertion *sub;
1062 char *nav, casefold;
1064 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1065 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1067 nav = UTF8normalize( value->bv_val, casefold );
1073 left.bv_len = strlen( nav );
1075 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1081 /* Add up asserted input length */
1082 if( sub->sa_initial ) {
1083 inlen += sub->sa_initial->bv_len;
1086 for(i=0; sub->sa_any[i] != NULL; i++) {
1087 inlen += sub->sa_any[i]->bv_len;
1090 if( sub->sa_final ) {
1091 inlen += sub->sa_final->bv_len;
1094 if( sub->sa_initial ) {
1095 if( inlen > left.bv_len ) {
1100 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
1101 sub->sa_initial->bv_len );
1107 left.bv_val += sub->sa_initial->bv_len;
1108 left.bv_len -= sub->sa_initial->bv_len;
1109 inlen -= sub->sa_initial->bv_len;
1112 if( sub->sa_final ) {
1113 if( inlen > left.bv_len ) {
1118 match = strncmp( sub->sa_final->bv_val,
1119 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
1120 sub->sa_final->bv_len );
1126 left.bv_len -= sub->sa_final->bv_len;
1127 inlen -= sub->sa_final->bv_len;
1131 for(i=0; sub->sa_any[i]; i++) {
1136 if( inlen > left.bv_len ) {
1137 /* not enough length */
1142 if( sub->sa_any[i]->bv_len == 0 ) {
1146 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
1153 idx = p - left.bv_val;
1154 assert( idx < left.bv_len );
1156 if( idx >= left.bv_len ) {
1157 /* this shouldn't happen */
1164 if( sub->sa_any[i]->bv_len > left.bv_len ) {
1165 /* not enough left */
1170 match = strncmp( left.bv_val,
1171 sub->sa_any[i]->bv_val,
1172 sub->sa_any[i]->bv_len );
1180 left.bv_val += sub->sa_any[i]->bv_len;
1181 left.bv_len -= sub->sa_any[i]->bv_len;
1182 inlen -= sub->sa_any[i]->bv_len;
1189 ch_free( sub->sa_final );
1190 ber_bvecfree( sub->sa_any );
1191 ch_free( sub->sa_initial );
1195 return LDAP_SUCCESS;
1198 /* Index generation function */
1199 int caseExactIgnoreIndexer(
1204 struct berval *prefix,
1205 struct berval **values,
1206 struct berval ***keysp )
1211 struct berval **keys;
1212 HASH_CONTEXT HASHcontext;
1213 unsigned char HASHdigest[HASH_BYTES];
1214 struct berval digest;
1215 digest.bv_val = HASHdigest;
1216 digest.bv_len = sizeof(HASHdigest);
1218 for( i=0; values[i] != NULL; i++ ) {
1219 /* empty - just count them */
1222 /* we should have at least one value at this point */
1225 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
1227 slen = strlen( syntax->ssyn_oid );
1228 mlen = strlen( mr->smr_oid );
1230 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1231 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1233 for( i=0; values[i] != NULL; i++ ) {
1234 struct berval *value;
1235 value = ber_bvstr( UTF8normalize( values[i]->bv_val,
1238 HASH_Init( &HASHcontext );
1239 if( prefix != NULL && prefix->bv_len > 0 ) {
1240 HASH_Update( &HASHcontext,
1241 prefix->bv_val, prefix->bv_len );
1243 HASH_Update( &HASHcontext,
1244 syntax->ssyn_oid, slen );
1245 HASH_Update( &HASHcontext,
1246 mr->smr_oid, mlen );
1247 HASH_Update( &HASHcontext,
1248 value->bv_val, value->bv_len );
1249 HASH_Final( HASHdigest, &HASHcontext );
1251 ber_bvfree( value );
1253 keys[i] = ber_bvdup( &digest );
1258 return LDAP_SUCCESS;
1261 /* Index generation function */
1262 int caseExactIgnoreFilter(
1267 struct berval *prefix,
1269 struct berval ***keysp )
1273 struct berval **keys;
1274 HASH_CONTEXT HASHcontext;
1275 unsigned char HASHdigest[HASH_BYTES];
1276 struct berval *value;
1277 struct berval digest;
1278 digest.bv_val = HASHdigest;
1279 digest.bv_len = sizeof(HASHdigest);
1281 slen = strlen( syntax->ssyn_oid );
1282 mlen = strlen( mr->smr_oid );
1284 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1285 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1287 value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue)->bv_val,
1289 /* This usually happens if filter contains bad UTF8 */
1290 if( value == NULL ) {
1291 keys = ch_malloc( sizeof( struct berval * ) );
1293 return LDAP_SUCCESS;
1296 keys = ch_malloc( sizeof( struct berval * ) * 2 );
1298 HASH_Init( &HASHcontext );
1299 if( prefix != NULL && prefix->bv_len > 0 ) {
1300 HASH_Update( &HASHcontext,
1301 prefix->bv_val, prefix->bv_len );
1303 HASH_Update( &HASHcontext,
1304 syntax->ssyn_oid, slen );
1305 HASH_Update( &HASHcontext,
1306 mr->smr_oid, mlen );
1307 HASH_Update( &HASHcontext,
1308 value->bv_val, value->bv_len );
1309 HASH_Final( HASHdigest, &HASHcontext );
1311 keys[0] = ber_bvdup( &digest );
1314 ber_bvfree( value );
1317 return LDAP_SUCCESS;
1320 /* Substrings Index generation function */
1321 int caseExactIgnoreSubstringsIndexer(
1326 struct berval *prefix,
1327 struct berval **values,
1328 struct berval ***keysp )
1333 struct berval **keys;
1334 struct berval **nvalues;
1336 HASH_CONTEXT HASHcontext;
1337 unsigned char HASHdigest[HASH_BYTES];
1338 struct berval digest;
1339 digest.bv_val = HASHdigest;
1340 digest.bv_len = sizeof(HASHdigest);
1344 for( i=0; values[i] != NULL; i++ ) {
1345 /* empty - just count them */
1348 /* we should have at least one value at this point */
1351 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1352 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1354 nvalues = ch_malloc( sizeof( struct berval * ) * (i+1) );
1355 for( i=0; values[i] != NULL; i++ ) {
1356 nvalues[i] = ber_bvstr( UTF8normalize( values[i]->bv_val,
1362 for( i=0; values[i] != NULL; i++ ) {
1363 /* count number of indices to generate */
1364 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1368 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1369 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1370 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1371 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1373 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1377 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1378 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1379 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1383 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1384 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1385 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1386 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1388 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1394 /* no keys to generate */
1396 return LDAP_SUCCESS;
1399 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1401 slen = strlen( syntax->ssyn_oid );
1402 mlen = strlen( mr->smr_oid );
1405 for( i=0; values[i] != NULL; i++ ) {
1407 struct berval *value;
1409 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1413 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1414 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1416 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1417 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1419 for( j=0; j<max; j++ ) {
1420 HASH_Init( &HASHcontext );
1421 if( prefix != NULL && prefix->bv_len > 0 ) {
1422 HASH_Update( &HASHcontext,
1423 prefix->bv_val, prefix->bv_len );
1426 HASH_Update( &HASHcontext,
1427 &pre, sizeof( pre ) );
1428 HASH_Update( &HASHcontext,
1429 syntax->ssyn_oid, slen );
1430 HASH_Update( &HASHcontext,
1431 mr->smr_oid, mlen );
1432 HASH_Update( &HASHcontext,
1434 SLAP_INDEX_SUBSTR_MAXLEN );
1435 HASH_Final( HASHdigest, &HASHcontext );
1437 keys[nkeys++] = ber_bvdup( &digest );
1441 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1442 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1444 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1447 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1448 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1449 HASH_Init( &HASHcontext );
1450 if( prefix != NULL && prefix->bv_len > 0 ) {
1451 HASH_Update( &HASHcontext,
1452 prefix->bv_val, prefix->bv_len );
1454 HASH_Update( &HASHcontext,
1455 &pre, sizeof( pre ) );
1456 HASH_Update( &HASHcontext,
1457 syntax->ssyn_oid, slen );
1458 HASH_Update( &HASHcontext,
1459 mr->smr_oid, mlen );
1460 HASH_Update( &HASHcontext,
1462 HASH_Final( HASHdigest, &HASHcontext );
1464 keys[nkeys++] = ber_bvdup( &digest );
1467 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1468 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1469 HASH_Init( &HASHcontext );
1470 if( prefix != NULL && prefix->bv_len > 0 ) {
1471 HASH_Update( &HASHcontext,
1472 prefix->bv_val, prefix->bv_len );
1474 HASH_Update( &HASHcontext,
1475 &pre, sizeof( pre ) );
1476 HASH_Update( &HASHcontext,
1477 syntax->ssyn_oid, slen );
1478 HASH_Update( &HASHcontext,
1479 mr->smr_oid, mlen );
1480 HASH_Update( &HASHcontext,
1481 &value->bv_val[value->bv_len-j], j );
1482 HASH_Final( HASHdigest, &HASHcontext );
1484 keys[nkeys++] = ber_bvdup( &digest );
1499 ber_bvecfree( nvalues );
1501 return LDAP_SUCCESS;
1504 int caseExactIgnoreSubstringsFilter(
1509 struct berval *prefix,
1511 struct berval ***keysp )
1513 SubstringsAssertion *sa;
1515 ber_len_t nkeys = 0;
1516 size_t slen, mlen, klen;
1517 struct berval **keys;
1518 HASH_CONTEXT HASHcontext;
1519 unsigned char HASHdigest[HASH_BYTES];
1520 struct berval *value;
1521 struct berval digest;
1523 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1524 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1526 sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
1529 return LDAP_SUCCESS;
1532 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1533 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1538 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1540 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1541 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1542 /* don't bother accounting for stepping */
1543 nkeys += sa->sa_any[i]->bv_len -
1544 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1549 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1550 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1557 return LDAP_SUCCESS;
1560 digest.bv_val = HASHdigest;
1561 digest.bv_len = sizeof(HASHdigest);
1563 slen = strlen( syntax->ssyn_oid );
1564 mlen = strlen( mr->smr_oid );
1566 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1569 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1570 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1572 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1573 value = sa->sa_initial;
1575 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1576 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1578 HASH_Init( &HASHcontext );
1579 if( prefix != NULL && prefix->bv_len > 0 ) {
1580 HASH_Update( &HASHcontext,
1581 prefix->bv_val, prefix->bv_len );
1583 HASH_Update( &HASHcontext,
1584 &pre, sizeof( pre ) );
1585 HASH_Update( &HASHcontext,
1586 syntax->ssyn_oid, slen );
1587 HASH_Update( &HASHcontext,
1588 mr->smr_oid, mlen );
1589 HASH_Update( &HASHcontext,
1590 value->bv_val, klen );
1591 HASH_Final( HASHdigest, &HASHcontext );
1593 keys[nkeys++] = ber_bvdup( &digest );
1596 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1598 pre = SLAP_INDEX_SUBSTR_PREFIX;
1599 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1601 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1602 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1606 value = sa->sa_any[i];
1609 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1610 j += SLAP_INDEX_SUBSTR_STEP )
1612 HASH_Init( &HASHcontext );
1613 if( prefix != NULL && prefix->bv_len > 0 ) {
1614 HASH_Update( &HASHcontext,
1615 prefix->bv_val, prefix->bv_len );
1617 HASH_Update( &HASHcontext,
1618 &pre, sizeof( pre ) );
1619 HASH_Update( &HASHcontext,
1620 syntax->ssyn_oid, slen );
1621 HASH_Update( &HASHcontext,
1622 mr->smr_oid, mlen );
1623 HASH_Update( &HASHcontext,
1624 &value->bv_val[j], klen );
1625 HASH_Final( HASHdigest, &HASHcontext );
1627 keys[nkeys++] = ber_bvdup( &digest );
1633 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1634 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1636 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1637 value = sa->sa_final;
1639 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1640 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1642 HASH_Init( &HASHcontext );
1643 if( prefix != NULL && prefix->bv_len > 0 ) {
1644 HASH_Update( &HASHcontext,
1645 prefix->bv_val, prefix->bv_len );
1647 HASH_Update( &HASHcontext,
1648 &pre, sizeof( pre ) );
1649 HASH_Update( &HASHcontext,
1650 syntax->ssyn_oid, slen );
1651 HASH_Update( &HASHcontext,
1652 mr->smr_oid, mlen );
1653 HASH_Update( &HASHcontext,
1654 &value->bv_val[value->bv_len-klen], klen );
1655 HASH_Final( HASHdigest, &HASHcontext );
1657 keys[nkeys++] = ber_bvdup( &digest );
1667 ch_free( sa->sa_final );
1668 ber_bvecfree( sa->sa_any );
1669 ch_free( sa->sa_initial );
1672 return LDAP_SUCCESS;
1681 struct berval *value,
1682 void *assertedValue )
1684 *matchp = UTF8normcmp( value->bv_val,
1685 ((struct berval *) assertedValue)->bv_val,
1687 return LDAP_SUCCESS;
1693 struct berval *val )
1697 if( val->bv_len == 0 ) {
1698 /* disallow empty strings */
1699 return LDAP_INVALID_SYNTAX;
1702 if( OID_LEADCHAR(val->bv_val[0]) ) {
1704 for(i=1; i < val->bv_len; i++) {
1705 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1706 if( dot++ ) return 1;
1707 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1710 return LDAP_INVALID_SYNTAX;
1714 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1716 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1717 for(i=1; i < val->bv_len; i++) {
1718 if( !DESC_CHAR(val->bv_val[i] ) ) {
1719 return LDAP_INVALID_SYNTAX;
1723 return LDAP_SUCCESS;
1726 return LDAP_INVALID_SYNTAX;
1732 struct berval *val )
1736 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1738 if( val->bv_val[0] == '+' || val->bv_val[0] == '-' ) {
1739 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1740 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1741 return LDAP_INVALID_SYNTAX;
1744 for(i=1; i < val->bv_len; i++) {
1745 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1748 return LDAP_SUCCESS;
1755 struct berval **normalized )
1758 struct berval *newval;
1764 negative = ( *p == '-' );
1765 if( *p == '-' || *p == '+' ) p++;
1767 /* Ignore leading zeros */
1768 while ( *p == '0' ) p++;
1770 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
1773 newval->bv_val = ch_strdup("0");
1778 newval->bv_val = ch_malloc( val->bv_len + 1 );
1782 newval->bv_val[newval->bv_len++] = '-';
1785 for( ; *p != '\0'; p++ ) {
1786 newval->bv_val[newval->bv_len++] = *p;
1790 *normalized = newval;
1791 return LDAP_SUCCESS;
1795 countryStringValidate(
1797 struct berval *val )
1799 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
1801 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
1802 return LDAP_INVALID_SYNTAX;
1804 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
1805 return LDAP_INVALID_SYNTAX;
1808 return LDAP_SUCCESS;
1812 printableStringValidate(
1814 struct berval *val )
1818 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1820 for(i=0; i < val->bv_len; i++) {
1821 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
1822 return LDAP_INVALID_SYNTAX;
1826 return LDAP_SUCCESS;
1830 printablesStringValidate(
1832 struct berval *val )
1836 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1838 for(i=0; i < val->bv_len; i++) {
1839 if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
1840 return LDAP_INVALID_SYNTAX;
1844 return LDAP_SUCCESS;
1850 struct berval *val )
1854 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1856 for(i=0; i < val->bv_len; i++) {
1857 if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1860 return LDAP_SUCCESS;
1867 struct berval **normalized )
1869 struct berval *newval;
1872 newval = ch_malloc( sizeof( struct berval ) );
1876 /* Ignore initial whitespace */
1877 while ( ASCII_SPACE( *p ) ) {
1883 return LDAP_INVALID_SYNTAX;
1886 newval->bv_val = ch_strdup( p );
1887 p = q = newval->bv_val;
1890 if ( ASCII_SPACE( *p ) ) {
1893 /* Ignore the extra whitespace */
1894 while ( ASCII_SPACE( *p ) ) {
1902 assert( *newval->bv_val );
1903 assert( newval->bv_val < p );
1906 /* cannot start with a space */
1907 assert( !ASCII_SPACE(*newval->bv_val) );
1910 * If the string ended in space, backup the pointer one
1911 * position. One is enough because the above loop collapsed
1912 * all whitespace to a single space.
1915 if ( ASCII_SPACE( q[-1] ) ) {
1919 /* cannot end with a space */
1920 assert( !ASCII_SPACE( q[-1] ) );
1922 /* null terminate */
1925 newval->bv_len = q - newval->bv_val;
1926 *normalized = newval;
1928 return LDAP_SUCCESS;
1937 struct berval *value,
1938 void *assertedValue )
1940 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
1943 match = strncmp( value->bv_val,
1944 ((struct berval *) assertedValue)->bv_val,
1949 return LDAP_SUCCESS;
1953 caseExactIA5SubstringsMatch(
1958 struct berval *value,
1959 void *assertedValue )
1962 SubstringsAssertion *sub = assertedValue;
1963 struct berval left = *value;
1967 /* Add up asserted input length */
1968 if( sub->sa_initial ) {
1969 inlen += sub->sa_initial->bv_len;
1972 for(i=0; sub->sa_any[i] != NULL; i++) {
1973 inlen += sub->sa_any[i]->bv_len;
1976 if( sub->sa_final ) {
1977 inlen += sub->sa_final->bv_len;
1980 if( sub->sa_initial ) {
1981 if( inlen > left.bv_len ) {
1986 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
1987 sub->sa_initial->bv_len );
1993 left.bv_val += sub->sa_initial->bv_len;
1994 left.bv_len -= sub->sa_initial->bv_len;
1995 inlen -= sub->sa_initial->bv_len;
1998 if( sub->sa_final ) {
1999 if( inlen > left.bv_len ) {
2004 match = strncmp( sub->sa_final->bv_val,
2005 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2006 sub->sa_final->bv_len );
2012 left.bv_len -= sub->sa_final->bv_len;
2013 inlen -= sub->sa_final->bv_len;
2017 for(i=0; sub->sa_any[i]; i++) {
2022 if( inlen > left.bv_len ) {
2023 /* not enough length */
2028 if( sub->sa_any[i]->bv_len == 0 ) {
2032 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
2039 idx = p - left.bv_val;
2040 assert( idx < left.bv_len );
2042 if( idx >= left.bv_len ) {
2043 /* this shouldn't happen */
2050 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2051 /* not enough left */
2056 match = strncmp( left.bv_val,
2057 sub->sa_any[i]->bv_val,
2058 sub->sa_any[i]->bv_len );
2066 left.bv_val += sub->sa_any[i]->bv_len;
2067 left.bv_len -= sub->sa_any[i]->bv_len;
2068 inlen -= sub->sa_any[i]->bv_len;
2074 return LDAP_SUCCESS;
2077 /* Index generation function */
2078 int caseExactIA5Indexer(
2083 struct berval *prefix,
2084 struct berval **values,
2085 struct berval ***keysp )
2089 struct berval **keys;
2090 HASH_CONTEXT HASHcontext;
2091 unsigned char HASHdigest[HASH_BYTES];
2092 struct berval digest;
2093 digest.bv_val = HASHdigest;
2094 digest.bv_len = sizeof(HASHdigest);
2096 for( i=0; values[i] != NULL; i++ ) {
2097 /* empty - just count them */
2100 /* we should have at least one value at this point */
2103 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2105 slen = strlen( syntax->ssyn_oid );
2106 mlen = strlen( mr->smr_oid );
2108 for( i=0; values[i] != NULL; i++ ) {
2109 struct berval *value = values[i];
2111 HASH_Init( &HASHcontext );
2112 if( prefix != NULL && prefix->bv_len > 0 ) {
2113 HASH_Update( &HASHcontext,
2114 prefix->bv_val, prefix->bv_len );
2116 HASH_Update( &HASHcontext,
2117 syntax->ssyn_oid, slen );
2118 HASH_Update( &HASHcontext,
2119 mr->smr_oid, mlen );
2120 HASH_Update( &HASHcontext,
2121 value->bv_val, value->bv_len );
2122 HASH_Final( HASHdigest, &HASHcontext );
2124 keys[i] = ber_bvdup( &digest );
2129 return LDAP_SUCCESS;
2132 /* Index generation function */
2133 int caseExactIA5Filter(
2138 struct berval *prefix,
2140 struct berval ***keysp )
2143 struct berval **keys;
2144 HASH_CONTEXT HASHcontext;
2145 unsigned char HASHdigest[HASH_BYTES];
2146 struct berval *value;
2147 struct berval digest;
2148 digest.bv_val = HASHdigest;
2149 digest.bv_len = sizeof(HASHdigest);
2151 slen = strlen( syntax->ssyn_oid );
2152 mlen = strlen( mr->smr_oid );
2154 value = (struct berval *) assertValue;
2156 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2158 HASH_Init( &HASHcontext );
2159 if( prefix != NULL && prefix->bv_len > 0 ) {
2160 HASH_Update( &HASHcontext,
2161 prefix->bv_val, prefix->bv_len );
2163 HASH_Update( &HASHcontext,
2164 syntax->ssyn_oid, slen );
2165 HASH_Update( &HASHcontext,
2166 mr->smr_oid, mlen );
2167 HASH_Update( &HASHcontext,
2168 value->bv_val, value->bv_len );
2169 HASH_Final( HASHdigest, &HASHcontext );
2171 keys[0] = ber_bvdup( &digest );
2175 return LDAP_SUCCESS;
2178 /* Substrings Index generation function */
2179 int caseExactIA5SubstringsIndexer(
2184 struct berval *prefix,
2185 struct berval **values,
2186 struct berval ***keysp )
2190 struct berval **keys;
2191 HASH_CONTEXT HASHcontext;
2192 unsigned char HASHdigest[HASH_BYTES];
2193 struct berval digest;
2194 digest.bv_val = HASHdigest;
2195 digest.bv_len = sizeof(HASHdigest);
2197 /* we should have at least one value at this point */
2198 assert( values != NULL && values[0] != NULL );
2201 for( i=0; values[i] != NULL; i++ ) {
2202 /* count number of indices to generate */
2203 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2207 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2208 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2209 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2210 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2212 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2216 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2217 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2218 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2222 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2223 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2224 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2225 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2227 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2233 /* no keys to generate */
2235 return LDAP_SUCCESS;
2238 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2240 slen = strlen( syntax->ssyn_oid );
2241 mlen = strlen( mr->smr_oid );
2244 for( i=0; values[i] != NULL; i++ ) {
2246 struct berval *value;
2249 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2251 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2252 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2254 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2255 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2257 for( j=0; j<max; j++ ) {
2258 HASH_Init( &HASHcontext );
2259 if( prefix != NULL && prefix->bv_len > 0 ) {
2260 HASH_Update( &HASHcontext,
2261 prefix->bv_val, prefix->bv_len );
2264 HASH_Update( &HASHcontext,
2265 &pre, sizeof( pre ) );
2266 HASH_Update( &HASHcontext,
2267 syntax->ssyn_oid, slen );
2268 HASH_Update( &HASHcontext,
2269 mr->smr_oid, mlen );
2270 HASH_Update( &HASHcontext,
2272 SLAP_INDEX_SUBSTR_MAXLEN );
2273 HASH_Final( HASHdigest, &HASHcontext );
2275 keys[nkeys++] = ber_bvdup( &digest );
2279 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2280 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2282 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2285 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2286 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2287 HASH_Init( &HASHcontext );
2288 if( prefix != NULL && prefix->bv_len > 0 ) {
2289 HASH_Update( &HASHcontext,
2290 prefix->bv_val, prefix->bv_len );
2292 HASH_Update( &HASHcontext,
2293 &pre, sizeof( pre ) );
2294 HASH_Update( &HASHcontext,
2295 syntax->ssyn_oid, slen );
2296 HASH_Update( &HASHcontext,
2297 mr->smr_oid, mlen );
2298 HASH_Update( &HASHcontext,
2300 HASH_Final( HASHdigest, &HASHcontext );
2302 keys[nkeys++] = ber_bvdup( &digest );
2305 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2306 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2307 HASH_Init( &HASHcontext );
2308 if( prefix != NULL && prefix->bv_len > 0 ) {
2309 HASH_Update( &HASHcontext,
2310 prefix->bv_val, prefix->bv_len );
2312 HASH_Update( &HASHcontext,
2313 &pre, sizeof( pre ) );
2314 HASH_Update( &HASHcontext,
2315 syntax->ssyn_oid, slen );
2316 HASH_Update( &HASHcontext,
2317 mr->smr_oid, mlen );
2318 HASH_Update( &HASHcontext,
2319 &value->bv_val[value->bv_len-j], j );
2320 HASH_Final( HASHdigest, &HASHcontext );
2322 keys[nkeys++] = ber_bvdup( &digest );
2336 return LDAP_SUCCESS;
2339 int caseExactIA5SubstringsFilter(
2344 struct berval *prefix,
2346 struct berval ***keysp )
2348 SubstringsAssertion *sa = assertValue;
2350 ber_len_t nkeys = 0;
2351 size_t slen, mlen, klen;
2352 struct berval **keys;
2353 HASH_CONTEXT HASHcontext;
2354 unsigned char HASHdigest[HASH_BYTES];
2355 struct berval *value;
2356 struct berval digest;
2358 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2359 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2364 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2366 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2367 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2368 /* don't bother accounting for stepping */
2369 nkeys += sa->sa_any[i]->bv_len -
2370 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2375 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2376 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2383 return LDAP_SUCCESS;
2386 digest.bv_val = HASHdigest;
2387 digest.bv_len = sizeof(HASHdigest);
2389 slen = strlen( syntax->ssyn_oid );
2390 mlen = strlen( mr->smr_oid );
2392 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2395 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2396 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2398 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2399 value = sa->sa_initial;
2401 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2402 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2404 HASH_Init( &HASHcontext );
2405 if( prefix != NULL && prefix->bv_len > 0 ) {
2406 HASH_Update( &HASHcontext,
2407 prefix->bv_val, prefix->bv_len );
2409 HASH_Update( &HASHcontext,
2410 &pre, sizeof( pre ) );
2411 HASH_Update( &HASHcontext,
2412 syntax->ssyn_oid, slen );
2413 HASH_Update( &HASHcontext,
2414 mr->smr_oid, mlen );
2415 HASH_Update( &HASHcontext,
2416 value->bv_val, klen );
2417 HASH_Final( HASHdigest, &HASHcontext );
2419 keys[nkeys++] = ber_bvdup( &digest );
2422 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2424 pre = SLAP_INDEX_SUBSTR_PREFIX;
2425 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2427 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2428 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2432 value = sa->sa_any[i];
2435 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2436 j += SLAP_INDEX_SUBSTR_STEP )
2438 HASH_Init( &HASHcontext );
2439 if( prefix != NULL && prefix->bv_len > 0 ) {
2440 HASH_Update( &HASHcontext,
2441 prefix->bv_val, prefix->bv_len );
2443 HASH_Update( &HASHcontext,
2444 &pre, sizeof( pre ) );
2445 HASH_Update( &HASHcontext,
2446 syntax->ssyn_oid, slen );
2447 HASH_Update( &HASHcontext,
2448 mr->smr_oid, mlen );
2449 HASH_Update( &HASHcontext,
2450 &value->bv_val[j], klen );
2451 HASH_Final( HASHdigest, &HASHcontext );
2453 keys[nkeys++] = ber_bvdup( &digest );
2458 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2459 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2461 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2462 value = sa->sa_final;
2464 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2465 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2467 HASH_Init( &HASHcontext );
2468 if( prefix != NULL && prefix->bv_len > 0 ) {
2469 HASH_Update( &HASHcontext,
2470 prefix->bv_val, prefix->bv_len );
2472 HASH_Update( &HASHcontext,
2473 &pre, sizeof( pre ) );
2474 HASH_Update( &HASHcontext,
2475 syntax->ssyn_oid, slen );
2476 HASH_Update( &HASHcontext,
2477 mr->smr_oid, mlen );
2478 HASH_Update( &HASHcontext,
2479 &value->bv_val[value->bv_len-klen], klen );
2480 HASH_Final( HASHdigest, &HASHcontext );
2482 keys[nkeys++] = ber_bvdup( &digest );
2493 return LDAP_SUCCESS;
2502 struct berval *value,
2503 void *assertedValue )
2505 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2507 if( match == 0 && value->bv_len ) {
2508 match = strncasecmp( value->bv_val,
2509 ((struct berval *) assertedValue)->bv_val,
2514 return LDAP_SUCCESS;
2518 caseIgnoreIA5SubstringsMatch(
2523 struct berval *value,
2524 void *assertedValue )
2527 SubstringsAssertion *sub = assertedValue;
2528 struct berval left = *value;
2532 /* Add up asserted input length */
2533 if( sub->sa_initial ) {
2534 inlen += sub->sa_initial->bv_len;
2537 for(i=0; sub->sa_any[i] != NULL; i++) {
2538 inlen += sub->sa_any[i]->bv_len;
2541 if( sub->sa_final ) {
2542 inlen += sub->sa_final->bv_len;
2545 if( sub->sa_initial ) {
2546 if( inlen > left.bv_len ) {
2551 match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
2552 sub->sa_initial->bv_len );
2558 left.bv_val += sub->sa_initial->bv_len;
2559 left.bv_len -= sub->sa_initial->bv_len;
2560 inlen -= sub->sa_initial->bv_len;
2563 if( sub->sa_final ) {
2564 if( inlen > left.bv_len ) {
2569 match = strncasecmp( sub->sa_final->bv_val,
2570 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2571 sub->sa_final->bv_len );
2577 left.bv_len -= sub->sa_final->bv_len;
2578 inlen -= sub->sa_final->bv_len;
2582 for(i=0; sub->sa_any[i]; i++) {
2587 if( inlen > left.bv_len ) {
2588 /* not enough length */
2593 if( sub->sa_any[i]->bv_len == 0 ) {
2597 p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
2604 idx = p - left.bv_val;
2605 assert( idx < left.bv_len );
2607 if( idx >= left.bv_len ) {
2608 /* this shouldn't happen */
2615 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2616 /* not enough left */
2621 match = strncasecmp( left.bv_val,
2622 sub->sa_any[i]->bv_val,
2623 sub->sa_any[i]->bv_len );
2632 left.bv_val += sub->sa_any[i]->bv_len;
2633 left.bv_len -= sub->sa_any[i]->bv_len;
2634 inlen -= sub->sa_any[i]->bv_len;
2640 return LDAP_SUCCESS;
2643 /* Index generation function */
2644 int caseIgnoreIA5Indexer(
2649 struct berval *prefix,
2650 struct berval **values,
2651 struct berval ***keysp )
2655 struct berval **keys;
2656 HASH_CONTEXT HASHcontext;
2657 unsigned char HASHdigest[HASH_BYTES];
2658 struct berval digest;
2659 digest.bv_val = HASHdigest;
2660 digest.bv_len = sizeof(HASHdigest);
2662 /* we should have at least one value at this point */
2663 assert( values != NULL && values[0] != NULL );
2665 for( i=0; values[i] != NULL; i++ ) {
2666 /* just count them */
2669 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2671 slen = strlen( syntax->ssyn_oid );
2672 mlen = strlen( mr->smr_oid );
2674 for( i=0; values[i] != NULL; i++ ) {
2675 struct berval *value = ber_bvdup( values[i] );
2676 ldap_pvt_str2upper( value->bv_val );
2678 HASH_Init( &HASHcontext );
2679 if( prefix != NULL && prefix->bv_len > 0 ) {
2680 HASH_Update( &HASHcontext,
2681 prefix->bv_val, prefix->bv_len );
2683 HASH_Update( &HASHcontext,
2684 syntax->ssyn_oid, slen );
2685 HASH_Update( &HASHcontext,
2686 mr->smr_oid, mlen );
2687 HASH_Update( &HASHcontext,
2688 value->bv_val, value->bv_len );
2689 HASH_Final( HASHdigest, &HASHcontext );
2691 ber_bvfree( value );
2693 keys[i] = ber_bvdup( &digest );
2698 return LDAP_SUCCESS;
2701 /* Index generation function */
2702 int caseIgnoreIA5Filter(
2707 struct berval *prefix,
2709 struct berval ***keysp )
2712 struct berval **keys;
2713 HASH_CONTEXT HASHcontext;
2714 unsigned char HASHdigest[HASH_BYTES];
2715 struct berval *value;
2716 struct berval digest;
2717 digest.bv_val = HASHdigest;
2718 digest.bv_len = sizeof(HASHdigest);
2720 slen = strlen( syntax->ssyn_oid );
2721 mlen = strlen( mr->smr_oid );
2723 value = ber_bvdup( (struct berval *) assertValue );
2724 ldap_pvt_str2upper( value->bv_val );
2726 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2728 HASH_Init( &HASHcontext );
2729 if( prefix != NULL && prefix->bv_len > 0 ) {
2730 HASH_Update( &HASHcontext,
2731 prefix->bv_val, prefix->bv_len );
2733 HASH_Update( &HASHcontext,
2734 syntax->ssyn_oid, slen );
2735 HASH_Update( &HASHcontext,
2736 mr->smr_oid, mlen );
2737 HASH_Update( &HASHcontext,
2738 value->bv_val, value->bv_len );
2739 HASH_Final( HASHdigest, &HASHcontext );
2741 keys[0] = ber_bvdup( &digest );
2744 ber_bvfree( value );
2748 return LDAP_SUCCESS;
2751 /* Substrings Index generation function */
2752 int caseIgnoreIA5SubstringsIndexer(
2757 struct berval *prefix,
2758 struct berval **values,
2759 struct berval ***keysp )
2763 struct berval **keys;
2764 HASH_CONTEXT HASHcontext;
2765 unsigned char HASHdigest[HASH_BYTES];
2766 struct berval digest;
2767 digest.bv_val = HASHdigest;
2768 digest.bv_len = sizeof(HASHdigest);
2770 /* we should have at least one value at this point */
2771 assert( values != NULL && values[0] != NULL );
2774 for( i=0; values[i] != NULL; i++ ) {
2775 /* count number of indices to generate */
2776 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2780 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2781 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2782 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2783 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2785 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2789 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2790 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2791 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2795 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2796 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2797 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2798 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2800 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2806 /* no keys to generate */
2808 return LDAP_SUCCESS;
2811 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2813 slen = strlen( syntax->ssyn_oid );
2814 mlen = strlen( mr->smr_oid );
2817 for( i=0; values[i] != NULL; i++ ) {
2819 struct berval *value;
2821 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2823 value = ber_bvdup( values[i] );
2824 ldap_pvt_str2upper( value->bv_val );
2826 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2827 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2829 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2830 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2832 for( j=0; j<max; j++ ) {
2833 HASH_Init( &HASHcontext );
2834 if( prefix != NULL && prefix->bv_len > 0 ) {
2835 HASH_Update( &HASHcontext,
2836 prefix->bv_val, prefix->bv_len );
2839 HASH_Update( &HASHcontext,
2840 &pre, sizeof( pre ) );
2841 HASH_Update( &HASHcontext,
2842 syntax->ssyn_oid, slen );
2843 HASH_Update( &HASHcontext,
2844 mr->smr_oid, mlen );
2845 HASH_Update( &HASHcontext,
2847 SLAP_INDEX_SUBSTR_MAXLEN );
2848 HASH_Final( HASHdigest, &HASHcontext );
2850 keys[nkeys++] = ber_bvdup( &digest );
2854 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2855 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2857 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2860 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2861 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2862 HASH_Init( &HASHcontext );
2863 if( prefix != NULL && prefix->bv_len > 0 ) {
2864 HASH_Update( &HASHcontext,
2865 prefix->bv_val, prefix->bv_len );
2867 HASH_Update( &HASHcontext,
2868 &pre, sizeof( pre ) );
2869 HASH_Update( &HASHcontext,
2870 syntax->ssyn_oid, slen );
2871 HASH_Update( &HASHcontext,
2872 mr->smr_oid, mlen );
2873 HASH_Update( &HASHcontext,
2875 HASH_Final( HASHdigest, &HASHcontext );
2877 keys[nkeys++] = ber_bvdup( &digest );
2880 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2881 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2882 HASH_Init( &HASHcontext );
2883 if( prefix != NULL && prefix->bv_len > 0 ) {
2884 HASH_Update( &HASHcontext,
2885 prefix->bv_val, prefix->bv_len );
2887 HASH_Update( &HASHcontext,
2888 &pre, sizeof( pre ) );
2889 HASH_Update( &HASHcontext,
2890 syntax->ssyn_oid, slen );
2891 HASH_Update( &HASHcontext,
2892 mr->smr_oid, mlen );
2893 HASH_Update( &HASHcontext,
2894 &value->bv_val[value->bv_len-j], j );
2895 HASH_Final( HASHdigest, &HASHcontext );
2897 keys[nkeys++] = ber_bvdup( &digest );
2902 ber_bvfree( value );
2913 return LDAP_SUCCESS;
2916 int caseIgnoreIA5SubstringsFilter(
2921 struct berval *prefix,
2923 struct berval ***keysp )
2925 SubstringsAssertion *sa = assertValue;
2927 ber_len_t nkeys = 0;
2928 size_t slen, mlen, klen;
2929 struct berval **keys;
2930 HASH_CONTEXT HASHcontext;
2931 unsigned char HASHdigest[HASH_BYTES];
2932 struct berval *value;
2933 struct berval digest;
2935 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
2936 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2941 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
2943 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2944 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2945 /* don't bother accounting for stepping */
2946 nkeys += sa->sa_any[i]->bv_len -
2947 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2952 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
2953 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2960 return LDAP_SUCCESS;
2963 digest.bv_val = HASHdigest;
2964 digest.bv_len = sizeof(HASHdigest);
2966 slen = strlen( syntax->ssyn_oid );
2967 mlen = strlen( mr->smr_oid );
2969 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2972 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
2973 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2975 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2976 value = ber_bvdup( sa->sa_initial );
2977 ldap_pvt_str2upper( value->bv_val );
2979 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2980 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2982 HASH_Init( &HASHcontext );
2983 if( prefix != NULL && prefix->bv_len > 0 ) {
2984 HASH_Update( &HASHcontext,
2985 prefix->bv_val, prefix->bv_len );
2987 HASH_Update( &HASHcontext,
2988 &pre, sizeof( pre ) );
2989 HASH_Update( &HASHcontext,
2990 syntax->ssyn_oid, slen );
2991 HASH_Update( &HASHcontext,
2992 mr->smr_oid, mlen );
2993 HASH_Update( &HASHcontext,
2994 value->bv_val, klen );
2995 HASH_Final( HASHdigest, &HASHcontext );
2997 ber_bvfree( value );
2998 keys[nkeys++] = ber_bvdup( &digest );
3001 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3003 pre = SLAP_INDEX_SUBSTR_PREFIX;
3004 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3006 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3007 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3011 value = ber_bvdup( sa->sa_any[i] );
3012 ldap_pvt_str2upper( value->bv_val );
3015 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3016 j += SLAP_INDEX_SUBSTR_STEP )
3018 HASH_Init( &HASHcontext );
3019 if( prefix != NULL && prefix->bv_len > 0 ) {
3020 HASH_Update( &HASHcontext,
3021 prefix->bv_val, prefix->bv_len );
3023 HASH_Update( &HASHcontext,
3024 &pre, sizeof( pre ) );
3025 HASH_Update( &HASHcontext,
3026 syntax->ssyn_oid, slen );
3027 HASH_Update( &HASHcontext,
3028 mr->smr_oid, mlen );
3029 HASH_Update( &HASHcontext,
3030 &value->bv_val[j], klen );
3031 HASH_Final( HASHdigest, &HASHcontext );
3033 keys[nkeys++] = ber_bvdup( &digest );
3036 ber_bvfree( value );
3040 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3041 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3043 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3044 value = ber_bvdup( sa->sa_final );
3045 ldap_pvt_str2upper( value->bv_val );
3047 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3048 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3050 HASH_Init( &HASHcontext );
3051 if( prefix != NULL && prefix->bv_len > 0 ) {
3052 HASH_Update( &HASHcontext,
3053 prefix->bv_val, prefix->bv_len );
3055 HASH_Update( &HASHcontext,
3056 &pre, sizeof( pre ) );
3057 HASH_Update( &HASHcontext,
3058 syntax->ssyn_oid, slen );
3059 HASH_Update( &HASHcontext,
3060 mr->smr_oid, mlen );
3061 HASH_Update( &HASHcontext,
3062 &value->bv_val[value->bv_len-klen], klen );
3063 HASH_Final( HASHdigest, &HASHcontext );
3065 ber_bvfree( value );
3066 keys[nkeys++] = ber_bvdup( &digest );
3077 return LDAP_SUCCESS;
3081 numericStringValidate(
3087 for(i=0; i < in->bv_len; i++) {
3088 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3089 return LDAP_INVALID_SYNTAX;
3093 return LDAP_SUCCESS;
3097 numericStringNormalize(
3100 struct berval **normalized )
3102 /* removal all spaces */
3103 struct berval *newval;
3106 newval = ch_malloc( sizeof( struct berval ) );
3107 newval->bv_val = ch_malloc( val->bv_len + 1 );
3113 if ( ASCII_SPACE( *p ) ) {
3114 /* Ignore whitespace */
3121 /* we should have copied no more then is in val */
3122 assert( (q - newval->bv_val) <= (p - val->bv_val) );
3124 /* null terminate */
3127 newval->bv_len = q - newval->bv_val;
3128 *normalized = newval;
3130 return LDAP_SUCCESS;
3134 objectIdentifierFirstComponentMatch(
3139 struct berval *value,
3140 void *assertedValue )
3142 int rc = LDAP_SUCCESS;
3144 struct berval *asserted = (struct berval *) assertedValue;
3148 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3149 return LDAP_INVALID_SYNTAX;
3152 /* trim leading white space */
3153 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3157 /* grab next word */
3158 oid.bv_val = &value->bv_val[i];
3159 oid.bv_len = value->bv_len - i;
3160 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3165 /* insert attributeTypes, objectclass check here */
3166 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3167 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3170 char *stored = ch_malloc( oid.bv_len + 1 );
3171 AC_MEMCPY( stored, oid.bv_val, oid.bv_len );
3172 stored[oid.bv_len] = '\0';
3174 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3175 MatchingRule *asserted_mr = mr_find( asserted->bv_val );
3176 MatchingRule *stored_mr = mr_find( stored );
3178 if( asserted_mr == NULL ) {
3179 rc = SLAPD_COMPARE_UNDEFINED;
3181 match = asserted_mr != stored_mr;
3184 } else if ( !strcmp( syntax->ssyn_oid,
3185 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3187 AttributeType *asserted_at = at_find( asserted->bv_val );
3188 AttributeType *stored_at = at_find( stored );
3190 if( asserted_at == NULL ) {
3191 rc = SLAPD_COMPARE_UNDEFINED;
3193 match = asserted_at != stored_at;
3196 } else if ( !strcmp( syntax->ssyn_oid,
3197 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3199 ObjectClass *asserted_oc = oc_find( asserted->bv_val );
3200 ObjectClass *stored_oc = oc_find( stored );
3202 if( asserted_oc == NULL ) {
3203 rc = SLAPD_COMPARE_UNDEFINED;
3205 match = asserted_oc != stored_oc;
3213 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3214 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3215 match, value->bv_val, asserted->bv_val ));
3217 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3218 "%d\n\t\"%s\"\n\t\"%s\"\n",
3219 match, value->bv_val, asserted->bv_val );
3223 if( rc == LDAP_SUCCESS ) *matchp = match;
3233 struct berval *value,
3234 void *assertedValue )
3236 long lValue, lAssertedValue;
3238 /* safe to assume integers are NUL terminated? */
3239 lValue = strtoul(value->bv_val, NULL, 10);
3240 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3241 return LDAP_CONSTRAINT_VIOLATION;
3243 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3244 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3245 return LDAP_CONSTRAINT_VIOLATION;
3247 *matchp = (lValue & lAssertedValue);
3248 return LDAP_SUCCESS;
3257 struct berval *value,
3258 void *assertedValue )
3260 long lValue, lAssertedValue;
3262 /* safe to assume integers are NUL terminated? */
3263 lValue = strtoul(value->bv_val, NULL, 10);
3264 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3265 return LDAP_CONSTRAINT_VIOLATION;
3267 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3268 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3269 return LDAP_CONSTRAINT_VIOLATION;
3271 *matchp = (lValue | lAssertedValue);
3272 return LDAP_SUCCESS;
3276 check_time_syntax (struct berval *val,
3280 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3281 static int mdays[2][12] = {
3282 /* non-leap years */
3283 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3285 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3288 int part, c, tzoffset, leapyear = 0 ;
3290 if( val->bv_len == 0 ) {
3291 return LDAP_INVALID_SYNTAX;
3294 p = (char *)val->bv_val;
3295 e = p + val->bv_len;
3297 /* Ignore initial whitespace */
3298 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3302 if (e - p < 13 - (2 * start)) {
3303 return LDAP_INVALID_SYNTAX;
3306 for (part = 0; part < 9; part++) {
3310 for (part = start; part < 7; part++) {
3312 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3319 return LDAP_INVALID_SYNTAX;
3321 if (c < 0 || c > 9) {
3322 return LDAP_INVALID_SYNTAX;
3328 return LDAP_INVALID_SYNTAX;
3330 if (c < 0 || c > 9) {
3331 return LDAP_INVALID_SYNTAX;
3336 if (part == 2 || part == 3) {
3339 if (parts[part] < 0) {
3340 return LDAP_INVALID_SYNTAX;
3342 if (parts[part] > ceiling[part]) {
3343 return LDAP_INVALID_SYNTAX;
3347 /* leapyear check for the Gregorian calendar (year>1581) */
3348 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
3349 ((parts[0] % 4 == 0) && (parts[1] == 0)))
3354 if (parts[3] > mdays[leapyear][parts[2]]) {
3355 return LDAP_INVALID_SYNTAX;
3360 tzoffset = 0; /* UTC */
3361 } else if (c != '+' && c != '-') {
3362 return LDAP_INVALID_SYNTAX;
3366 } else /* c == '+' */ {
3371 return LDAP_INVALID_SYNTAX;
3374 for (part = 7; part < 9; part++) {
3376 if (c < 0 || c > 9) {
3377 return LDAP_INVALID_SYNTAX;
3382 if (c < 0 || c > 9) {
3383 return LDAP_INVALID_SYNTAX;
3387 if (parts[part] < 0 || parts[part] > ceiling[part]) {
3388 return LDAP_INVALID_SYNTAX;
3393 /* Ignore trailing whitespace */
3394 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3398 return LDAP_INVALID_SYNTAX;
3401 switch ( tzoffset ) {
3402 case -1: /* negativ offset to UTC, ie west of Greenwich */
3403 parts[4] += parts[7];
3404 parts[5] += parts[8];
3405 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
3409 c = mdays[leapyear][parts[2]];
3411 if (parts[part] > c) {
3412 parts[part] -= c + 1;
3417 case 1: /* positive offset to UTC, ie east of Greenwich */
3418 parts[4] -= parts[7];
3419 parts[5] -= parts[8];
3420 for (part = 6; --part > 0; ) {
3424 /* first arg to % needs to be non negativ */
3425 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
3427 if (parts[part] < 0) {
3428 parts[part] += c + 1;
3433 case 0: /* already UTC */
3437 return LDAP_SUCCESS;
3444 struct berval **normalized )
3449 rc = check_time_syntax(val, 1, parts);
3450 if (rc != LDAP_SUCCESS) {
3455 out = ch_malloc( sizeof(struct berval) );
3457 return LBER_ERROR_MEMORY;
3460 out->bv_val = ch_malloc( 14 );
3461 if ( out->bv_val == NULL ) {
3463 return LBER_ERROR_MEMORY;
3466 sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ldZ",
3467 parts[1], parts[2] + 1, parts[3] + 1,
3468 parts[4], parts[5], parts[6] );
3472 return LDAP_SUCCESS;
3482 return check_time_syntax(in, 1, parts);
3486 generalizedTimeValidate(
3492 return check_time_syntax(in, 0, parts);
3496 generalizedTimeNormalize(
3499 struct berval **normalized )
3504 rc = check_time_syntax(val, 0, parts);
3505 if (rc != LDAP_SUCCESS) {
3510 out = ch_malloc( sizeof(struct berval) );
3512 return LBER_ERROR_MEMORY;
3515 out->bv_val = ch_malloc( 16 );
3516 if ( out->bv_val == NULL ) {
3518 return LBER_ERROR_MEMORY;
3521 sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ld%02ldZ",
3522 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
3523 parts[4], parts[5], parts[6] );
3527 return LDAP_SUCCESS;
3531 nisNetgroupTripleValidate(
3533 struct berval *val )
3538 if ( val->bv_len == 0 ) {
3539 return LDAP_INVALID_SYNTAX;
3542 p = (char *)val->bv_val;
3543 e = p + val->bv_len;
3545 if ( *p != '(' /*')'*/ ) {
3546 return LDAP_INVALID_SYNTAX;
3549 for ( p++; ( p < e ) && ( *p != ')' ); p++ ) {
3553 return LDAP_INVALID_SYNTAX;
3556 } else if ( !ATTR_CHAR( *p ) ) {
3557 return LDAP_INVALID_SYNTAX;
3561 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
3562 return LDAP_INVALID_SYNTAX;
3568 return LDAP_INVALID_SYNTAX;
3571 return LDAP_SUCCESS;
3575 bootParameterValidate(
3577 struct berval *val )
3581 if ( val->bv_len == 0 ) {
3582 return LDAP_INVALID_SYNTAX;
3585 p = (char *)val->bv_val;
3586 e = p + val->bv_len;
3589 for (; ( p < e ) && ( *p != '=' ); p++ ) {
3590 if ( !ATTR_CHAR( *p ) ) {
3591 return LDAP_INVALID_SYNTAX;
3596 return LDAP_INVALID_SYNTAX;
3600 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
3601 if ( !ATTR_CHAR( *p ) ) {
3602 return LDAP_INVALID_SYNTAX;
3607 return LDAP_INVALID_SYNTAX;
3611 for ( p++; p < e; p++ ) {
3612 if ( !ATTR_CHAR( *p ) ) {
3613 return LDAP_INVALID_SYNTAX;
3617 return LDAP_SUCCESS;
3620 struct syntax_defs_rec {
3623 slap_syntax_validate_func *sd_validate;
3624 slap_syntax_transform_func *sd_normalize;
3625 slap_syntax_transform_func *sd_pretty;
3626 #ifdef SLAPD_BINARY_CONVERSION
3627 slap_syntax_transform_func *sd_ber2str;
3628 slap_syntax_transform_func *sd_str2ber;
3632 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
3633 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
3635 struct syntax_defs_rec syntax_defs[] = {
3636 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
3637 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
3638 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
3639 0, NULL, NULL, NULL},
3640 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
3641 0, NULL, NULL, NULL},
3642 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
3643 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
3644 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_NOT_H_R ")",
3645 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3646 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
3647 0, bitStringValidate, NULL, NULL },
3648 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
3649 0, booleanValidate, NULL, NULL},
3650 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
3651 X_BINARY X_NOT_H_R ")",
3652 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3653 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
3654 X_BINARY X_NOT_H_R ")",
3655 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3656 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
3657 X_BINARY X_NOT_H_R ")",
3658 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3659 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
3660 0, countryStringValidate, IA5StringNormalize, NULL},
3661 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
3662 0, dnValidate, dnNormalize, dnPretty},
3663 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
3664 0, NULL, NULL, NULL},
3665 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
3666 0, NULL, NULL, NULL},
3667 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
3668 0, UTF8StringValidate, UTF8StringNormalize, NULL},
3669 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
3670 0, NULL, NULL, NULL},
3671 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
3672 0, NULL, NULL, NULL},
3673 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
3674 0, NULL, NULL, NULL},
3675 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
3676 0, NULL, NULL, NULL},
3677 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
3678 0, NULL, NULL, NULL},
3679 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
3680 0, printablesStringValidate, IA5StringNormalize, NULL},
3681 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
3682 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
3683 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
3684 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
3685 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
3686 0, NULL, NULL, NULL},
3687 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
3688 0, IA5StringValidate, IA5StringNormalize, NULL},
3689 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
3690 0, integerValidate, integerNormalize, integerPretty},
3691 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
3692 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
3693 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
3694 0, NULL, NULL, NULL},
3695 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
3696 0, NULL, NULL, NULL},
3697 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
3698 0, NULL, NULL, NULL},
3699 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
3700 0, NULL, NULL, NULL},
3701 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
3702 0, NULL, NULL, NULL},
3703 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
3704 0, nameUIDValidate, nameUIDNormalize, NULL},
3705 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
3706 0, NULL, NULL, NULL},
3707 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
3708 0, numericStringValidate, numericStringNormalize, NULL},
3709 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
3710 0, NULL, NULL, NULL},
3711 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
3712 0, oidValidate, NULL, NULL},
3713 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
3714 0, IA5StringValidate, IA5StringNormalize, NULL},
3715 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
3716 0, blobValidate, NULL, NULL},
3717 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
3718 0, UTF8StringValidate, UTF8StringNormalize, NULL},
3719 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
3720 0, NULL, NULL, NULL},
3721 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
3722 0, NULL, NULL, NULL},
3723 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
3724 0, printableStringValidate, IA5StringNormalize, NULL},
3725 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
3726 X_BINARY X_NOT_H_R ")",
3727 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3728 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
3729 0, printableStringValidate, IA5StringNormalize, NULL},
3730 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
3731 0, NULL, NULL, NULL},
3732 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
3733 0, printableStringValidate, IA5StringNormalize, NULL},
3734 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
3735 0, utcTimeValidate, utcTimeNormalize, NULL},
3736 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
3737 0, NULL, NULL, NULL},
3738 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
3739 0, NULL, NULL, NULL},
3740 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
3741 0, NULL, NULL, NULL},
3742 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
3743 0, NULL, NULL, NULL},
3744 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
3745 0, NULL, NULL, NULL},
3747 /* RFC 2307 NIS Syntaxes */
3748 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
3749 0, nisNetgroupTripleValidate, NULL, NULL},
3750 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
3751 0, bootParameterValidate, NULL, NULL},
3753 /* OpenLDAP Experimental Syntaxes */
3754 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
3755 0, UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
3757 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
3758 0, NULL, NULL, NULL},
3760 /* OpenLDAP Void Syntax */
3761 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
3762 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
3763 {NULL, 0, NULL, NULL, NULL}
3766 struct mrule_defs_rec {
3768 slap_mask_t mrd_usage;
3769 slap_mr_convert_func * mrd_convert;
3770 slap_mr_normalize_func * mrd_normalize;
3771 slap_mr_match_func * mrd_match;
3772 slap_mr_indexer_func * mrd_indexer;
3773 slap_mr_filter_func * mrd_filter;
3775 char * mrd_associated;
3779 * Other matching rules in X.520 that we do not use (yet):
3781 * 2.5.13.9 numericStringOrderingMatch
3782 * 2.5.13.15 integerOrderingMatch
3783 * 2.5.13.18 octetStringOrderingMatch
3784 * 2.5.13.19 octetStringSubstringsMatch
3785 * 2.5.13.25 uTCTimeMatch
3786 * 2.5.13.26 uTCTimeOrderingMatch
3787 * 2.5.13.31 directoryStringFirstComponentMatch
3788 * 2.5.13.32 wordMatch
3789 * 2.5.13.33 keywordMatch
3790 * 2.5.13.34 certificateExactMatch
3791 * 2.5.13.35 certificateMatch
3792 * 2.5.13.36 certificatePairExactMatch
3793 * 2.5.13.37 certificatePairMatch
3794 * 2.5.13.38 certificateListExactMatch
3795 * 2.5.13.39 certificateListMatch
3796 * 2.5.13.40 algorithmIdentifierMatch
3797 * 2.5.13.41 storedPrefixMatch
3798 * 2.5.13.42 attributeCertificateMatch
3799 * 2.5.13.43 readerAndKeyIDMatch
3800 * 2.5.13.44 attributeIntegrityMatch
3803 struct mrule_defs_rec mrule_defs[] = {
3805 * EQUALITY matching rules must be listed after associated APPROX
3806 * matching rules. So, we list all APPROX matching rules first.
3808 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
3809 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3810 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
3812 directoryStringApproxMatch,
3813 directoryStringApproxIndexer,
3814 directoryStringApproxFilter,
3817 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
3818 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
3819 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
3821 IA5StringApproxMatch,
3822 IA5StringApproxIndexer,
3823 IA5StringApproxFilter,
3827 * Other matching rules
3830 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
3831 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
3832 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3834 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
3837 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
3838 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
3839 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3841 dnMatch, dnIndexer, dnFilter,
3844 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
3845 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3846 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3848 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
3849 directoryStringApproxMatchOID },
3851 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
3852 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3855 caseIgnoreOrderingMatch, NULL, NULL,
3858 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
3859 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3860 SLAP_MR_SUBSTR | SLAP_MR_EXT,
3862 caseExactIgnoreSubstringsMatch,
3863 caseExactIgnoreSubstringsIndexer,
3864 caseExactIgnoreSubstringsFilter,
3867 {"( 2.5.13.5 NAME 'caseExactMatch' "
3868 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3869 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3871 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
3872 directoryStringApproxMatchOID },
3874 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
3875 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3878 caseExactOrderingMatch, NULL, NULL,
3881 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
3882 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3883 SLAP_MR_SUBSTR | SLAP_MR_EXT,
3885 caseExactIgnoreSubstringsMatch,
3886 caseExactIgnoreSubstringsIndexer,
3887 caseExactIgnoreSubstringsFilter,
3890 {"( 2.5.13.8 NAME 'numericStringMatch' "
3891 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
3892 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3895 caseIgnoreIA5Indexer,
3896 caseIgnoreIA5Filter,
3899 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
3900 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3901 SLAP_MR_SUBSTR | SLAP_MR_EXT,
3903 caseIgnoreIA5SubstringsMatch,
3904 caseIgnoreIA5SubstringsIndexer,
3905 caseIgnoreIA5SubstringsFilter,
3908 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
3909 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
3910 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3912 caseIgnoreListMatch, NULL, NULL,
3915 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
3916 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3917 SLAP_MR_SUBSTR | SLAP_MR_EXT,
3919 caseIgnoreListSubstringsMatch, NULL, NULL,
3922 {"( 2.5.13.13 NAME 'booleanMatch' "
3923 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
3924 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3926 booleanMatch, NULL, NULL,
3929 {"( 2.5.13.14 NAME 'integerMatch' "
3930 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
3931 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3933 integerMatch, integerIndexer, integerFilter,
3936 {"( 2.5.13.16 NAME 'bitStringMatch' "
3937 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
3938 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3940 bitStringMatch, NULL, NULL,
3943 {"( 2.5.13.17 NAME 'octetStringMatch' "
3944 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
3945 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3947 octetStringMatch, octetStringIndexer, octetStringFilter,
3950 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
3951 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
3952 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3954 telephoneNumberMatch,
3955 telephoneNumberIndexer,
3956 telephoneNumberFilter,
3959 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
3960 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3961 SLAP_MR_SUBSTR | SLAP_MR_EXT,
3963 telephoneNumberSubstringsMatch,
3964 telephoneNumberSubstringsIndexer,
3965 telephoneNumberSubstringsFilter,
3968 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
3969 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
3970 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3975 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
3976 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
3977 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3979 uniqueMemberMatch, NULL, NULL,
3982 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
3983 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
3984 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3986 protocolInformationMatch, NULL, NULL,
3989 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
3990 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
3991 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3993 generalizedTimeMatch, NULL, NULL,
3996 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
3997 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4000 generalizedTimeOrderingMatch, NULL, NULL,
4003 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4004 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4005 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4007 integerFirstComponentMatch, NULL, NULL,
4010 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4011 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4012 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4014 objectIdentifierFirstComponentMatch, NULL, NULL,
4017 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4018 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4019 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4021 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4022 IA5StringApproxMatchOID },
4024 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4025 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4026 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4028 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4029 IA5StringApproxMatchOID },
4031 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4032 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4035 caseIgnoreIA5SubstringsMatch,
4036 caseIgnoreIA5SubstringsIndexer,
4037 caseIgnoreIA5SubstringsFilter,
4040 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4041 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4044 caseExactIA5SubstringsMatch,
4045 caseExactIA5SubstringsIndexer,
4046 caseExactIA5SubstringsFilter,
4049 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4050 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4053 authPasswordMatch, NULL, NULL,
4056 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4057 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4060 OpenLDAPaciMatch, NULL, NULL,
4063 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4064 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4067 integerBitAndMatch, NULL, NULL,
4070 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4071 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4074 integerBitOrMatch, NULL, NULL,
4077 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
4086 /* we should only be called once (from main) */
4087 assert( schema_init_done == 0 );
4089 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4090 res = register_syntax( syntax_defs[i].sd_desc,
4091 syntax_defs[i].sd_flags,
4092 syntax_defs[i].sd_validate,
4093 syntax_defs[i].sd_normalize,
4094 syntax_defs[i].sd_pretty
4095 #ifdef SLAPD_BINARY_CONVERSION
4097 syntax_defs[i].sd_ber2str,
4098 syntax_defs[i].sd_str2ber
4103 fprintf( stderr, "schema_init: Error registering syntax %s\n",
4104 syntax_defs[i].sd_desc );
4109 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4110 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
4112 "schema_init: Ingoring unusable matching rule %s\n",
4113 mrule_defs[i].mrd_desc );
4117 res = register_matching_rule(
4118 mrule_defs[i].mrd_desc,
4119 mrule_defs[i].mrd_usage,
4120 mrule_defs[i].mrd_convert,
4121 mrule_defs[i].mrd_normalize,
4122 mrule_defs[i].mrd_match,
4123 mrule_defs[i].mrd_indexer,
4124 mrule_defs[i].mrd_filter,
4125 mrule_defs[i].mrd_associated );
4129 "schema_init: Error registering matching rule %s\n",
4130 mrule_defs[i].mrd_desc );
4134 schema_init_done = 1;
4135 return LDAP_SUCCESS;