1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
15 #include <ac/string.h>
16 #include <ac/socket.h>
21 #include "ldap_utf8.h"
23 #include "lutil_hash.h"
24 #define HASH_BYTES LUTIL_HASH_BYTES
25 #define HASH_CONTEXT lutil_HASH_CTX
26 #define HASH_Init(c) lutil_HASHInit(c)
27 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
28 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
30 /* recycled validatation routines */
31 #define berValidate blobValidate
33 /* unimplemented pretters */
34 #define integerPretty NULL
36 /* recycled matching routines */
37 #define bitStringMatch octetStringMatch
38 #define numericStringMatch caseIgnoreIA5Match
39 #define objectIdentifierMatch caseIgnoreIA5Match
40 #define telephoneNumberMatch caseIgnoreIA5Match
41 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
42 #define generalizedTimeMatch caseIgnoreIA5Match
43 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
44 #define uniqueMemberMatch dnMatch
46 /* approx matching rules */
47 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
48 #define directoryStringApproxMatch approxMatch
49 #define directoryStringApproxIndexer approxIndexer
50 #define directoryStringApproxFilter approxFilter
51 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
52 #define IA5StringApproxMatch approxMatch
53 #define IA5StringApproxIndexer approxIndexer
54 #define IA5StringApproxFilter approxFilter
56 /* orderring matching rules */
57 #define caseIgnoreOrderingMatch caseIgnoreMatch
58 #define caseExactOrderingMatch caseExactMatch
60 /* unimplemented matching routines */
61 #define caseIgnoreListMatch NULL
62 #define caseIgnoreListSubstringsMatch NULL
63 #define protocolInformationMatch NULL
64 #define integerFirstComponentMatch NULL
66 #define OpenLDAPaciMatch NULL
67 #define authPasswordMatch NULL
69 /* recycled indexing/filtering routines */
70 #define dnIndexer caseExactIgnoreIndexer
71 #define dnFilter caseExactIgnoreFilter
72 #define bitStringFilter octetStringFilter
73 #define bitStringIndexer octetStringIndexer
75 #define telephoneNumberIndexer caseIgnoreIA5Indexer
76 #define telephoneNumberFilter caseIgnoreIA5Filter
77 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
78 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
80 /* must match OIDs below */
81 #define caseExactMatchOID "2.5.13.5"
82 #define caseExactSubstringsMatchOID "2.5.13.7"
84 static char *strcasechr( const char *str, int c )
86 char *lower = strchr( str, TOLOWER(c) );
87 char *upper = strchr( str, TOUPPER(c) );
89 if( lower && upper ) {
90 return lower < upper ? lower : upper;
104 struct berval *value,
105 void *assertedValue )
107 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
110 match = memcmp( value->bv_val,
111 ((struct berval *) assertedValue)->bv_val,
119 /* Index generation function */
120 static int octetStringIndexer(
125 struct berval *prefix,
132 HASH_CONTEXT HASHcontext;
133 unsigned char HASHdigest[HASH_BYTES];
134 struct berval digest;
135 digest.bv_val = HASHdigest;
136 digest.bv_len = sizeof(HASHdigest);
138 for( i=0; values[i].bv_val != NULL; i++ ) {
139 /* just count them */
142 /* we should have at least one value at this point */
145 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
147 slen = syntax->ssyn_oidlen;
148 mlen = mr->smr_oidlen;
150 for( i=0; values[i].bv_val != NULL; i++ ) {
151 HASH_Init( &HASHcontext );
152 if( prefix != NULL && prefix->bv_len > 0 ) {
153 HASH_Update( &HASHcontext,
154 prefix->bv_val, prefix->bv_len );
156 HASH_Update( &HASHcontext,
157 syntax->ssyn_oid, slen );
158 HASH_Update( &HASHcontext,
160 HASH_Update( &HASHcontext,
161 values[i].bv_val, values[i].bv_len );
162 HASH_Final( HASHdigest, &HASHcontext );
164 ber_dupbv( &keys[i], &digest );
167 keys[i].bv_val = NULL;
174 /* Index generation function */
175 static int octetStringFilter(
180 struct berval *prefix,
186 HASH_CONTEXT HASHcontext;
187 unsigned char HASHdigest[HASH_BYTES];
188 struct berval *value = (struct berval *) assertValue;
189 struct berval digest;
190 digest.bv_val = HASHdigest;
191 digest.bv_len = sizeof(HASHdigest);
193 slen = syntax->ssyn_oidlen;
194 mlen = mr->smr_oidlen;
196 keys = ch_malloc( sizeof( struct berval ) * 2 );
198 HASH_Init( &HASHcontext );
199 if( prefix != NULL && prefix->bv_len > 0 ) {
200 HASH_Update( &HASHcontext,
201 prefix->bv_val, prefix->bv_len );
203 HASH_Update( &HASHcontext,
204 syntax->ssyn_oid, slen );
205 HASH_Update( &HASHcontext,
207 HASH_Update( &HASHcontext,
208 value->bv_val, value->bv_len );
209 HASH_Final( HASHdigest, &HASHcontext );
211 ber_dupbv( keys, &digest );
212 keys[1].bv_val = NULL;
227 if( in->bv_len == 0 ) return LDAP_SUCCESS;
229 ber_dupbv( &dn, in );
230 if( !dn.bv_val ) return LDAP_OTHER;
232 if( dn.bv_val[dn.bv_len-1] == 'B'
233 && dn.bv_val[dn.bv_len-2] == '\'' )
235 /* assume presence of optional UID */
238 for(i=dn.bv_len-3; i>1; i--) {
239 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
243 if( dn.bv_val[i] != '\'' ||
244 dn.bv_val[i-1] != '#' ) {
245 ber_memfree( dn.bv_val );
246 return LDAP_INVALID_SYNTAX;
249 /* trim the UID to allow use of dnValidate */
250 dn.bv_val[i-1] = '\0';
254 rc = dnValidate( NULL, &dn );
264 struct berval *normalized )
269 ber_dupbv( &out, val );
270 if( out.bv_len != 0 ) {
273 ber_len_t uidlen = 0;
275 if( out.bv_val[out.bv_len-1] == '\'' ) {
276 /* assume presence of optional UID */
277 uid = strrchr( out.bv_val, '#' );
281 return LDAP_INVALID_SYNTAX;
284 uidlen = out.bv_len - (uid - out.bv_val);
285 /* temporarily trim the UID */
287 out.bv_len -= uidlen;
290 #ifdef USE_DN_NORMALIZE
291 rc = dnNormalize2( NULL, &out, normalized );
293 rc = dnPretty2( NULL, &out, normalized );
296 if( rc != LDAP_SUCCESS ) {
298 return LDAP_INVALID_SYNTAX;
301 dnlen = normalized->bv_len;
305 b2.bv_val = ch_malloc(dnlen + uidlen + 1);
306 AC_MEMCPY( b2.bv_val, normalized->bv_val, dnlen );
308 /* restore the separator */
311 AC_MEMCPY( normalized->bv_val+dnlen, uid, uidlen );
312 b2.bv_len = dnlen + uidlen;
313 normalized->bv_val[dnlen+uidlen] = '\0';
314 free(normalized->bv_val);
328 /* any value allowed */
337 /* any value allowed */
348 /* very unforgiving validation, requires no normalization
349 * before simplistic matching
351 if( in->bv_len < 3 ) {
352 return LDAP_INVALID_SYNTAX;
356 * rfc 2252 section 6.3 Bit String
357 * bitstring = "'" *binary-digit "'"
358 * binary-digit = "0" / "1"
359 * example: '0101111101'B
362 if( in->bv_val[0] != '\'' ||
363 in->bv_val[in->bv_len-2] != '\'' ||
364 in->bv_val[in->bv_len-1] != 'B' )
366 return LDAP_INVALID_SYNTAX;
369 for( i=in->bv_len-3; i>0; i-- ) {
370 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
371 return LDAP_INVALID_SYNTAX;
382 struct berval *normalized )
385 * A normalized bitString is has no extaneous (leading) zero bits.
386 * That is, '00010'B is normalized to '10'B
387 * However, as a special case, '0'B requires no normalization.
391 /* start at the first bit */
394 /* Find the first non-zero bit */
395 while ( *p == '0' ) p++;
398 /* no non-zero bits */
399 ber_str2bv( "\'0\'B", sizeof("\'0\'B") - 1, 1, normalized );
403 normalized->bv_val = ch_malloc( val->bv_len + 1 );
405 normalized->bv_val[0] = '\'';
406 normalized->bv_len = 1;
408 for( ; *p != '\0'; p++ ) {
409 normalized->bv_val[normalized->bv_len++] = *p;
412 normalized->bv_val[normalized->bv_len] = '\0';
419 * Handling boolean syntax and matching is quite rigid.
420 * A more flexible approach would be to allow a variety
421 * of strings to be normalized and prettied into TRUE
429 /* very unforgiving validation, requires no normalization
430 * before simplistic matching
433 if( in->bv_len == 4 ) {
434 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
437 } else if( in->bv_len == 5 ) {
438 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
443 return LDAP_INVALID_SYNTAX;
452 struct berval *value,
453 void *assertedValue )
455 /* simplistic matching allowed by rigid validation */
456 struct berval *asserted = (struct berval *) assertedValue;
457 *matchp = value->bv_len != asserted->bv_len;
468 unsigned char *u = in->bv_val;
470 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
472 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
473 /* get the length indicated by the first byte */
474 len = LDAP_UTF8_CHARLEN2( u, len );
476 /* very basic checks */
479 if( (u[5] & 0xC0) != 0x80 ) {
480 return LDAP_INVALID_SYNTAX;
483 if( (u[4] & 0xC0) != 0x80 ) {
484 return LDAP_INVALID_SYNTAX;
487 if( (u[3] & 0xC0) != 0x80 ) {
488 return LDAP_INVALID_SYNTAX;
491 if( (u[2] & 0xC0 )!= 0x80 ) {
492 return LDAP_INVALID_SYNTAX;
495 if( (u[1] & 0xC0) != 0x80 ) {
496 return LDAP_INVALID_SYNTAX;
500 return LDAP_INVALID_SYNTAX;
504 return LDAP_INVALID_SYNTAX;
507 /* make sure len corresponds with the offset
508 to the next character */
509 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
512 if( count != 0 ) return LDAP_INVALID_SYNTAX;
521 struct berval *normalized )
528 /* Ignore initial whitespace */
529 /* All space is ASCII. All ASCII is 1 byte */
530 while ( ASCII_SPACE( *p ) ) {
535 return LDAP_INVALID_SYNTAX;
538 ber_str2bv( p, val->bv_len - (p - val->bv_val), 1, normalized );
540 assert( normalized->bv_val );
542 p = q = normalized->bv_val;
547 if ( ASCII_SPACE( *p ) ) {
552 /* Ignore the extra whitespace */
553 while ( ASCII_SPACE( *p ) ) {
557 len = LDAP_UTF8_COPY(q,p);
563 assert( normalized->bv_val < p );
564 assert( q+len <= p );
566 /* cannot start with a space */
567 assert( !ASCII_SPACE(normalized->bv_val[0]) );
570 * If the string ended in space, backup the pointer one
571 * position. One is enough because the above loop collapsed
572 * all whitespace to a single space.
580 /* cannot end with a space */
581 assert( !ASCII_SPACE( *q ) );
588 normalized->bv_len = q - normalized->bv_val;
593 /* Returns Unicode canonically normalized copy of a substring assertion
594 * Skipping attribute description */
595 static SubstringsAssertion *
596 UTF8SubstringsassertionNormalize(
597 SubstringsAssertion *sa,
600 SubstringsAssertion *nsa;
603 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
608 if( sa->sa_initial.bv_val != NULL ) {
609 ber_str2bv( UTF8normalize( &sa->sa_initial, casefold ), 0,
610 0, &nsa->sa_initial );
611 if( nsa->sa_initial.bv_val == NULL ) {
616 if( sa->sa_any != NULL ) {
617 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
620 nsa->sa_any = (struct berval *)ch_malloc( (i + 1) * sizeof(struct berval) );
621 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
622 ber_str2bv( UTF8normalize( &sa->sa_any[i], casefold ),
623 0, 0, &nsa->sa_any[i] );
624 if( nsa->sa_any[i].bv_val == NULL ) {
628 nsa->sa_any[i].bv_val = NULL;
631 if( sa->sa_final.bv_val != NULL ) {
632 ber_str2bv( UTF8normalize( &sa->sa_final, casefold ), 0,
634 if( nsa->sa_final.bv_val == NULL ) {
642 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
643 if ( nsa->sa_any )ber_bvarray_free( nsa->sa_any );
644 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
649 /* Strip characters with the 8th bit set */
662 while( *++q & 0x80 ) {
665 p = AC_MEMCPY(p, q, strlen(q) + 1);
673 #ifndef SLAPD_APPROX_OLDSINGLESTRING
675 #if defined(SLAPD_APPROX_INITIALS)
676 #define SLAPD_APPROX_DELIMITER "._ "
677 #define SLAPD_APPROX_WORDLEN 2
679 #define SLAPD_APPROX_DELIMITER " "
680 #define SLAPD_APPROX_WORDLEN 1
689 struct berval *value,
690 void *assertedValue )
692 char *val, *nval, *assertv, **values, **words, *c;
693 int i, count, len, nextchunk=0, nextavail=0;
696 /* Yes, this is necessary */
697 nval = UTF8normalize( value, LDAP_UTF8_NOCASEFOLD );
702 strip8bitChars( nval );
704 /* Yes, this is necessary */
705 assertv = UTF8normalize( ((struct berval *)assertedValue),
706 LDAP_UTF8_NOCASEFOLD );
707 if( assertv == NULL ) {
712 strip8bitChars( assertv );
713 avlen = strlen( assertv );
715 /* Isolate how many words there are */
716 for( c=nval,count=1; *c; c++ ) {
717 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
718 if ( c == NULL ) break;
723 /* Get a phonetic copy of each word */
724 words = (char **)ch_malloc( count * sizeof(char *) );
725 values = (char **)ch_malloc( count * sizeof(char *) );
726 for( c=nval,i=0; i<count; i++,c+=strlen(c)+1 ) {
728 values[i] = phonetic(c);
731 /* Work through the asserted value's words, to see if at least some
732 of the words are there, in the same order. */
734 while ( (size_t) nextchunk < avlen ) {
735 len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER);
740 #if defined(SLAPD_APPROX_INITIALS)
741 else if( len == 1 ) {
742 /* Single letter words need to at least match one word's initial */
743 for( i=nextavail; i<count; i++ )
744 if( !strncasecmp( assertv+nextchunk, words[i], 1 )) {
751 /* Isolate the next word in the asserted value and phonetic it */
752 assertv[nextchunk+len] = '\0';
753 val = phonetic( assertv + nextchunk );
755 /* See if this phonetic chunk is in the remaining words of *value */
756 for( i=nextavail; i<count; i++ ){
757 if( !strcmp( val, values[i] ) ){
765 /* This chunk in the asserted value was NOT within the *value. */
771 /* Go on to the next word in the asserted value */
775 /* If some of the words were seen, call it a match */
776 if( nextavail > 0 ) {
785 for( i=0; i<count; i++ ) {
786 ch_free( values[i] );
801 struct berval *prefix,
806 int i,j, len, wordcount, keycount=0;
807 struct berval *newkeys;
810 for( j=0; values[j].bv_val != NULL; j++ ) {
811 /* Yes, this is necessary */
812 val = UTF8normalize( &values[j], LDAP_UTF8_NOCASEFOLD );
813 strip8bitChars( val );
815 /* Isolate how many words there are. There will be a key for each */
816 for( wordcount=0,c=val; *c; c++) {
817 len = strcspn(c, SLAPD_APPROX_DELIMITER);
818 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
820 if (*c == '\0') break;
824 /* Allocate/increase storage to account for new keys */
825 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
826 * sizeof(struct berval) );
827 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
828 if( keys ) ch_free( keys );
831 /* Get a phonetic copy of each word */
832 for( c=val,i=0; i<wordcount; c+=len+1 ) {
834 if( len < SLAPD_APPROX_WORDLEN ) continue;
835 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
842 keys[keycount].bv_val = NULL;
854 struct berval *prefix,
862 /* Yes, this is necessary */
863 val = UTF8normalize( ((struct berval *)assertValue),
864 LDAP_UTF8_NOCASEFOLD );
866 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
867 keys[0].bv_val = NULL;
871 strip8bitChars( val );
873 /* Isolate how many words there are. There will be a key for each */
874 for( count=0,c=val; *c; c++) {
875 len = strcspn(c, SLAPD_APPROX_DELIMITER);
876 if( len >= SLAPD_APPROX_WORDLEN ) count++;
878 if (*c == '\0') break;
882 /* Allocate storage for new keys */
883 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
885 /* Get a phonetic copy of each word */
886 for( c=val,i=0; i<count; c+=len+1 ) {
888 if( len < SLAPD_APPROX_WORDLEN ) continue;
889 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
895 keys[count].bv_val = NULL;
903 /* No other form of Approximate Matching is defined */
911 struct berval *value,
912 void *assertedValue )
914 char *vapprox, *avapprox;
917 /* Yes, this is necessary */
918 s = UTF8normalize( value, UTF8_NOCASEFOLD );
924 /* Yes, this is necessary */
925 t = UTF8normalize( ((struct berval *)assertedValue),
933 vapprox = phonetic( strip8bitChars( s ) );
934 avapprox = phonetic( strip8bitChars( t ) );
939 *matchp = strcmp( vapprox, avapprox );
953 struct berval *prefix,
961 for( i=0; values[i].bv_val != NULL; i++ ) {
962 /* empty - just count them */
965 /* we should have at least one value at this point */
968 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
970 /* Copy each value and run it through phonetic() */
971 for( i=0; values[i].bv_val != NULL; i++ ) {
972 /* Yes, this is necessary */
973 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
975 /* strip 8-bit chars and run through phonetic() */
976 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
979 keys[i].bv_val = NULL;
992 struct berval *prefix,
999 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1001 /* Yes, this is necessary */
1002 s = UTF8normalize( ((struct berval *)assertValue),
1007 /* strip 8-bit chars and run through phonetic() */
1008 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1014 return LDAP_SUCCESS;
1025 struct berval *value,
1026 void *assertedValue )
1028 *matchp = UTF8normcmp( value->bv_val,
1029 ((struct berval *) assertedValue)->bv_val,
1030 LDAP_UTF8_NOCASEFOLD );
1031 return LDAP_SUCCESS;
1035 caseExactIgnoreSubstringsMatch(
1040 struct berval *value,
1041 void *assertedValue )
1044 SubstringsAssertion *sub = NULL;
1051 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1052 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1054 nav = UTF8normalize( value, casefold );
1060 left.bv_len = strlen( nav );
1062 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1068 /* Add up asserted input length */
1069 if( sub->sa_initial.bv_val ) {
1070 inlen += sub->sa_initial.bv_len;
1073 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1074 inlen += sub->sa_any[i].bv_len;
1077 if( sub->sa_final.bv_val ) {
1078 inlen += sub->sa_final.bv_len;
1081 if( sub->sa_initial.bv_val ) {
1082 if( inlen > left.bv_len ) {
1087 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
1088 sub->sa_initial.bv_len );
1094 left.bv_val += sub->sa_initial.bv_len;
1095 left.bv_len -= sub->sa_initial.bv_len;
1096 inlen -= sub->sa_initial.bv_len;
1099 if( sub->sa_final.bv_val ) {
1100 if( inlen > left.bv_len ) {
1105 match = strncmp( sub->sa_final.bv_val,
1106 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1107 sub->sa_final.bv_len );
1113 left.bv_len -= sub->sa_final.bv_len;
1114 inlen -= sub->sa_final.bv_len;
1118 for(i=0; sub->sa_any[i].bv_val; i++) {
1123 if( inlen > left.bv_len ) {
1124 /* not enough length */
1129 if( sub->sa_any[i].bv_len == 0 ) {
1133 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
1140 idx = p - left.bv_val;
1141 assert( idx < left.bv_len );
1143 if( idx >= left.bv_len ) {
1144 /* this shouldn't happen */
1146 if ( sub->sa_final.bv_val )
1147 ch_free( sub->sa_final.bv_val );
1149 ber_bvarray_free( sub->sa_any );
1150 if ( sub->sa_initial.bv_val )
1151 ch_free( sub->sa_initial.bv_val );
1159 if( sub->sa_any[i].bv_len > left.bv_len ) {
1160 /* not enough left */
1165 match = strncmp( left.bv_val,
1166 sub->sa_any[i].bv_val,
1167 sub->sa_any[i].bv_len );
1175 left.bv_val += sub->sa_any[i].bv_len;
1176 left.bv_len -= sub->sa_any[i].bv_len;
1177 inlen -= sub->sa_any[i].bv_len;
1184 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1185 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1186 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1190 return LDAP_SUCCESS;
1193 /* Index generation function */
1194 static int caseExactIgnoreIndexer(
1199 struct berval *prefix,
1207 HASH_CONTEXT HASHcontext;
1208 unsigned char HASHdigest[HASH_BYTES];
1209 struct berval digest;
1210 digest.bv_val = HASHdigest;
1211 digest.bv_len = sizeof(HASHdigest);
1213 for( i=0; values[i].bv_val != NULL; i++ ) {
1214 /* empty - just count them */
1217 /* we should have at least one value at this point */
1220 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1222 slen = syntax->ssyn_oidlen;
1223 mlen = mr->smr_oidlen;
1225 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1226 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1228 for( i=0; values[i].bv_val != NULL; i++ ) {
1229 struct berval value;
1230 ber_str2bv( UTF8normalize( &values[i], casefold ), 0, 0,
1233 HASH_Init( &HASHcontext );
1234 if( prefix != NULL && prefix->bv_len > 0 ) {
1235 HASH_Update( &HASHcontext,
1236 prefix->bv_val, prefix->bv_len );
1238 HASH_Update( &HASHcontext,
1239 syntax->ssyn_oid, slen );
1240 HASH_Update( &HASHcontext,
1241 mr->smr_oid, mlen );
1242 HASH_Update( &HASHcontext,
1243 value.bv_val, value.bv_len );
1244 HASH_Final( HASHdigest, &HASHcontext );
1246 free( value.bv_val );
1248 ber_dupbv( &keys[i], &digest );
1251 keys[i].bv_val = NULL;
1253 return LDAP_SUCCESS;
1256 /* Index generation function */
1257 static int caseExactIgnoreFilter(
1262 struct berval *prefix,
1269 HASH_CONTEXT HASHcontext;
1270 unsigned char HASHdigest[HASH_BYTES];
1271 struct berval value;
1272 struct berval digest;
1273 digest.bv_val = HASHdigest;
1274 digest.bv_len = sizeof(HASHdigest);
1276 slen = syntax->ssyn_oidlen;
1277 mlen = mr->smr_oidlen;
1279 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1280 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1282 ber_str2bv( UTF8normalize( ((struct berval *) assertValue), casefold ),
1284 /* This usually happens if filter contains bad UTF8 */
1285 if( value.bv_val == NULL ) {
1286 keys = ch_malloc( sizeof( struct berval ) );
1287 keys[0].bv_val = NULL;
1288 return LDAP_SUCCESS;
1291 keys = ch_malloc( sizeof( struct berval ) * 2 );
1293 HASH_Init( &HASHcontext );
1294 if( prefix != NULL && prefix->bv_len > 0 ) {
1295 HASH_Update( &HASHcontext,
1296 prefix->bv_val, prefix->bv_len );
1298 HASH_Update( &HASHcontext,
1299 syntax->ssyn_oid, slen );
1300 HASH_Update( &HASHcontext,
1301 mr->smr_oid, mlen );
1302 HASH_Update( &HASHcontext,
1303 value.bv_val, value.bv_len );
1304 HASH_Final( HASHdigest, &HASHcontext );
1306 ber_dupbv( keys, &digest );
1307 keys[1].bv_val = NULL;
1309 free( value.bv_val );
1312 return LDAP_SUCCESS;
1315 /* Substrings Index generation function */
1316 static int caseExactIgnoreSubstringsIndexer(
1321 struct berval *prefix,
1331 HASH_CONTEXT HASHcontext;
1332 unsigned char HASHdigest[HASH_BYTES];
1333 struct berval digest;
1334 digest.bv_val = HASHdigest;
1335 digest.bv_len = sizeof(HASHdigest);
1339 for( i=0; values[i].bv_val != NULL; i++ ) {
1340 /* empty - just count them */
1343 /* we should have at least one value at this point */
1346 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1347 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1349 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1350 for( i=0; values[i].bv_val != NULL; i++ ) {
1351 ber_str2bv( UTF8normalize( &values[i], casefold ),
1352 0, 0, &nvalues[i] );
1354 nvalues[i].bv_val = NULL;
1357 for( i=0; values[i].bv_val != NULL; i++ ) {
1358 /* count number of indices to generate */
1359 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1363 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1364 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1365 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1366 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1368 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1372 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1373 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1374 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1378 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1379 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1380 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1381 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1383 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1389 /* no keys to generate */
1391 ber_bvarray_free( nvalues );
1392 return LDAP_SUCCESS;
1395 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1397 slen = syntax->ssyn_oidlen;
1398 mlen = mr->smr_oidlen;
1401 for( i=0; values[i].bv_val != NULL; i++ ) {
1404 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1406 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1407 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1409 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1410 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1412 for( j=0; j<max; j++ ) {
1413 HASH_Init( &HASHcontext );
1414 if( prefix != NULL && prefix->bv_len > 0 ) {
1415 HASH_Update( &HASHcontext,
1416 prefix->bv_val, prefix->bv_len );
1419 HASH_Update( &HASHcontext,
1420 &pre, sizeof( pre ) );
1421 HASH_Update( &HASHcontext,
1422 syntax->ssyn_oid, slen );
1423 HASH_Update( &HASHcontext,
1424 mr->smr_oid, mlen );
1425 HASH_Update( &HASHcontext,
1426 &values[i].bv_val[j],
1427 SLAP_INDEX_SUBSTR_MAXLEN );
1428 HASH_Final( HASHdigest, &HASHcontext );
1430 ber_dupbv( &keys[nkeys++], &digest );
1434 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1435 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1437 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1440 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1441 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1442 HASH_Init( &HASHcontext );
1443 if( prefix != NULL && prefix->bv_len > 0 ) {
1444 HASH_Update( &HASHcontext,
1445 prefix->bv_val, prefix->bv_len );
1447 HASH_Update( &HASHcontext,
1448 &pre, sizeof( pre ) );
1449 HASH_Update( &HASHcontext,
1450 syntax->ssyn_oid, slen );
1451 HASH_Update( &HASHcontext,
1452 mr->smr_oid, mlen );
1453 HASH_Update( &HASHcontext,
1454 values[i].bv_val, j );
1455 HASH_Final( HASHdigest, &HASHcontext );
1457 ber_dupbv( &keys[nkeys++], &digest );
1460 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1461 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1462 HASH_Init( &HASHcontext );
1463 if( prefix != NULL && prefix->bv_len > 0 ) {
1464 HASH_Update( &HASHcontext,
1465 prefix->bv_val, prefix->bv_len );
1467 HASH_Update( &HASHcontext,
1468 &pre, sizeof( pre ) );
1469 HASH_Update( &HASHcontext,
1470 syntax->ssyn_oid, slen );
1471 HASH_Update( &HASHcontext,
1472 mr->smr_oid, mlen );
1473 HASH_Update( &HASHcontext,
1474 &values[i].bv_val[values[i].bv_len-j], j );
1475 HASH_Final( HASHdigest, &HASHcontext );
1477 ber_dupbv( &keys[nkeys++], &digest );
1485 keys[nkeys].bv_val = NULL;
1492 ber_bvarray_free( nvalues );
1494 return LDAP_SUCCESS;
1497 static int caseExactIgnoreSubstringsFilter(
1502 struct berval *prefix,
1506 SubstringsAssertion *sa;
1509 ber_len_t nkeys = 0;
1510 size_t slen, mlen, klen;
1512 HASH_CONTEXT HASHcontext;
1513 unsigned char HASHdigest[HASH_BYTES];
1514 struct berval *value;
1515 struct berval digest;
1517 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1518 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1520 sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
1523 return LDAP_SUCCESS;
1526 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1527 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1532 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1534 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1535 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1536 /* don't bother accounting for stepping */
1537 nkeys += sa->sa_any[i].bv_len -
1538 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1543 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1544 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1550 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1551 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1552 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1555 return LDAP_SUCCESS;
1558 digest.bv_val = HASHdigest;
1559 digest.bv_len = sizeof(HASHdigest);
1561 slen = syntax->ssyn_oidlen;
1562 mlen = mr->smr_oidlen;
1564 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1567 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1568 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1570 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1571 value = &sa->sa_initial;
1573 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1574 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1576 HASH_Init( &HASHcontext );
1577 if( prefix != NULL && prefix->bv_len > 0 ) {
1578 HASH_Update( &HASHcontext,
1579 prefix->bv_val, prefix->bv_len );
1581 HASH_Update( &HASHcontext,
1582 &pre, sizeof( pre ) );
1583 HASH_Update( &HASHcontext,
1584 syntax->ssyn_oid, slen );
1585 HASH_Update( &HASHcontext,
1586 mr->smr_oid, mlen );
1587 HASH_Update( &HASHcontext,
1588 value->bv_val, klen );
1589 HASH_Final( HASHdigest, &HASHcontext );
1591 ber_dupbv( &keys[nkeys++], &digest );
1594 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1596 pre = SLAP_INDEX_SUBSTR_PREFIX;
1597 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1599 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1600 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1604 value = &sa->sa_any[i];
1607 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1608 j += SLAP_INDEX_SUBSTR_STEP )
1610 HASH_Init( &HASHcontext );
1611 if( prefix != NULL && prefix->bv_len > 0 ) {
1612 HASH_Update( &HASHcontext,
1613 prefix->bv_val, prefix->bv_len );
1615 HASH_Update( &HASHcontext,
1616 &pre, sizeof( pre ) );
1617 HASH_Update( &HASHcontext,
1618 syntax->ssyn_oid, slen );
1619 HASH_Update( &HASHcontext,
1620 mr->smr_oid, mlen );
1621 HASH_Update( &HASHcontext,
1622 &value->bv_val[j], klen );
1623 HASH_Final( HASHdigest, &HASHcontext );
1625 ber_dupbv( &keys[nkeys++], &digest );
1631 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1632 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1634 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1635 value = &sa->sa_final;
1637 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1638 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1640 HASH_Init( &HASHcontext );
1641 if( prefix != NULL && prefix->bv_len > 0 ) {
1642 HASH_Update( &HASHcontext,
1643 prefix->bv_val, prefix->bv_len );
1645 HASH_Update( &HASHcontext,
1646 &pre, sizeof( pre ) );
1647 HASH_Update( &HASHcontext,
1648 syntax->ssyn_oid, slen );
1649 HASH_Update( &HASHcontext,
1650 mr->smr_oid, mlen );
1651 HASH_Update( &HASHcontext,
1652 &value->bv_val[value->bv_len-klen], klen );
1653 HASH_Final( HASHdigest, &HASHcontext );
1655 ber_dupbv( &keys[nkeys++], &digest );
1659 keys[nkeys].bv_val = NULL;
1665 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1666 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1667 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1670 return LDAP_SUCCESS;
1679 struct berval *value,
1680 void *assertedValue )
1682 *matchp = UTF8normcmp( value->bv_val,
1683 ((struct berval *) assertedValue)->bv_val,
1684 LDAP_UTF8_CASEFOLD );
1685 return LDAP_SUCCESS;
1691 struct berval *val )
1695 if( val->bv_len == 0 ) {
1696 /* disallow empty strings */
1697 return LDAP_INVALID_SYNTAX;
1700 if( OID_LEADCHAR(val->bv_val[0]) ) {
1702 for(i=1; i < val->bv_len; i++) {
1703 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1704 if( dot++ ) return 1;
1705 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1708 return LDAP_INVALID_SYNTAX;
1712 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1714 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1715 for(i=1; i < val->bv_len; i++) {
1716 if( !DESC_CHAR(val->bv_val[i] ) ) {
1717 return LDAP_INVALID_SYNTAX;
1721 return LDAP_SUCCESS;
1724 return LDAP_INVALID_SYNTAX;
1733 struct berval *value,
1734 void *assertedValue )
1737 int vsign=0, avsign=0;
1738 struct berval *asserted;
1739 ber_len_t vlen, avlen;
1742 /* Start off pessimistic */
1745 /* Skip past leading spaces/zeros, and get the sign of the *value number */
1747 vlen = value->bv_len;
1749 if( ASCII_SPACE(*v) || ( *v == '0' )) {
1750 /* empty -- skip spaces */
1752 else if ( *v == '+' ) {
1755 else if ( *v == '-' ) {
1758 else if ( ASCII_DIGIT(*v) ) {
1759 if ( vsign == 0 ) vsign = 1;
1767 /* Skip past leading spaces/zeros, and get the sign of the *assertedValue
1769 asserted = (struct berval *) assertedValue;
1770 av = asserted->bv_val;
1771 avlen = asserted->bv_len;
1773 if( ASCII_SPACE(*av) || ( *av == '0' )) {
1774 /* empty -- skip spaces */
1776 else if ( *av == '+' ) {
1779 else if ( *av == '-' ) {
1782 else if ( ASCII_DIGIT(*av) ) {
1783 if ( avsign == 0 ) avsign = 1;
1791 /* The two ?sign vars are now one of :
1792 -2 negative non-zero number
1794 0 0 collapse these three to 0
1796 +2 positive non-zero number
1798 if ( abs( vsign ) == 1 ) vsign = 0;
1799 if ( abs( avsign ) == 1 ) avsign = 0;
1801 if( vsign != avsign ) return LDAP_SUCCESS;
1803 /* Check the significant digits */
1804 while( vlen && avlen ) {
1805 if( *v != *av ) break;
1812 /* If all digits compared equal, the numbers are equal */
1813 if(( vlen == 0 ) && ( avlen == 0 )) {
1816 return LDAP_SUCCESS;
1822 struct berval *val )
1826 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1828 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
1829 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1830 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1831 return LDAP_INVALID_SYNTAX;
1834 for( i=1; i < val->bv_len; i++ ) {
1835 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1838 return LDAP_SUCCESS;
1845 struct berval *normalized )
1855 /* Ignore leading spaces */
1856 while ( len && ( *p == ' ' )) {
1863 negative = ( *p == '-' );
1864 if(( *p == '-' ) || ( *p == '+' )) {
1870 /* Ignore leading zeros */
1871 while ( len && ( *p == '0' )) {
1876 /* If there are no non-zero digits left, the number is zero, otherwise
1877 allocate space for the number and copy it into the buffer */
1879 normalized->bv_val = ch_strdup("0");
1880 normalized->bv_len = 1;
1883 normalized->bv_len = len+negative;
1884 normalized->bv_val = ch_malloc( normalized->bv_len );
1886 normalized->bv_val[0] = '-';
1888 AC_MEMCPY( normalized->bv_val + negative, p, len );
1891 return LDAP_SUCCESS;
1894 /* Index generation function */
1895 static int integerIndexer(
1900 struct berval *prefix,
1907 /* we should have at least one value at this point */
1908 assert( values != NULL && values[0].bv_val != NULL );
1910 for( i=0; values[i].bv_val != NULL; i++ ) {
1911 /* empty -- just count them */
1914 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1916 for( i=0; values[i].bv_val != NULL; i++ ) {
1917 integerNormalize( syntax, &values[i], &keys[i] );
1920 keys[i].bv_val = NULL;
1922 return LDAP_SUCCESS;
1925 /* Index generation function */
1926 static int integerFilter(
1931 struct berval *prefix,
1937 keys = ch_malloc( sizeof( struct berval ) * 2 );
1938 integerNormalize( syntax, assertValue, &keys[0] );
1939 keys[1].bv_val = NULL;
1942 return LDAP_SUCCESS;
1947 countryStringValidate(
1949 struct berval *val )
1951 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
1953 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
1954 return LDAP_INVALID_SYNTAX;
1956 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
1957 return LDAP_INVALID_SYNTAX;
1960 return LDAP_SUCCESS;
1964 printableStringValidate(
1966 struct berval *val )
1970 for(i=0; i < val->bv_len; i++) {
1971 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
1972 return LDAP_INVALID_SYNTAX;
1976 return LDAP_SUCCESS;
1980 printablesStringValidate(
1982 struct berval *val )
1986 for(i=0; i < val->bv_len; i++) {
1987 if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
1988 return LDAP_INVALID_SYNTAX;
1992 return LDAP_SUCCESS;
1998 struct berval *val )
2002 for(i=0; i < val->bv_len; i++) {
2003 if( !LDAP_ASCII(val->bv_val[i]) ) {
2004 return LDAP_INVALID_SYNTAX;
2008 return LDAP_SUCCESS;
2015 struct berval *normalized )
2021 /* Ignore initial whitespace */
2022 while ( ASCII_SPACE( *p ) ) {
2026 normalized->bv_val = ch_strdup( p );
2027 p = q = normalized->bv_val;
2030 if ( ASCII_SPACE( *p ) ) {
2033 /* Ignore the extra whitespace */
2034 while ( ASCII_SPACE( *p ) ) {
2042 assert( normalized->bv_val <= p );
2046 * If the string ended in space, backup the pointer one
2047 * position. One is enough because the above loop collapsed
2048 * all whitespace to a single space.
2051 if ( ASCII_SPACE( q[-1] ) ) {
2055 /* null terminate */
2058 normalized->bv_len = q - normalized->bv_val;
2060 return LDAP_SUCCESS;
2069 struct berval *value,
2070 void *assertedValue )
2072 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2075 match = strncmp( value->bv_val,
2076 ((struct berval *) assertedValue)->bv_val,
2081 return LDAP_SUCCESS;
2085 caseExactIA5SubstringsMatch(
2090 struct berval *value,
2091 void *assertedValue )
2094 SubstringsAssertion *sub = assertedValue;
2095 struct berval left = *value;
2099 /* Add up asserted input length */
2100 if( sub->sa_initial.bv_val ) {
2101 inlen += sub->sa_initial.bv_len;
2104 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2105 inlen += sub->sa_any[i].bv_len;
2108 if( sub->sa_final.bv_val ) {
2109 inlen += sub->sa_final.bv_len;
2112 if( sub->sa_initial.bv_val ) {
2113 if( inlen > left.bv_len ) {
2118 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
2119 sub->sa_initial.bv_len );
2125 left.bv_val += sub->sa_initial.bv_len;
2126 left.bv_len -= sub->sa_initial.bv_len;
2127 inlen -= sub->sa_initial.bv_len;
2130 if( sub->sa_final.bv_val ) {
2131 if( inlen > left.bv_len ) {
2136 match = strncmp( sub->sa_final.bv_val,
2137 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2138 sub->sa_final.bv_len );
2144 left.bv_len -= sub->sa_final.bv_len;
2145 inlen -= sub->sa_final.bv_len;
2149 for(i=0; sub->sa_any[i].bv_val; i++) {
2154 if( inlen > left.bv_len ) {
2155 /* not enough length */
2160 if( sub->sa_any[i].bv_len == 0 ) {
2164 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
2171 idx = p - left.bv_val;
2172 assert( idx < left.bv_len );
2174 if( idx >= left.bv_len ) {
2175 /* this shouldn't happen */
2182 if( sub->sa_any[i].bv_len > left.bv_len ) {
2183 /* not enough left */
2188 match = strncmp( left.bv_val,
2189 sub->sa_any[i].bv_val,
2190 sub->sa_any[i].bv_len );
2198 left.bv_val += sub->sa_any[i].bv_len;
2199 left.bv_len -= sub->sa_any[i].bv_len;
2200 inlen -= sub->sa_any[i].bv_len;
2206 return LDAP_SUCCESS;
2209 /* Index generation function */
2210 static int caseExactIA5Indexer(
2215 struct berval *prefix,
2222 HASH_CONTEXT HASHcontext;
2223 unsigned char HASHdigest[HASH_BYTES];
2224 struct berval digest;
2225 digest.bv_val = HASHdigest;
2226 digest.bv_len = sizeof(HASHdigest);
2228 for( i=0; values[i].bv_val != NULL; i++ ) {
2229 /* empty - just count them */
2232 /* we should have at least one value at this point */
2235 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2237 slen = syntax->ssyn_oidlen;
2238 mlen = mr->smr_oidlen;
2240 for( i=0; values[i].bv_val != NULL; i++ ) {
2241 struct berval *value = &values[i];
2243 HASH_Init( &HASHcontext );
2244 if( prefix != NULL && prefix->bv_len > 0 ) {
2245 HASH_Update( &HASHcontext,
2246 prefix->bv_val, prefix->bv_len );
2248 HASH_Update( &HASHcontext,
2249 syntax->ssyn_oid, slen );
2250 HASH_Update( &HASHcontext,
2251 mr->smr_oid, mlen );
2252 HASH_Update( &HASHcontext,
2253 value->bv_val, value->bv_len );
2254 HASH_Final( HASHdigest, &HASHcontext );
2256 ber_dupbv( &keys[i], &digest );
2259 keys[i].bv_val = NULL;
2261 return LDAP_SUCCESS;
2264 /* Index generation function */
2265 static int caseExactIA5Filter(
2270 struct berval *prefix,
2276 HASH_CONTEXT HASHcontext;
2277 unsigned char HASHdigest[HASH_BYTES];
2278 struct berval *value;
2279 struct berval digest;
2280 digest.bv_val = HASHdigest;
2281 digest.bv_len = sizeof(HASHdigest);
2283 slen = syntax->ssyn_oidlen;
2284 mlen = mr->smr_oidlen;
2286 value = (struct berval *) assertValue;
2288 keys = ch_malloc( sizeof( struct berval ) * 2 );
2290 HASH_Init( &HASHcontext );
2291 if( prefix != NULL && prefix->bv_len > 0 ) {
2292 HASH_Update( &HASHcontext,
2293 prefix->bv_val, prefix->bv_len );
2295 HASH_Update( &HASHcontext,
2296 syntax->ssyn_oid, slen );
2297 HASH_Update( &HASHcontext,
2298 mr->smr_oid, mlen );
2299 HASH_Update( &HASHcontext,
2300 value->bv_val, value->bv_len );
2301 HASH_Final( HASHdigest, &HASHcontext );
2303 ber_dupbv( &keys[0], &digest );
2304 keys[1].bv_val = NULL;
2307 return LDAP_SUCCESS;
2310 /* Substrings Index generation function */
2311 static int caseExactIA5SubstringsIndexer(
2316 struct berval *prefix,
2323 HASH_CONTEXT HASHcontext;
2324 unsigned char HASHdigest[HASH_BYTES];
2325 struct berval digest;
2326 digest.bv_val = HASHdigest;
2327 digest.bv_len = sizeof(HASHdigest);
2329 /* we should have at least one value at this point */
2330 assert( values != NULL && values[0].bv_val != NULL );
2333 for( i=0; values[i].bv_val != NULL; i++ ) {
2334 /* count number of indices to generate */
2335 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2339 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2340 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2341 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2342 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2344 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2348 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2349 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2350 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2354 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2355 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2356 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2357 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2359 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2365 /* no keys to generate */
2367 return LDAP_SUCCESS;
2370 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2372 slen = syntax->ssyn_oidlen;
2373 mlen = mr->smr_oidlen;
2376 for( i=0; values[i].bv_val != NULL; i++ ) {
2378 struct berval *value;
2381 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2383 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2384 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2386 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2387 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2389 for( j=0; j<max; j++ ) {
2390 HASH_Init( &HASHcontext );
2391 if( prefix != NULL && prefix->bv_len > 0 ) {
2392 HASH_Update( &HASHcontext,
2393 prefix->bv_val, prefix->bv_len );
2396 HASH_Update( &HASHcontext,
2397 &pre, sizeof( pre ) );
2398 HASH_Update( &HASHcontext,
2399 syntax->ssyn_oid, slen );
2400 HASH_Update( &HASHcontext,
2401 mr->smr_oid, mlen );
2402 HASH_Update( &HASHcontext,
2404 SLAP_INDEX_SUBSTR_MAXLEN );
2405 HASH_Final( HASHdigest, &HASHcontext );
2407 ber_dupbv( &keys[nkeys++], &digest );
2411 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2412 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2414 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2417 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2418 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2419 HASH_Init( &HASHcontext );
2420 if( prefix != NULL && prefix->bv_len > 0 ) {
2421 HASH_Update( &HASHcontext,
2422 prefix->bv_val, prefix->bv_len );
2424 HASH_Update( &HASHcontext,
2425 &pre, sizeof( pre ) );
2426 HASH_Update( &HASHcontext,
2427 syntax->ssyn_oid, slen );
2428 HASH_Update( &HASHcontext,
2429 mr->smr_oid, mlen );
2430 HASH_Update( &HASHcontext,
2432 HASH_Final( HASHdigest, &HASHcontext );
2434 ber_dupbv( &keys[nkeys++], &digest );
2437 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2438 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2439 HASH_Init( &HASHcontext );
2440 if( prefix != NULL && prefix->bv_len > 0 ) {
2441 HASH_Update( &HASHcontext,
2442 prefix->bv_val, prefix->bv_len );
2444 HASH_Update( &HASHcontext,
2445 &pre, sizeof( pre ) );
2446 HASH_Update( &HASHcontext,
2447 syntax->ssyn_oid, slen );
2448 HASH_Update( &HASHcontext,
2449 mr->smr_oid, mlen );
2450 HASH_Update( &HASHcontext,
2451 &value->bv_val[value->bv_len-j], j );
2452 HASH_Final( HASHdigest, &HASHcontext );
2454 ber_dupbv( &keys[nkeys++], &digest );
2461 keys[nkeys].bv_val = NULL;
2468 return LDAP_SUCCESS;
2471 static int caseExactIA5SubstringsFilter(
2476 struct berval *prefix,
2480 SubstringsAssertion *sa = assertValue;
2482 ber_len_t nkeys = 0;
2483 size_t slen, mlen, klen;
2485 HASH_CONTEXT HASHcontext;
2486 unsigned char HASHdigest[HASH_BYTES];
2487 struct berval *value;
2488 struct berval digest;
2490 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2491 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2496 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2498 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2499 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2500 /* don't bother accounting for stepping */
2501 nkeys += sa->sa_any[i].bv_len -
2502 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2507 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2508 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2515 return LDAP_SUCCESS;
2518 digest.bv_val = HASHdigest;
2519 digest.bv_len = sizeof(HASHdigest);
2521 slen = syntax->ssyn_oidlen;
2522 mlen = mr->smr_oidlen;
2524 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2527 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2528 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2530 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2531 value = &sa->sa_initial;
2533 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2534 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2536 HASH_Init( &HASHcontext );
2537 if( prefix != NULL && prefix->bv_len > 0 ) {
2538 HASH_Update( &HASHcontext,
2539 prefix->bv_val, prefix->bv_len );
2541 HASH_Update( &HASHcontext,
2542 &pre, sizeof( pre ) );
2543 HASH_Update( &HASHcontext,
2544 syntax->ssyn_oid, slen );
2545 HASH_Update( &HASHcontext,
2546 mr->smr_oid, mlen );
2547 HASH_Update( &HASHcontext,
2548 value->bv_val, klen );
2549 HASH_Final( HASHdigest, &HASHcontext );
2551 ber_dupbv( &keys[nkeys++], &digest );
2554 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2556 pre = SLAP_INDEX_SUBSTR_PREFIX;
2557 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2559 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2560 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2564 value = &sa->sa_any[i];
2567 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2568 j += SLAP_INDEX_SUBSTR_STEP )
2570 HASH_Init( &HASHcontext );
2571 if( prefix != NULL && prefix->bv_len > 0 ) {
2572 HASH_Update( &HASHcontext,
2573 prefix->bv_val, prefix->bv_len );
2575 HASH_Update( &HASHcontext,
2576 &pre, sizeof( pre ) );
2577 HASH_Update( &HASHcontext,
2578 syntax->ssyn_oid, slen );
2579 HASH_Update( &HASHcontext,
2580 mr->smr_oid, mlen );
2581 HASH_Update( &HASHcontext,
2582 &value->bv_val[j], klen );
2583 HASH_Final( HASHdigest, &HASHcontext );
2585 ber_dupbv( &keys[nkeys++], &digest );
2590 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2591 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2593 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2594 value = &sa->sa_final;
2596 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2597 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2599 HASH_Init( &HASHcontext );
2600 if( prefix != NULL && prefix->bv_len > 0 ) {
2601 HASH_Update( &HASHcontext,
2602 prefix->bv_val, prefix->bv_len );
2604 HASH_Update( &HASHcontext,
2605 &pre, sizeof( pre ) );
2606 HASH_Update( &HASHcontext,
2607 syntax->ssyn_oid, slen );
2608 HASH_Update( &HASHcontext,
2609 mr->smr_oid, mlen );
2610 HASH_Update( &HASHcontext,
2611 &value->bv_val[value->bv_len-klen], klen );
2612 HASH_Final( HASHdigest, &HASHcontext );
2614 ber_dupbv( &keys[nkeys++], &digest );
2618 keys[nkeys].bv_val = NULL;
2625 return LDAP_SUCCESS;
2634 struct berval *value,
2635 void *assertedValue )
2637 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2639 if( match == 0 && value->bv_len ) {
2640 match = strncasecmp( value->bv_val,
2641 ((struct berval *) assertedValue)->bv_val,
2646 return LDAP_SUCCESS;
2650 caseIgnoreIA5SubstringsMatch(
2655 struct berval *value,
2656 void *assertedValue )
2659 SubstringsAssertion *sub = assertedValue;
2660 struct berval left = *value;
2664 /* Add up asserted input length */
2665 if( sub->sa_initial.bv_val ) {
2666 inlen += sub->sa_initial.bv_len;
2669 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2670 inlen += sub->sa_any[i].bv_len;
2673 if( sub->sa_final.bv_val ) {
2674 inlen += sub->sa_final.bv_len;
2677 if( sub->sa_initial.bv_val ) {
2678 if( inlen > left.bv_len ) {
2683 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
2684 sub->sa_initial.bv_len );
2690 left.bv_val += sub->sa_initial.bv_len;
2691 left.bv_len -= sub->sa_initial.bv_len;
2692 inlen -= sub->sa_initial.bv_len;
2695 if( sub->sa_final.bv_val ) {
2696 if( inlen > left.bv_len ) {
2701 match = strncasecmp( sub->sa_final.bv_val,
2702 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2703 sub->sa_final.bv_len );
2709 left.bv_len -= sub->sa_final.bv_len;
2710 inlen -= sub->sa_final.bv_len;
2714 for(i=0; sub->sa_any[i].bv_val; i++) {
2719 if( inlen > left.bv_len ) {
2720 /* not enough length */
2725 if( sub->sa_any[i].bv_len == 0 ) {
2729 p = strcasechr( left.bv_val, *sub->sa_any[i].bv_val );
2736 idx = p - left.bv_val;
2737 assert( idx < left.bv_len );
2739 if( idx >= left.bv_len ) {
2740 /* this shouldn't happen */
2747 if( sub->sa_any[i].bv_len > left.bv_len ) {
2748 /* not enough left */
2753 match = strncasecmp( left.bv_val,
2754 sub->sa_any[i].bv_val,
2755 sub->sa_any[i].bv_len );
2764 left.bv_val += sub->sa_any[i].bv_len;
2765 left.bv_len -= sub->sa_any[i].bv_len;
2766 inlen -= sub->sa_any[i].bv_len;
2772 return LDAP_SUCCESS;
2775 /* Index generation function */
2776 static int caseIgnoreIA5Indexer(
2781 struct berval *prefix,
2788 HASH_CONTEXT HASHcontext;
2789 unsigned char HASHdigest[HASH_BYTES];
2790 struct berval digest;
2791 digest.bv_val = HASHdigest;
2792 digest.bv_len = sizeof(HASHdigest);
2794 /* we should have at least one value at this point */
2795 assert( values != NULL && values[0].bv_val != NULL );
2797 for( i=0; values[i].bv_val != NULL; i++ ) {
2798 /* just count them */
2801 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2803 slen = syntax->ssyn_oidlen;
2804 mlen = mr->smr_oidlen;
2806 for( i=0; values[i].bv_val != NULL; i++ ) {
2807 struct berval value;
2808 ber_dupbv( &value, &values[i] );
2809 ldap_pvt_str2upper( value.bv_val );
2811 HASH_Init( &HASHcontext );
2812 if( prefix != NULL && prefix->bv_len > 0 ) {
2813 HASH_Update( &HASHcontext,
2814 prefix->bv_val, prefix->bv_len );
2816 HASH_Update( &HASHcontext,
2817 syntax->ssyn_oid, slen );
2818 HASH_Update( &HASHcontext,
2819 mr->smr_oid, mlen );
2820 HASH_Update( &HASHcontext,
2821 value.bv_val, value.bv_len );
2822 HASH_Final( HASHdigest, &HASHcontext );
2824 free( value.bv_val );
2826 ber_dupbv( &keys[i], &digest );
2829 keys[i].bv_val = NULL;
2831 return LDAP_SUCCESS;
2834 /* Index generation function */
2835 static int caseIgnoreIA5Filter(
2840 struct berval *prefix,
2846 HASH_CONTEXT HASHcontext;
2847 unsigned char HASHdigest[HASH_BYTES];
2848 struct berval value;
2849 struct berval digest;
2850 digest.bv_val = HASHdigest;
2851 digest.bv_len = sizeof(HASHdigest);
2853 slen = syntax->ssyn_oidlen;
2854 mlen = mr->smr_oidlen;
2856 ber_dupbv( &value, (struct berval *) assertValue );
2857 ldap_pvt_str2upper( value.bv_val );
2859 keys = ch_malloc( sizeof( struct berval ) * 2 );
2861 HASH_Init( &HASHcontext );
2862 if( prefix != NULL && prefix->bv_len > 0 ) {
2863 HASH_Update( &HASHcontext,
2864 prefix->bv_val, prefix->bv_len );
2866 HASH_Update( &HASHcontext,
2867 syntax->ssyn_oid, slen );
2868 HASH_Update( &HASHcontext,
2869 mr->smr_oid, mlen );
2870 HASH_Update( &HASHcontext,
2871 value.bv_val, value.bv_len );
2872 HASH_Final( HASHdigest, &HASHcontext );
2874 ber_dupbv( &keys[0], &digest );
2875 keys[1].bv_val = NULL;
2877 free( value.bv_val );
2881 return LDAP_SUCCESS;
2884 /* Substrings Index generation function */
2885 static int caseIgnoreIA5SubstringsIndexer(
2890 struct berval *prefix,
2897 HASH_CONTEXT HASHcontext;
2898 unsigned char HASHdigest[HASH_BYTES];
2899 struct berval digest;
2900 digest.bv_val = HASHdigest;
2901 digest.bv_len = sizeof(HASHdigest);
2903 /* we should have at least one value at this point */
2904 assert( values != NULL && values[0].bv_val != NULL );
2907 for( i=0; values[i].bv_val != NULL; i++ ) {
2908 /* count number of indices to generate */
2909 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2913 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2914 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2915 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2916 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2918 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2922 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2923 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2924 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2928 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2929 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2930 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2931 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2933 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2939 /* no keys to generate */
2941 return LDAP_SUCCESS;
2944 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2946 slen = syntax->ssyn_oidlen;
2947 mlen = mr->smr_oidlen;
2950 for( i=0; values[i].bv_val != NULL; i++ ) {
2952 struct berval value;
2954 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2956 ber_dupbv( &value, &values[i] );
2957 ldap_pvt_str2upper( value.bv_val );
2959 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2960 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2962 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2963 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2965 for( j=0; j<max; j++ ) {
2966 HASH_Init( &HASHcontext );
2967 if( prefix != NULL && prefix->bv_len > 0 ) {
2968 HASH_Update( &HASHcontext,
2969 prefix->bv_val, prefix->bv_len );
2972 HASH_Update( &HASHcontext,
2973 &pre, sizeof( pre ) );
2974 HASH_Update( &HASHcontext,
2975 syntax->ssyn_oid, slen );
2976 HASH_Update( &HASHcontext,
2977 mr->smr_oid, mlen );
2978 HASH_Update( &HASHcontext,
2980 SLAP_INDEX_SUBSTR_MAXLEN );
2981 HASH_Final( HASHdigest, &HASHcontext );
2983 ber_dupbv( &keys[nkeys++], &digest );
2987 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
2988 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
2990 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2993 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2994 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2995 HASH_Init( &HASHcontext );
2996 if( prefix != NULL && prefix->bv_len > 0 ) {
2997 HASH_Update( &HASHcontext,
2998 prefix->bv_val, prefix->bv_len );
3000 HASH_Update( &HASHcontext,
3001 &pre, sizeof( pre ) );
3002 HASH_Update( &HASHcontext,
3003 syntax->ssyn_oid, slen );
3004 HASH_Update( &HASHcontext,
3005 mr->smr_oid, mlen );
3006 HASH_Update( &HASHcontext,
3008 HASH_Final( HASHdigest, &HASHcontext );
3010 ber_dupbv( &keys[nkeys++], &digest );
3013 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3014 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3015 HASH_Init( &HASHcontext );
3016 if( prefix != NULL && prefix->bv_len > 0 ) {
3017 HASH_Update( &HASHcontext,
3018 prefix->bv_val, prefix->bv_len );
3020 HASH_Update( &HASHcontext,
3021 &pre, sizeof( pre ) );
3022 HASH_Update( &HASHcontext,
3023 syntax->ssyn_oid, slen );
3024 HASH_Update( &HASHcontext,
3025 mr->smr_oid, mlen );
3026 HASH_Update( &HASHcontext,
3027 &value.bv_val[value.bv_len-j], j );
3028 HASH_Final( HASHdigest, &HASHcontext );
3030 ber_dupbv( &keys[nkeys++], &digest );
3035 free( value.bv_val );
3039 keys[nkeys].bv_val = NULL;
3046 return LDAP_SUCCESS;
3049 static int caseIgnoreIA5SubstringsFilter(
3054 struct berval *prefix,
3058 SubstringsAssertion *sa = assertValue;
3060 ber_len_t nkeys = 0;
3061 size_t slen, mlen, klen;
3063 HASH_CONTEXT HASHcontext;
3064 unsigned char HASHdigest[HASH_BYTES];
3065 struct berval value;
3066 struct berval digest;
3068 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3069 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3074 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3076 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3077 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3078 /* don't bother accounting for stepping */
3079 nkeys += sa->sa_any[i].bv_len -
3080 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3085 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3086 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3093 return LDAP_SUCCESS;
3096 digest.bv_val = HASHdigest;
3097 digest.bv_len = sizeof(HASHdigest);
3099 slen = syntax->ssyn_oidlen;
3100 mlen = mr->smr_oidlen;
3102 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3105 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3106 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3108 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3109 ber_dupbv( &value, &sa->sa_initial );
3110 ldap_pvt_str2upper( value.bv_val );
3112 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3113 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3115 HASH_Init( &HASHcontext );
3116 if( prefix != NULL && prefix->bv_len > 0 ) {
3117 HASH_Update( &HASHcontext,
3118 prefix->bv_val, prefix->bv_len );
3120 HASH_Update( &HASHcontext,
3121 &pre, sizeof( pre ) );
3122 HASH_Update( &HASHcontext,
3123 syntax->ssyn_oid, slen );
3124 HASH_Update( &HASHcontext,
3125 mr->smr_oid, mlen );
3126 HASH_Update( &HASHcontext,
3127 value.bv_val, klen );
3128 HASH_Final( HASHdigest, &HASHcontext );
3130 free( value.bv_val );
3131 ber_dupbv( &keys[nkeys++], &digest );
3134 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3136 pre = SLAP_INDEX_SUBSTR_PREFIX;
3137 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3139 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3140 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3144 ber_dupbv( &value, &sa->sa_any[i] );
3145 ldap_pvt_str2upper( value.bv_val );
3148 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3149 j += SLAP_INDEX_SUBSTR_STEP )
3151 HASH_Init( &HASHcontext );
3152 if( prefix != NULL && prefix->bv_len > 0 ) {
3153 HASH_Update( &HASHcontext,
3154 prefix->bv_val, prefix->bv_len );
3156 HASH_Update( &HASHcontext,
3157 &pre, sizeof( pre ) );
3158 HASH_Update( &HASHcontext,
3159 syntax->ssyn_oid, slen );
3160 HASH_Update( &HASHcontext,
3161 mr->smr_oid, mlen );
3162 HASH_Update( &HASHcontext,
3163 &value.bv_val[j], klen );
3164 HASH_Final( HASHdigest, &HASHcontext );
3166 ber_dupbv( &keys[nkeys++], &digest );
3169 free( value.bv_val );
3173 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3174 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3176 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3177 ber_dupbv( &value, &sa->sa_final );
3178 ldap_pvt_str2upper( value.bv_val );
3180 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3181 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3183 HASH_Init( &HASHcontext );
3184 if( prefix != NULL && prefix->bv_len > 0 ) {
3185 HASH_Update( &HASHcontext,
3186 prefix->bv_val, prefix->bv_len );
3188 HASH_Update( &HASHcontext,
3189 &pre, sizeof( pre ) );
3190 HASH_Update( &HASHcontext,
3191 syntax->ssyn_oid, slen );
3192 HASH_Update( &HASHcontext,
3193 mr->smr_oid, mlen );
3194 HASH_Update( &HASHcontext,
3195 &value.bv_val[value.bv_len-klen], klen );
3196 HASH_Final( HASHdigest, &HASHcontext );
3198 free( value.bv_val );
3199 ber_dupbv( &keys[nkeys++], &digest );
3203 keys[nkeys].bv_val = NULL;
3210 return LDAP_SUCCESS;
3214 numericStringValidate(
3220 for(i=0; i < in->bv_len; i++) {
3221 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3222 return LDAP_INVALID_SYNTAX;
3226 return LDAP_SUCCESS;
3230 numericStringNormalize(
3233 struct berval *normalized )
3235 /* removal all spaces */
3238 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3241 q = normalized->bv_val;
3244 if ( ASCII_SPACE( *p ) ) {
3245 /* Ignore whitespace */
3252 /* we should have copied no more then is in val */
3253 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3255 /* null terminate */
3258 normalized->bv_len = q - normalized->bv_val;
3260 return LDAP_SUCCESS;
3264 objectIdentifierFirstComponentMatch(
3269 struct berval *value,
3270 void *assertedValue )
3272 int rc = LDAP_SUCCESS;
3274 struct berval *asserted = (struct berval *) assertedValue;
3278 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3279 return LDAP_INVALID_SYNTAX;
3282 /* trim leading white space */
3283 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3287 /* grab next word */
3288 oid.bv_val = &value->bv_val[i];
3289 oid.bv_len = value->bv_len - i;
3290 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3295 /* insert attributeTypes, objectclass check here */
3296 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3297 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3300 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3301 MatchingRule *asserted_mr = mr_bvfind( asserted );
3302 MatchingRule *stored_mr = mr_bvfind( &oid );
3304 if( asserted_mr == NULL ) {
3305 rc = SLAPD_COMPARE_UNDEFINED;
3307 match = asserted_mr != stored_mr;
3310 } else if ( !strcmp( syntax->ssyn_oid,
3311 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3313 AttributeType *asserted_at = at_bvfind( asserted );
3314 AttributeType *stored_at = at_bvfind( &oid );
3316 if( asserted_at == NULL ) {
3317 rc = SLAPD_COMPARE_UNDEFINED;
3319 match = asserted_at != stored_at;
3322 } else if ( !strcmp( syntax->ssyn_oid,
3323 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3325 ObjectClass *asserted_oc = oc_bvfind( asserted );
3326 ObjectClass *stored_oc = oc_bvfind( &oid );
3328 if( asserted_oc == NULL ) {
3329 rc = SLAPD_COMPARE_UNDEFINED;
3331 match = asserted_oc != stored_oc;
3337 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3338 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3339 match, value->bv_val, asserted->bv_val ));
3341 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3342 "%d\n\t\"%s\"\n\t\"%s\"\n",
3343 match, value->bv_val, asserted->bv_val );
3347 if( rc == LDAP_SUCCESS ) *matchp = match;
3357 struct berval *value,
3358 void *assertedValue )
3360 long lValue, lAssertedValue;
3362 /* safe to assume integers are NUL terminated? */
3363 lValue = strtoul(value->bv_val, NULL, 10);
3364 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3365 return LDAP_CONSTRAINT_VIOLATION;
3367 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3368 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3369 return LDAP_CONSTRAINT_VIOLATION;
3371 *matchp = (lValue & lAssertedValue);
3372 return LDAP_SUCCESS;
3381 struct berval *value,
3382 void *assertedValue )
3384 long lValue, lAssertedValue;
3386 /* safe to assume integers are NUL terminated? */
3387 lValue = strtoul(value->bv_val, NULL, 10);
3388 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3389 return LDAP_CONSTRAINT_VIOLATION;
3391 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3392 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3393 return LDAP_CONSTRAINT_VIOLATION;
3395 *matchp = (lValue | lAssertedValue);
3396 return LDAP_SUCCESS;
3400 #include <openssl/x509.h>
3401 #include <openssl/err.h>
3402 char digit[] = "0123456789";
3405 * Next function returns a string representation of a ASN1_INTEGER.
3406 * It works for unlimited lengths.
3409 static struct berval *
3410 asn1_integer2str(ASN1_INTEGER *a)
3415 /* We work backwards, make it fill from the end of buf */
3416 p = buf + sizeof(buf) - 1;
3419 if ( a == NULL || a->length == 0 ) {
3427 /* We want to preserve the original */
3428 copy = ch_malloc(n*sizeof(unsigned int));
3429 for (i = 0; i<n; i++) {
3430 copy[i] = a->data[i];
3434 * base indicates the index of the most significant
3435 * byte that might be nonzero. When it goes off the
3436 * end, we now there is nothing left to do.
3442 for (i = base; i<n; i++ ) {
3443 copy[i] += carry*256;
3444 carry = copy[i] % 10;
3449 * Way too large, we need to leave
3450 * room for sign if negative
3455 *--p = digit[carry];
3456 if (copy[base] == 0)
3462 if ( a->type == V_ASN1_NEG_INTEGER ) {
3466 return ber_bvstrdup(p);
3469 /* Get a DN in RFC2253 format from a X509_NAME internal struct */
3470 static struct berval *
3471 dn_openssl2ldap(X509_NAME *name)
3473 char issuer_dn[1024];
3476 bio = BIO_new(BIO_s_mem());
3479 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3480 "dn_openssl2ldap: error creating BIO_s_mem: %s\n",
3481 ERR_error_string(ERR_get_error(),NULL)));
3483 Debug( LDAP_DEBUG_ARGS, "dn_openssl2ldap: "
3484 "error creating BIO: %s\n",
3485 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3489 X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253);
3491 BIO_gets(bio, issuer_dn, 1024);
3494 return ber_bvstrdup(issuer_dn);
3498 * Given a certificate in DER format, extract the corresponding
3499 * assertion value for certificateExactMatch
3502 certificateExactConvert(
3504 struct berval * out )
3507 unsigned char *p = in->bv_val;
3508 struct berval *serial;
3509 struct berval *issuer_dn;
3510 struct berval *bv_tmp;
3512 xcert = d2i_X509(NULL, &p, in->bv_len);
3515 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3516 "certificateExactConvert: error parsing cert: %s\n",
3517 ERR_error_string(ERR_get_error(),NULL)));
3519 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3520 "error parsing cert: %s\n",
3521 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3523 return LDAP_INVALID_SYNTAX;
3526 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3529 return LDAP_INVALID_SYNTAX;
3531 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
3535 return LDAP_INVALID_SYNTAX;
3537 /* Actually, dn_openssl2ldap returns in a normalized format, but
3538 it is different from our normalized format */
3540 if ( dnNormalize(NULL, bv_tmp, &issuer_dn) != LDAP_SUCCESS ) {
3544 return LDAP_INVALID_SYNTAX;
3550 out->bv_len = serial->bv_len + issuer_dn->bv_len + sizeof(" $ ");
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, " $ ", sizeof(" $ ")-1);
3557 AC_MEMCPY(p, issuer_dn->bv_val, issuer_dn->bv_len);
3558 p += issuer_dn->bv_len;
3562 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3563 "certificateExactConvert: \n %s\n",
3566 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3568 out->bv_val, NULL, NULL );
3572 ber_bvfree(issuer_dn);
3574 return LDAP_SUCCESS;
3578 serial_and_issuer_parse(
3579 struct berval *assertion,
3580 struct berval **serial,
3581 struct berval **issuer_dn
3589 begin = assertion->bv_val;
3590 end = assertion->bv_val+assertion->bv_len-1;
3591 for (p=begin; p<=end && *p != '$'; p++)
3594 return LDAP_INVALID_SYNTAX;
3596 /* p now points at the $ sign, now use begin and end to delimit the
3598 while (ASCII_SPACE(*begin))
3601 while (ASCII_SPACE(*end))
3604 bv.bv_len = end-begin+1;
3606 *serial = ber_dupbv(NULL, &bv);
3608 /* now extract the issuer, remember p was at the dollar sign */
3610 end = assertion->bv_val+assertion->bv_len-1;
3611 while (ASCII_SPACE(*begin))
3613 /* should we trim spaces at the end too? is it safe always? */
3615 bv.bv_len = end-begin+1;
3617 dnNormalize( NULL, &bv, issuer_dn );
3619 return LDAP_SUCCESS;
3623 certificateExactMatch(
3628 struct berval *value,
3629 void *assertedValue )
3632 unsigned char *p = value->bv_val;
3633 struct berval *serial;
3634 struct berval *issuer_dn;
3635 struct berval *asserted_serial;
3636 struct berval *asserted_issuer_dn;
3639 xcert = d2i_X509(NULL, &p, value->bv_len);
3642 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3643 "certificateExactMatch: error parsing cert: %s\n",
3644 ERR_error_string(ERR_get_error(),NULL)));
3646 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
3647 "error parsing cert: %s\n",
3648 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3650 return LDAP_INVALID_SYNTAX;
3653 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3654 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
3658 serial_and_issuer_parse(assertedValue,
3660 &asserted_issuer_dn);
3665 slap_schema.si_syn_integer,
3666 slap_schema.si_mr_integerMatch,
3669 if ( ret == LDAP_SUCCESS ) {
3670 if ( *matchp == 0 ) {
3671 /* We need to normalize everything for dnMatch */
3675 slap_schema.si_syn_distinguishedName,
3676 slap_schema.si_mr_distinguishedNameMatch,
3678 asserted_issuer_dn);
3683 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3684 "certificateExactMatch: %d\n %s $ %s\n %s $ %s\n",
3685 *matchp, serial->bv_val, issuer_dn->bv_val,
3686 asserted->serial->bv_val, asserted_issuer_dn->bv_val));
3688 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3689 "%d\n\t\"%s $ %s\"\n",
3690 *matchp, serial->bv_val, issuer_dn->bv_val );
3691 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3692 asserted_serial->bv_val, asserted_issuer_dn->bv_val,
3697 ber_bvfree(issuer_dn);
3698 ber_bvfree(asserted_serial);
3699 ber_bvfree(asserted_issuer_dn);
3705 * Index generation function
3706 * We just index the serials, in most scenarios the issuer DN is one of
3707 * a very small set of values.
3709 static int certificateExactIndexer(
3714 struct berval *prefix,
3722 struct berval * serial;
3724 /* we should have at least one value at this point */
3725 assert( values != NULL && values[0].bv_val != NULL );
3727 for( i=0; values[i].bv_val != NULL; i++ ) {
3728 /* empty -- just count them */
3731 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3733 for( i=0; values[i].bv_val != NULL; i++ ) {
3734 p = values[i].bv_val;
3735 xcert = d2i_X509(NULL, &p, values[i].bv_len);
3738 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3739 "certificateExactIndexer: error parsing cert: %s\n",
3740 ERR_error_string(ERR_get_error(),NULL)));
3742 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3743 "error parsing cert: %s\n",
3744 ERR_error_string(ERR_get_error(),NULL),
3747 /* Do we leak keys on error? */
3748 return LDAP_INVALID_SYNTAX;
3751 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3753 integerNormalize( slap_schema.si_syn_integer,
3758 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3759 "certificateExactIndexer: returning: %s\n",
3762 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3769 keys[i].bv_val = NULL;
3771 return LDAP_SUCCESS;
3774 /* Index generation function */
3775 /* We think this is always called with a value in matching rule syntax */
3776 static int certificateExactFilter(
3781 struct berval *prefix,
3786 struct berval *asserted_serial;
3787 struct berval *asserted_issuer_dn;
3789 serial_and_issuer_parse(assertValue,
3791 &asserted_issuer_dn);
3793 keys = ch_malloc( sizeof( struct berval ) * 2 );
3794 integerNormalize( syntax, asserted_serial, &keys[0] );
3795 keys[1].bv_val = NULL;
3798 ber_bvfree(asserted_serial);
3799 ber_bvfree(asserted_issuer_dn);
3800 return LDAP_SUCCESS;
3805 check_time_syntax (struct berval *val,
3809 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3810 static int mdays[2][12] = {
3811 /* non-leap years */
3812 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3814 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3817 int part, c, tzoffset, leapyear = 0 ;
3819 if( val->bv_len == 0 ) {
3820 return LDAP_INVALID_SYNTAX;
3823 p = (char *)val->bv_val;
3824 e = p + val->bv_len;
3826 /* Ignore initial whitespace */
3827 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3831 if (e - p < 13 - (2 * start)) {
3832 return LDAP_INVALID_SYNTAX;
3835 for (part = 0; part < 9; part++) {
3839 for (part = start; part < 7; part++) {
3841 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3848 return LDAP_INVALID_SYNTAX;
3850 if (c < 0 || c > 9) {
3851 return LDAP_INVALID_SYNTAX;
3857 return LDAP_INVALID_SYNTAX;
3859 if (c < 0 || c > 9) {
3860 return LDAP_INVALID_SYNTAX;
3865 if (part == 2 || part == 3) {
3868 if (parts[part] < 0) {
3869 return LDAP_INVALID_SYNTAX;
3871 if (parts[part] > ceiling[part]) {
3872 return LDAP_INVALID_SYNTAX;
3876 /* leapyear check for the Gregorian calendar (year>1581) */
3877 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
3878 ((parts[0] % 4 == 0) && (parts[1] == 0)))
3883 if (parts[3] > mdays[leapyear][parts[2]]) {
3884 return LDAP_INVALID_SYNTAX;
3889 tzoffset = 0; /* UTC */
3890 } else if (c != '+' && c != '-') {
3891 return LDAP_INVALID_SYNTAX;
3895 } else /* c == '+' */ {
3900 return LDAP_INVALID_SYNTAX;
3903 for (part = 7; part < 9; part++) {
3905 if (c < 0 || c > 9) {
3906 return LDAP_INVALID_SYNTAX;
3911 if (c < 0 || c > 9) {
3912 return LDAP_INVALID_SYNTAX;
3916 if (parts[part] < 0 || parts[part] > ceiling[part]) {
3917 return LDAP_INVALID_SYNTAX;
3922 /* Ignore trailing whitespace */
3923 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3927 return LDAP_INVALID_SYNTAX;
3930 switch ( tzoffset ) {
3931 case -1: /* negativ offset to UTC, ie west of Greenwich */
3932 parts[4] += parts[7];
3933 parts[5] += parts[8];
3934 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
3938 c = mdays[leapyear][parts[2]];
3940 if (parts[part] > c) {
3941 parts[part] -= c + 1;
3946 case 1: /* positive offset to UTC, ie east of Greenwich */
3947 parts[4] -= parts[7];
3948 parts[5] -= parts[8];
3949 for (part = 6; --part > 0; ) {
3953 /* first arg to % needs to be non negativ */
3954 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
3956 if (parts[part] < 0) {
3957 parts[part] += c + 1;
3962 case 0: /* already UTC */
3966 return LDAP_SUCCESS;
3973 struct berval *normalized )
3977 rc = check_time_syntax(val, 1, parts);
3978 if (rc != LDAP_SUCCESS) {
3982 normalized->bv_val = ch_malloc( 14 );
3983 if ( normalized->bv_val == NULL ) {
3984 return LBER_ERROR_MEMORY;
3987 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
3988 parts[1], parts[2] + 1, parts[3] + 1,
3989 parts[4], parts[5], parts[6] );
3990 normalized->bv_len = 13;
3992 return LDAP_SUCCESS;
4002 return check_time_syntax(in, 1, parts);
4006 generalizedTimeValidate(
4012 return check_time_syntax(in, 0, parts);
4016 generalizedTimeNormalize(
4019 struct berval *normalized )
4023 rc = check_time_syntax(val, 0, parts);
4024 if (rc != LDAP_SUCCESS) {
4028 normalized->bv_val = ch_malloc( 16 );
4029 if ( normalized->bv_val == NULL ) {
4030 return LBER_ERROR_MEMORY;
4033 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4034 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4035 parts[4], parts[5], parts[6] );
4036 normalized->bv_len = 15;
4038 return LDAP_SUCCESS;
4042 nisNetgroupTripleValidate(
4044 struct berval *val )
4049 if ( val->bv_len == 0 ) {
4050 return LDAP_INVALID_SYNTAX;
4053 p = (char *)val->bv_val;
4054 e = p + val->bv_len;
4056 if ( *p != '(' /*')'*/ ) {
4057 return LDAP_INVALID_SYNTAX;
4060 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4064 return LDAP_INVALID_SYNTAX;
4067 } else if ( !ATTR_CHAR( *p ) ) {
4068 return LDAP_INVALID_SYNTAX;
4072 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4073 return LDAP_INVALID_SYNTAX;
4079 return LDAP_INVALID_SYNTAX;
4082 return LDAP_SUCCESS;
4086 bootParameterValidate(
4088 struct berval *val )
4092 if ( val->bv_len == 0 ) {
4093 return LDAP_INVALID_SYNTAX;
4096 p = (char *)val->bv_val;
4097 e = p + val->bv_len;
4100 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4101 if ( !ATTR_CHAR( *p ) ) {
4102 return LDAP_INVALID_SYNTAX;
4107 return LDAP_INVALID_SYNTAX;
4111 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4112 if ( !ATTR_CHAR( *p ) ) {
4113 return LDAP_INVALID_SYNTAX;
4118 return LDAP_INVALID_SYNTAX;
4122 for ( p++; p < e; p++ ) {
4123 if ( !ATTR_CHAR( *p ) ) {
4124 return LDAP_INVALID_SYNTAX;
4128 return LDAP_SUCCESS;
4131 static struct syntax_defs_rec {
4133 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4134 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4136 slap_syntax_validate_func *sd_validate;
4137 slap_syntax_transform_func *sd_normalize;
4138 slap_syntax_transform_func *sd_pretty;
4139 #ifdef SLAPD_BINARY_CONVERSION
4140 slap_syntax_transform_func *sd_ber2str;
4141 slap_syntax_transform_func *sd_str2ber;
4144 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4145 X_BINARY X_NOT_H_R ")",
4146 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4147 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4148 0, NULL, NULL, NULL},
4149 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4150 0, NULL, NULL, NULL},
4151 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4153 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4154 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4156 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4157 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4158 0, bitStringValidate, bitStringNormalize, NULL },
4159 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4160 0, booleanValidate, NULL, NULL},
4161 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4162 X_BINARY X_NOT_H_R ")",
4163 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4164 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4165 X_BINARY X_NOT_H_R ")",
4166 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4167 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4168 X_BINARY X_NOT_H_R ")",
4169 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4170 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4171 0, countryStringValidate, IA5StringNormalize, NULL},
4172 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4173 0, dnValidate, dnNormalize2, dnPretty2},
4174 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4175 0, NULL, NULL, NULL},
4176 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4177 0, NULL, NULL, NULL},
4178 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4179 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4180 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4181 0, NULL, NULL, NULL},
4182 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4183 0, NULL, NULL, NULL},
4184 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4185 0, NULL, NULL, NULL},
4186 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4187 0, NULL, NULL, NULL},
4188 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4189 0, NULL, NULL, NULL},
4190 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4191 0, printablesStringValidate, IA5StringNormalize, NULL},
4192 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4193 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4194 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4195 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4196 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4197 0, NULL, NULL, NULL},
4198 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4199 0, IA5StringValidate, IA5StringNormalize, NULL},
4200 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4201 0, integerValidate, integerNormalize, NULL},
4202 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4203 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4204 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4205 0, NULL, NULL, NULL},
4206 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4207 0, NULL, NULL, NULL},
4208 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4209 0, NULL, NULL, NULL},
4210 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4211 0, NULL, NULL, NULL},
4212 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4213 0, NULL, NULL, NULL},
4214 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4215 0, nameUIDValidate, nameUIDNormalize, NULL},
4216 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4217 0, NULL, NULL, NULL},
4218 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4219 0, numericStringValidate, numericStringNormalize, NULL},
4220 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4221 0, NULL, NULL, NULL},
4222 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4223 0, oidValidate, NULL, NULL},
4224 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4225 0, IA5StringValidate, IA5StringNormalize, NULL},
4226 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4227 0, blobValidate, NULL, NULL},
4228 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4229 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4230 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4231 0, NULL, NULL, NULL},
4232 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4233 0, NULL, NULL, NULL},
4234 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4235 0, printableStringValidate, IA5StringNormalize, NULL},
4236 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4237 X_BINARY X_NOT_H_R ")",
4238 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4239 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4240 X_BINARY X_NOT_H_R ")",
4241 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4242 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4243 0, printableStringValidate, IA5StringNormalize, NULL},
4244 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4245 0, NULL, NULL, NULL},
4246 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4247 0, printablesStringValidate, IA5StringNormalize, NULL},
4248 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4249 0, utcTimeValidate, utcTimeNormalize, NULL},
4250 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4251 0, NULL, NULL, NULL},
4252 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4253 0, NULL, NULL, NULL},
4254 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4255 0, NULL, NULL, NULL},
4256 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4257 0, NULL, NULL, NULL},
4258 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4259 0, NULL, NULL, NULL},
4261 /* RFC 2307 NIS Syntaxes */
4262 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4263 0, nisNetgroupTripleValidate, NULL, NULL},
4264 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4265 0, bootParameterValidate, NULL, NULL},
4269 /* These OIDs are not published yet, but will be in the next
4270 * I-D for PKIX LDAPv3 schema as have been advanced by David
4271 * Chadwick in private mail.
4273 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4274 0, NULL, NULL, NULL},
4277 /* OpenLDAP Experimental Syntaxes */
4278 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4280 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4283 #ifdef SLAPD_AUTHPASSWD
4284 /* needs updating */
4285 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4286 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4289 /* OpenLDAP Void Syntax */
4290 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4291 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4292 {NULL, 0, NULL, NULL, NULL}
4296 * Other matching rules in X.520 that we do not use (yet):
4298 * 2.5.13.9 numericStringOrderingMatch
4299 * 2.5.13.15 integerOrderingMatch
4300 * 2.5.13.18 octetStringOrderingMatch
4301 * 2.5.13.19 octetStringSubstringsMatch
4302 * 2.5.13.25 uTCTimeMatch
4303 * 2.5.13.26 uTCTimeOrderingMatch
4304 * 2.5.13.31 directoryStringFirstComponentMatch
4305 * 2.5.13.32 wordMatch
4306 * 2.5.13.33 keywordMatch
4307 * 2.5.13.35 certificateMatch
4308 * 2.5.13.36 certificatePairExactMatch
4309 * 2.5.13.37 certificatePairMatch
4310 * 2.5.13.38 certificateListExactMatch
4311 * 2.5.13.39 certificateListMatch
4312 * 2.5.13.40 algorithmIdentifierMatch
4313 * 2.5.13.41 storedPrefixMatch
4314 * 2.5.13.42 attributeCertificateMatch
4315 * 2.5.13.43 readerAndKeyIDMatch
4316 * 2.5.13.44 attributeIntegrityMatch
4318 static struct mrule_defs_rec {
4320 slap_mask_t mrd_usage;
4321 slap_mr_convert_func * mrd_convert;
4322 slap_mr_normalize_func * mrd_normalize;
4323 slap_mr_match_func * mrd_match;
4324 slap_mr_indexer_func * mrd_indexer;
4325 slap_mr_filter_func * mrd_filter;
4327 char * mrd_associated;
4330 * EQUALITY matching rules must be listed after associated APPROX
4331 * matching rules. So, we list all APPROX matching rules first.
4333 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4334 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4335 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4337 directoryStringApproxMatch,
4338 directoryStringApproxIndexer,
4339 directoryStringApproxFilter,
4342 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4343 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4344 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4346 IA5StringApproxMatch,
4347 IA5StringApproxIndexer,
4348 IA5StringApproxFilter,
4352 * Other matching rules
4355 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4356 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4357 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4359 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4362 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4363 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4364 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4366 dnMatch, dnIndexer, dnFilter,
4369 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4370 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4371 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4373 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4374 directoryStringApproxMatchOID },
4376 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4377 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4380 caseIgnoreOrderingMatch, NULL, NULL,
4383 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4384 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4385 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4387 caseExactIgnoreSubstringsMatch,
4388 caseExactIgnoreSubstringsIndexer,
4389 caseExactIgnoreSubstringsFilter,
4392 {"( 2.5.13.5 NAME 'caseExactMatch' "
4393 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4394 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4396 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4397 directoryStringApproxMatchOID },
4399 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4400 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4403 caseExactOrderingMatch, NULL, NULL,
4406 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4407 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4408 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4410 caseExactIgnoreSubstringsMatch,
4411 caseExactIgnoreSubstringsIndexer,
4412 caseExactIgnoreSubstringsFilter,
4415 {"( 2.5.13.8 NAME 'numericStringMatch' "
4416 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4417 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4420 caseIgnoreIA5Indexer,
4421 caseIgnoreIA5Filter,
4424 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4425 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4426 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4428 caseIgnoreIA5SubstringsMatch,
4429 caseIgnoreIA5SubstringsIndexer,
4430 caseIgnoreIA5SubstringsFilter,
4433 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4434 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4435 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4437 caseIgnoreListMatch, NULL, NULL,
4440 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4441 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4442 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4444 caseIgnoreListSubstringsMatch, NULL, NULL,
4447 {"( 2.5.13.13 NAME 'booleanMatch' "
4448 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4449 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4451 booleanMatch, NULL, NULL,
4454 {"( 2.5.13.14 NAME 'integerMatch' "
4455 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4456 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4458 integerMatch, integerIndexer, integerFilter,
4461 {"( 2.5.13.16 NAME 'bitStringMatch' "
4462 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4463 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4465 bitStringMatch, bitStringIndexer, bitStringFilter,
4468 {"( 2.5.13.17 NAME 'octetStringMatch' "
4469 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4470 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4472 octetStringMatch, octetStringIndexer, octetStringFilter,
4475 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4476 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4477 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4479 telephoneNumberMatch,
4480 telephoneNumberIndexer,
4481 telephoneNumberFilter,
4484 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4485 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4486 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4488 telephoneNumberSubstringsMatch,
4489 telephoneNumberSubstringsIndexer,
4490 telephoneNumberSubstringsFilter,
4493 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4494 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4495 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4500 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4501 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4502 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4504 uniqueMemberMatch, NULL, NULL,
4507 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4508 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4509 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4511 protocolInformationMatch, NULL, NULL,
4514 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4515 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4516 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4518 generalizedTimeMatch, NULL, NULL,
4521 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4522 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4525 generalizedTimeOrderingMatch, NULL, NULL,
4528 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4529 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4530 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4532 integerFirstComponentMatch, NULL, NULL,
4535 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4536 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4537 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4539 objectIdentifierFirstComponentMatch, NULL, NULL,
4543 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4544 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4545 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4546 certificateExactConvert, NULL,
4547 certificateExactMatch,
4548 certificateExactIndexer, certificateExactFilter,
4552 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4553 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4554 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4556 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4557 IA5StringApproxMatchOID },
4559 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4560 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4561 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4563 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4564 IA5StringApproxMatchOID },
4566 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4567 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4570 caseIgnoreIA5SubstringsMatch,
4571 caseIgnoreIA5SubstringsIndexer,
4572 caseIgnoreIA5SubstringsFilter,
4575 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4576 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4579 caseExactIA5SubstringsMatch,
4580 caseExactIA5SubstringsIndexer,
4581 caseExactIA5SubstringsFilter,
4584 #ifdef SLAPD_AUTHPASSWD
4585 /* needs updating */
4586 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4587 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4590 authPasswordMatch, NULL, NULL,
4594 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4595 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4598 OpenLDAPaciMatch, NULL, NULL,
4601 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4602 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4605 integerBitAndMatch, NULL, NULL,
4608 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4609 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4612 integerBitOrMatch, NULL, NULL,
4615 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
4619 slap_schema_init( void )
4624 /* we should only be called once (from main) */
4625 assert( schema_init_done == 0 );
4627 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4628 res = register_syntax( syntax_defs[i].sd_desc,
4629 syntax_defs[i].sd_flags,
4630 syntax_defs[i].sd_validate,
4631 syntax_defs[i].sd_normalize,
4632 syntax_defs[i].sd_pretty
4633 #ifdef SLAPD_BINARY_CONVERSION
4635 syntax_defs[i].sd_ber2str,
4636 syntax_defs[i].sd_str2ber
4641 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
4642 syntax_defs[i].sd_desc );
4647 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4648 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
4650 "slap_schema_init: Ingoring unusable matching rule %s\n",
4651 mrule_defs[i].mrd_desc );
4655 res = register_matching_rule(
4656 mrule_defs[i].mrd_desc,
4657 mrule_defs[i].mrd_usage,
4658 mrule_defs[i].mrd_convert,
4659 mrule_defs[i].mrd_normalize,
4660 mrule_defs[i].mrd_match,
4661 mrule_defs[i].mrd_indexer,
4662 mrule_defs[i].mrd_filter,
4663 mrule_defs[i].mrd_associated );
4667 "slap_schema_init: Error registering matching rule %s\n",
4668 mrule_defs[i].mrd_desc );
4673 res = slap_schema_load();
4674 schema_init_done = 1;
4679 schema_destroy( void )