1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
15 #include <ac/string.h>
16 #include <ac/socket.h>
22 #include "ldap_utf8.h"
24 #include "lutil_hash.h"
25 #define HASH_BYTES LUTIL_HASH_BYTES
26 #define HASH_CONTEXT lutil_HASH_CTX
27 #define HASH_Init(c) lutil_HASHInit(c)
28 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
29 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
32 #define SLAP_MR_DN_FOLD (0) /* TO BE DELETED */
35 /* recycled validatation routines */
36 #define berValidate blobValidate
38 /* unimplemented pretters */
39 #define integerPretty NULL
41 /* recycled matching routines */
42 #define bitStringMatch octetStringMatch
43 #define numericStringMatch caseIgnoreIA5Match
44 #define objectIdentifierMatch octetStringMatch
45 #define telephoneNumberMatch caseIgnoreIA5Match
46 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
47 #define generalizedTimeMatch caseIgnoreIA5Match
48 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
49 #define uniqueMemberMatch dnMatch
50 #define integerFirstComponentMatch integerMatch
52 /* approx matching rules */
53 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
54 #define directoryStringApproxMatch approxMatch
55 #define directoryStringApproxIndexer approxIndexer
56 #define directoryStringApproxFilter approxFilter
57 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
58 #define IA5StringApproxMatch approxMatch
59 #define IA5StringApproxIndexer approxIndexer
60 #define IA5StringApproxFilter approxFilter
62 /* ordering matching rules */
63 #define caseIgnoreOrderingMatch caseIgnoreMatch
64 #define caseExactOrderingMatch caseExactMatch
65 #define integerOrderingMatch integerMatch
67 /* unimplemented matching routines */
68 #define caseIgnoreListMatch NULL
69 #define caseIgnoreListSubstringsMatch NULL
70 #define protocolInformationMatch NULL
72 #ifdef SLAPD_ACI_ENABLED
73 #define OpenLDAPaciMatch NULL
75 #ifdef SLAPD_AUTHPASSWD
76 #define authPasswordMatch NULL
79 /* recycled indexing/filtering routines */
80 #define dnIndexer caseExactIgnoreIndexer
81 #define dnFilter caseExactIgnoreFilter
82 #define bitStringFilter octetStringFilter
83 #define bitStringIndexer octetStringIndexer
85 #define telephoneNumberIndexer caseIgnoreIA5Indexer
86 #define telephoneNumberFilter caseIgnoreIA5Filter
87 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
88 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
90 static MatchingRule *caseExactMatchingRule;
91 static MatchingRule *caseExactSubstringsMatchingRule;
92 static MatchingRule *integerFirstComponentMatchingRule;
94 static const struct MatchingRulePtr {
98 /* must match OIDs below */
99 { "2.5.13.5", &caseExactMatchingRule },
100 { "2.5.13.7", &caseExactSubstringsMatchingRule },
101 { "2.5.13.29", &integerFirstComponentMatchingRule }
105 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
108 char lower = TOLOWER( c );
109 char upper = TOUPPER( c );
111 if( c == 0 ) return NULL;
113 for( i=0; i < bv->bv_len; i++ ) {
114 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
116 return &bv->bv_val[i];
129 struct berval *value,
130 void *assertedValue )
132 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
135 match = memcmp( value->bv_val,
136 ((struct berval *) assertedValue)->bv_val,
145 octetStringOrderingMatch(
150 struct berval *value,
151 void *assertedValue )
153 ber_len_t v_len = value->bv_len;
154 ber_len_t av_len = ((struct berval *) assertedValue)->bv_len;
155 int match = memcmp( value->bv_val,
156 ((struct berval *) assertedValue)->bv_val,
157 (v_len < av_len ? v_len : av_len) );
159 match = v_len - av_len;
164 /* Index generation function */
165 int octetStringIndexer(
170 struct berval *prefix,
177 HASH_CONTEXT HASHcontext;
178 unsigned char HASHdigest[HASH_BYTES];
179 struct berval digest;
180 digest.bv_val = HASHdigest;
181 digest.bv_len = sizeof(HASHdigest);
183 for( i=0; values[i].bv_val != NULL; i++ ) {
184 /* just count them */
187 /* we should have at least one value at this point */
190 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
192 slen = syntax->ssyn_oidlen;
193 mlen = mr->smr_oidlen;
195 for( i=0; values[i].bv_val != NULL; i++ ) {
196 HASH_Init( &HASHcontext );
197 if( prefix != NULL && prefix->bv_len > 0 ) {
198 HASH_Update( &HASHcontext,
199 prefix->bv_val, prefix->bv_len );
201 HASH_Update( &HASHcontext,
202 syntax->ssyn_oid, slen );
203 HASH_Update( &HASHcontext,
205 HASH_Update( &HASHcontext,
206 values[i].bv_val, values[i].bv_len );
207 HASH_Final( HASHdigest, &HASHcontext );
209 ber_dupbv( &keys[i], &digest );
212 keys[i].bv_val = NULL;
220 /* Index generation function */
221 int octetStringFilter(
226 struct berval *prefix,
227 void * assertedValue,
232 HASH_CONTEXT HASHcontext;
233 unsigned char HASHdigest[HASH_BYTES];
234 struct berval *value = (struct berval *) assertedValue;
235 struct berval digest;
236 digest.bv_val = HASHdigest;
237 digest.bv_len = sizeof(HASHdigest);
239 slen = syntax->ssyn_oidlen;
240 mlen = mr->smr_oidlen;
242 keys = ch_malloc( sizeof( struct berval ) * 2 );
244 HASH_Init( &HASHcontext );
245 if( prefix != NULL && prefix->bv_len > 0 ) {
246 HASH_Update( &HASHcontext,
247 prefix->bv_val, prefix->bv_len );
249 HASH_Update( &HASHcontext,
250 syntax->ssyn_oid, slen );
251 HASH_Update( &HASHcontext,
253 HASH_Update( &HASHcontext,
254 value->bv_val, value->bv_len );
255 HASH_Final( HASHdigest, &HASHcontext );
257 ber_dupbv( keys, &digest );
258 keys[1].bv_val = NULL;
271 /* no value allowed */
272 return LDAP_INVALID_SYNTAX;
280 /* any value allowed */
291 /* very unforgiving validation, requires no normalization
292 * before simplistic matching
294 if( in->bv_len < 3 ) {
295 return LDAP_INVALID_SYNTAX;
299 * rfc 2252 section 6.3 Bit String
300 * bitstring = "'" *binary-digit "'"
301 * binary-digit = "0" / "1"
302 * example: '0101111101'B
305 if( in->bv_val[0] != '\'' ||
306 in->bv_val[in->bv_len-2] != '\'' ||
307 in->bv_val[in->bv_len-1] != 'B' )
309 return LDAP_INVALID_SYNTAX;
312 for( i=in->bv_len-3; i>0; i-- ) {
313 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
314 return LDAP_INVALID_SYNTAX;
329 if( in->bv_len == 0 ) return LDAP_SUCCESS;
331 ber_dupbv( &dn, in );
332 if( !dn.bv_val ) return LDAP_OTHER;
334 if( dn.bv_val[dn.bv_len-1] == 'B'
335 && dn.bv_val[dn.bv_len-2] == '\'' )
337 /* assume presence of optional UID */
340 for(i=dn.bv_len-3; i>1; i--) {
341 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
345 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
346 ber_memfree( dn.bv_val );
347 return LDAP_INVALID_SYNTAX;
350 /* trim the UID to allow use of dnValidate */
351 dn.bv_val[i-1] = '\0';
355 rc = dnValidate( NULL, &dn );
357 ber_memfree( dn.bv_val );
365 struct berval *normalized )
370 ber_dupbv( &out, val );
371 if( out.bv_len != 0 ) {
372 struct berval uid = { 0, NULL };
374 if( out.bv_val[out.bv_len-1] == 'B'
375 && out.bv_val[out.bv_len-2] == '\'' )
377 /* assume presence of optional UID */
378 uid.bv_val = strrchr( out.bv_val, '#' );
380 if( uid.bv_val == NULL ) {
382 return LDAP_INVALID_SYNTAX;
385 uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
386 out.bv_len -= uid.bv_len--;
388 /* temporarily trim the UID */
389 *(uid.bv_val++) = '\0';
392 rc = dnNormalize2( NULL, &out, normalized );
394 if( rc != LDAP_SUCCESS ) {
396 return LDAP_INVALID_SYNTAX;
400 normalized->bv_val = ch_realloc( normalized->bv_val,
401 normalized->bv_len + uid.bv_len + sizeof("#") );
403 /* insert the separator */
404 normalized->bv_val[normalized->bv_len++] = '#';
407 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
408 uid.bv_val, uid.bv_len );
409 normalized->bv_len += uid.bv_len;
412 normalized->bv_val[normalized->bv_len] = '\0';
422 * Handling boolean syntax and matching is quite rigid.
423 * A more flexible approach would be to allow a variety
424 * of strings to be normalized and prettied into TRUE
432 /* very unforgiving validation, requires no normalization
433 * before simplistic matching
436 if( in->bv_len == 4 ) {
437 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
440 } else if( in->bv_len == 5 ) {
441 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
446 return LDAP_INVALID_SYNTAX;
455 struct berval *value,
456 void *assertedValue )
458 /* simplistic matching allowed by rigid validation */
459 struct berval *asserted = (struct berval *) assertedValue;
460 *matchp = value->bv_len != asserted->bv_len;
464 /*-------------------------------------------------------------------
465 LDAP/X.500 string syntax / matching rules have a few oddities. This
466 comment attempts to detail how slapd(8) treats them.
469 StringSyntax X.500 LDAP Matching
470 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
471 PrintableString subset subset i/e + ignore insignificant spaces
472 NumericString subset subset ignore all spaces
473 IA5String ASCII ASCII i/e + ignore insignificant spaces
474 TeletexString T.61 T.61 i/e + ignore insignificant spaces
476 TelephoneNumber subset subset i + ignore all spaces and "-"
478 See draft-ietf-ldapbis-strpro for details (once published).
482 In X.500(93), a directory string can be either a PrintableString,
483 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
484 In later versions, more CHOICEs were added. In all cases the string
487 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
489 For matching, there are both case ignore and exact rules. Both
490 also require that "insignificant" spaces be ignored.
491 spaces before the first non-space are ignored;
492 spaces after the last non-space are ignored;
493 spaces after a space are ignored.
494 Note: by these rules (and as clarified in X.520), a string of only
495 spaces is to be treated as if held one space, not empty (which
496 would be a syntax error).
499 In ASN.1, numeric string is just a string of digits and spaces
500 and could be empty. However, in X.500, all attribute values of
501 numeric string carry a non-empty constraint. For example:
503 internationalISDNNumber ATTRIBUTE ::= {
504 WITH SYNTAX InternationalISDNNumber
505 EQUALITY MATCHING RULE numericStringMatch
506 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
507 ID id-at-internationalISDNNumber }
508 InternationalISDNNumber ::=
509 NumericString (SIZE(1..ub-international-isdn-number))
511 Unforunately, some assertion values are don't carry the same
512 constraint (but its unclear how such an assertion could ever
513 be true). In LDAP, there is one syntax (numericString) not two
514 (numericString with constraint, numericString without constraint).
515 This should be treated as numericString with non-empty constraint.
516 Note that while someone may have no ISDN number, there are no ISDN
517 numbers which are zero length.
519 In matching, spaces are ignored.
522 In ASN.1, Printable string is just a string of printable characters
523 and can be empty. In X.500, semantics much like NumericString (see
524 serialNumber for a like example) excepting uses insignificant space
525 handling instead of ignore all spaces.
528 Basically same as PrintableString. There are no examples in X.500,
529 but same logic applies. So we require them to be non-empty as
532 -------------------------------------------------------------------*/
541 unsigned char *u = in->bv_val;
543 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
545 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
546 /* get the length indicated by the first byte */
547 len = LDAP_UTF8_CHARLEN2( u, len );
549 /* very basic checks */
552 if( (u[5] & 0xC0) != 0x80 ) {
553 return LDAP_INVALID_SYNTAX;
556 if( (u[4] & 0xC0) != 0x80 ) {
557 return LDAP_INVALID_SYNTAX;
560 if( (u[3] & 0xC0) != 0x80 ) {
561 return LDAP_INVALID_SYNTAX;
564 if( (u[2] & 0xC0 )!= 0x80 ) {
565 return LDAP_INVALID_SYNTAX;
568 if( (u[1] & 0xC0) != 0x80 ) {
569 return LDAP_INVALID_SYNTAX;
572 /* CHARLEN already validated it */
575 return LDAP_INVALID_SYNTAX;
578 /* make sure len corresponds with the offset
579 to the next character */
580 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
583 if( count != 0 ) return LDAP_INVALID_SYNTAX;
592 struct berval *normalized )
597 /* validator should have refused an empty string */
598 assert( val->bv_len );
602 /* Ignore initial whitespace */
603 /* All space is ASCII. All ASCII is 1 byte */
604 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
606 normalized->bv_len = val->bv_len - (p - val->bv_val);
608 if( !normalized->bv_len ) {
609 ber_mem2bv( " ", 1, 1, normalized );
613 ber_mem2bv( p, normalized->bv_len, 1, normalized );
614 e = normalized->bv_val + normalized->bv_len;
616 assert( normalized->bv_val );
618 p = q = normalized->bv_val;
623 if ( ASCII_SPACE( *p ) ) {
628 /* Ignore the extra whitespace */
629 while ( ASCII_SPACE( *p ) ) {
633 len = LDAP_UTF8_COPY(q,p);
639 assert( normalized->bv_val <= p );
640 assert( q+len <= p );
642 /* cannot start with a space */
643 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
646 * If the string ended in space, backup the pointer one
647 * position. One is enough because the above loop collapsed
648 * all whitespace to a single space.
656 /* cannot end with a space */
657 assert( !ASCII_SPACE( *q ) );
664 normalized->bv_len = q - normalized->bv_val;
669 /* Returns Unicode canonically normalized copy of a substring assertion
670 * Skipping attribute description */
671 static SubstringsAssertion *
672 UTF8SubstringsassertionNormalize(
673 SubstringsAssertion *sa,
676 SubstringsAssertion *nsa;
679 nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) );
684 if( sa->sa_initial.bv_val != NULL ) {
685 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
686 if( nsa->sa_initial.bv_val == NULL ) {
691 if( sa->sa_any != NULL ) {
692 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
695 nsa->sa_any = (struct berval *)
696 SLAP_MALLOC( (i + 1) * sizeof(struct berval) );
697 if( nsa->sa_any == NULL ) {
701 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
702 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
704 if( nsa->sa_any[i].bv_val == NULL ) {
708 nsa->sa_any[i].bv_val = NULL;
711 if( sa->sa_final.bv_val != NULL ) {
712 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
713 if( nsa->sa_final.bv_val == NULL ) {
721 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
722 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
723 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
728 #ifndef SLAPD_APPROX_OLDSINGLESTRING
730 #if defined(SLAPD_APPROX_INITIALS)
731 #define SLAPD_APPROX_DELIMITER "._ "
732 #define SLAPD_APPROX_WORDLEN 2
734 #define SLAPD_APPROX_DELIMITER " "
735 #define SLAPD_APPROX_WORDLEN 1
744 struct berval *value,
745 void *assertedValue )
747 struct berval *nval, *assertv;
748 char *val, **values, **words, *c;
749 int i, count, len, nextchunk=0, nextavail=0;
751 /* Yes, this is necessary */
752 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
758 /* Yes, this is necessary */
759 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
760 NULL, LDAP_UTF8_APPROX );
761 if( assertv == NULL ) {
767 /* Isolate how many words there are */
768 for ( c = nval->bv_val, count = 1; *c; c++ ) {
769 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
770 if ( c == NULL ) break;
775 /* Get a phonetic copy of each word */
776 words = (char **)ch_malloc( count * sizeof(char *) );
777 values = (char **)ch_malloc( count * sizeof(char *) );
778 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
780 values[i] = phonetic(c);
783 /* Work through the asserted value's words, to see if at least some
784 of the words are there, in the same order. */
786 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
787 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
792 #if defined(SLAPD_APPROX_INITIALS)
793 else if( len == 1 ) {
794 /* Single letter words need to at least match one word's initial */
795 for( i=nextavail; i<count; i++ )
796 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
803 /* Isolate the next word in the asserted value and phonetic it */
804 assertv->bv_val[nextchunk+len] = '\0';
805 val = phonetic( assertv->bv_val + nextchunk );
807 /* See if this phonetic chunk is in the remaining words of *value */
808 for( i=nextavail; i<count; i++ ){
809 if( !strcmp( val, values[i] ) ){
817 /* This chunk in the asserted value was NOT within the *value. */
823 /* Go on to the next word in the asserted value */
827 /* If some of the words were seen, call it a match */
828 if( nextavail > 0 ) {
836 ber_bvfree( assertv );
837 for( i=0; i<count; i++ ) {
838 ch_free( values[i] );
853 struct berval *prefix,
858 int i,j, len, wordcount, keycount=0;
859 struct berval *newkeys;
862 for( j=0; values[j].bv_val != NULL; j++ ) {
863 struct berval val = { 0, NULL };
864 /* Yes, this is necessary */
865 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
866 assert( val.bv_val != NULL );
868 /* Isolate how many words there are. There will be a key for each */
869 for( wordcount = 0, c = val.bv_val; *c; c++) {
870 len = strcspn(c, SLAPD_APPROX_DELIMITER);
871 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
873 if (*c == '\0') break;
877 /* Allocate/increase storage to account for new keys */
878 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
879 * sizeof(struct berval) );
880 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
881 if( keys ) ch_free( keys );
884 /* Get a phonetic copy of each word */
885 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
887 if( len < SLAPD_APPROX_WORDLEN ) continue;
888 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
893 ber_memfree( val.bv_val );
895 keys[keycount].bv_val = NULL;
907 struct berval *prefix,
908 void * assertedValue,
916 /* Yes, this is necessary */
917 val = UTF8bvnormalize( ((struct berval *)assertedValue),
918 NULL, LDAP_UTF8_APPROX );
919 if( val == NULL || val->bv_val == NULL ) {
920 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
921 keys[0].bv_val = NULL;
927 /* Isolate how many words there are. There will be a key for each */
928 for( count = 0,c = val->bv_val; *c; c++) {
929 len = strcspn(c, SLAPD_APPROX_DELIMITER);
930 if( len >= SLAPD_APPROX_WORDLEN ) count++;
932 if (*c == '\0') break;
936 /* Allocate storage for new keys */
937 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
939 /* Get a phonetic copy of each word */
940 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
942 if( len < SLAPD_APPROX_WORDLEN ) continue;
943 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
949 keys[count].bv_val = NULL;
957 /* No other form of Approximate Matching is defined */
965 struct berval *value,
966 void *assertedValue )
968 char *vapprox, *avapprox;
971 /* Yes, this is necessary */
972 s = UTF8normalize( value, UTF8_NOCASEFOLD );
978 /* Yes, this is necessary */
979 t = UTF8normalize( ((struct berval *)assertedValue),
987 vapprox = phonetic( strip8bitChars( s ) );
988 avapprox = phonetic( strip8bitChars( t ) );
993 *matchp = strcmp( vapprox, avapprox );
1007 struct berval *prefix,
1015 for( i=0; values[i].bv_val != NULL; i++ ) {
1016 /* empty - just count them */
1019 /* we should have at least one value at this point */
1022 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1024 /* Copy each value and run it through phonetic() */
1025 for( i=0; values[i].bv_val != NULL; i++ ) {
1026 /* Yes, this is necessary */
1027 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1029 /* strip 8-bit chars and run through phonetic() */
1030 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1033 keys[i].bv_val = NULL;
1036 return LDAP_SUCCESS;
1046 struct berval *prefix,
1047 void * assertedValue,
1053 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1055 /* Yes, this is necessary */
1056 s = UTF8normalize( ((struct berval *)assertedValue),
1061 /* strip 8-bit chars and run through phonetic() */
1062 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1068 return LDAP_SUCCESS;
1079 struct berval *value,
1080 void *assertedValue )
1082 *matchp = UTF8bvnormcmp( value,
1083 (struct berval *) assertedValue,
1084 LDAP_UTF8_NOCASEFOLD );
1085 return LDAP_SUCCESS;
1089 caseExactIgnoreSubstringsMatch(
1094 struct berval *value,
1095 void *assertedValue )
1098 SubstringsAssertion *sub = NULL;
1099 struct berval left = { 0, NULL };
1105 casefold = ( mr != caseExactSubstringsMatchingRule )
1106 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1108 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1114 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1120 /* Add up asserted input length */
1121 if( sub->sa_initial.bv_val ) {
1122 inlen += sub->sa_initial.bv_len;
1125 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1126 inlen += sub->sa_any[i].bv_len;
1129 if( sub->sa_final.bv_val ) {
1130 inlen += sub->sa_final.bv_len;
1133 if( sub->sa_initial.bv_val ) {
1134 if( inlen > left.bv_len ) {
1139 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1140 sub->sa_initial.bv_len );
1146 left.bv_val += sub->sa_initial.bv_len;
1147 left.bv_len -= sub->sa_initial.bv_len;
1148 inlen -= sub->sa_initial.bv_len;
1151 if( sub->sa_final.bv_val ) {
1152 if( inlen > left.bv_len ) {
1157 match = memcmp( sub->sa_final.bv_val,
1158 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1159 sub->sa_final.bv_len );
1165 left.bv_len -= sub->sa_final.bv_len;
1166 inlen -= sub->sa_final.bv_len;
1170 for(i=0; sub->sa_any[i].bv_val; i++) {
1175 if( inlen > left.bv_len ) {
1176 /* not enough length */
1181 if( sub->sa_any[i].bv_len == 0 ) {
1185 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1191 idx = p - left.bv_val;
1193 if( idx >= left.bv_len ) {
1194 /* this shouldn't happen */
1196 if ( sub->sa_final.bv_val )
1197 ch_free( sub->sa_final.bv_val );
1199 ber_bvarray_free( sub->sa_any );
1200 if ( sub->sa_initial.bv_val )
1201 ch_free( sub->sa_initial.bv_val );
1209 if( sub->sa_any[i].bv_len > left.bv_len ) {
1210 /* not enough left */
1215 match = memcmp( left.bv_val,
1216 sub->sa_any[i].bv_val,
1217 sub->sa_any[i].bv_len );
1225 left.bv_val += sub->sa_any[i].bv_len;
1226 left.bv_len -= sub->sa_any[i].bv_len;
1227 inlen -= sub->sa_any[i].bv_len;
1234 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1235 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1236 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1240 return LDAP_SUCCESS;
1243 /* Index generation function */
1244 static int caseExactIgnoreIndexer(
1249 struct berval *prefix,
1254 unsigned casefold,wasspace;
1257 HASH_CONTEXT HASHcontext;
1258 unsigned char HASHdigest[HASH_BYTES];
1259 struct berval digest;
1260 digest.bv_val = HASHdigest;
1261 digest.bv_len = sizeof(HASHdigest);
1263 for( i=0; values[i].bv_val != NULL; i++ ) {
1264 /* empty - just count them */
1267 /* we should have at least one value at this point */
1270 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1272 slen = syntax->ssyn_oidlen;
1273 mlen = mr->smr_oidlen;
1275 casefold = ( mr != caseExactMatchingRule )
1276 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1278 for( i=0; values[i].bv_val != NULL; i++ ) {
1279 struct berval value, nvalue;
1280 UTF8bvnormalize( &values[i], &value, casefold );
1282 /* collapse spaces (in place) */
1284 nvalue.bv_val = value.bv_val;
1287 for( j=0; j<value.bv_len; j++) {
1288 if ( ASCII_SPACE( value.bv_val[j] )) {
1289 if( wasspace++ == 0 ) {
1290 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1294 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1298 if( nvalue.bv_len == 0 ) {
1299 nvalue.bv_val = " ";
1300 nvalue.bv_len = sizeof(" ")-1;
1302 if( wasspace ) --nvalue.bv_len;
1303 nvalue.bv_val[nvalue.bv_len] = '\0';
1306 HASH_Init( &HASHcontext );
1307 if( prefix != NULL && prefix->bv_len > 0 ) {
1308 HASH_Update( &HASHcontext,
1309 prefix->bv_val, prefix->bv_len );
1311 HASH_Update( &HASHcontext,
1312 syntax->ssyn_oid, slen );
1313 HASH_Update( &HASHcontext,
1314 mr->smr_oid, mlen );
1315 HASH_Update( &HASHcontext,
1316 nvalue.bv_val, nvalue.bv_len );
1317 HASH_Final( HASHdigest, &HASHcontext );
1319 free( value.bv_val );
1320 ber_dupbv( &keys[i], &digest );
1323 keys[i].bv_val = NULL;
1325 return LDAP_SUCCESS;
1328 /* Index generation function */
1329 static int caseExactIgnoreFilter(
1334 struct berval *prefix,
1335 void * assertedValue,
1341 HASH_CONTEXT HASHcontext;
1342 unsigned char HASHdigest[HASH_BYTES];
1343 struct berval value = { 0, NULL };
1344 struct berval digest;
1346 digest.bv_val = HASHdigest;
1347 digest.bv_len = sizeof(HASHdigest);
1349 slen = syntax->ssyn_oidlen;
1350 mlen = mr->smr_oidlen;
1352 casefold = ( mr != caseExactMatchingRule )
1353 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1355 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1356 /* This usually happens if filter contains bad UTF8 */
1357 if( value.bv_val == NULL ) {
1358 keys = ch_malloc( sizeof( struct berval ) );
1359 keys[0].bv_val = NULL;
1360 return LDAP_SUCCESS;
1363 keys = ch_malloc( sizeof( struct berval ) * 2 );
1365 HASH_Init( &HASHcontext );
1366 if( prefix != NULL && prefix->bv_len > 0 ) {
1367 HASH_Update( &HASHcontext,
1368 prefix->bv_val, prefix->bv_len );
1370 HASH_Update( &HASHcontext,
1371 syntax->ssyn_oid, slen );
1372 HASH_Update( &HASHcontext,
1373 mr->smr_oid, mlen );
1374 HASH_Update( &HASHcontext,
1375 value.bv_val, value.bv_len );
1376 HASH_Final( HASHdigest, &HASHcontext );
1378 ber_dupbv( keys, &digest );
1379 keys[1].bv_val = NULL;
1381 free( value.bv_val );
1384 return LDAP_SUCCESS;
1387 /* Substrings Index generation function */
1388 static int caseExactIgnoreSubstringsIndexer(
1393 struct berval *prefix,
1397 unsigned casefold, wasspace;
1398 ber_len_t i, j, nkeys;
1401 BerVarray tvalues, nvalues;
1403 HASH_CONTEXT HASHcontext;
1404 unsigned char HASHdigest[HASH_BYTES];
1405 struct berval digest;
1406 digest.bv_val = HASHdigest;
1407 digest.bv_len = sizeof(HASHdigest);
1411 for( i=0; values[i].bv_val != NULL; i++ ) {
1412 /* empty - just count them */
1415 /* we should have at least one value at this point */
1418 casefold = ( mr != caseExactSubstringsMatchingRule )
1419 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1421 tvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1422 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1424 for( i=0; values[i].bv_val != NULL; i++ ) {
1425 UTF8bvnormalize( &values[i], &tvalues[i], casefold );
1427 /* collapse spaces (in place) */
1428 nvalues[i].bv_len = 0;
1429 nvalues[i].bv_val = tvalues[i].bv_val;
1432 for( j=0; j<tvalues[i].bv_len; j++) {
1433 if ( ASCII_SPACE( tvalues[i].bv_val[j] )) {
1434 if( wasspace++ == 0 ) {
1435 nvalues[i].bv_val[nvalues[i].bv_len++] =
1436 tvalues[i].bv_val[j];
1440 nvalues[i].bv_val[nvalues[i].bv_len++] = tvalues[i].bv_val[j];
1444 if( nvalues[i].bv_len == 0 ) {
1445 nvalues[i].bv_val = " ";
1446 nvalues[i].bv_len = sizeof(" ")-1;
1448 if( wasspace ) --nvalues[i].bv_len;
1449 nvalues[i].bv_val[nvalues[i].bv_len] = '\0';
1453 tvalues[i].bv_val = NULL;
1454 nvalues[i].bv_val = NULL;
1457 for( i=0; values[i].bv_val != NULL; i++ ) {
1458 /* count number of indices to generate */
1459 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1463 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1464 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1465 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1466 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1468 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1472 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1473 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1474 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1478 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1479 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1480 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1481 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1483 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1489 /* no keys to generate */
1491 ber_bvarray_free( tvalues );
1493 return LDAP_SUCCESS;
1496 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1498 slen = syntax->ssyn_oidlen;
1499 mlen = mr->smr_oidlen;
1502 for( i=0; values[i].bv_val != NULL; i++ ) {
1505 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1507 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1508 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1510 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1511 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1513 for( j=0; j<max; j++ ) {
1514 HASH_Init( &HASHcontext );
1515 if( prefix != NULL && prefix->bv_len > 0 ) {
1516 HASH_Update( &HASHcontext,
1517 prefix->bv_val, prefix->bv_len );
1520 HASH_Update( &HASHcontext,
1521 &pre, sizeof( pre ) );
1522 HASH_Update( &HASHcontext,
1523 syntax->ssyn_oid, slen );
1524 HASH_Update( &HASHcontext,
1525 mr->smr_oid, mlen );
1526 HASH_Update( &HASHcontext,
1527 &values[i].bv_val[j],
1528 SLAP_INDEX_SUBSTR_MAXLEN );
1529 HASH_Final( HASHdigest, &HASHcontext );
1531 ber_dupbv( &keys[nkeys++], &digest );
1535 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1536 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1538 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1541 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1542 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1543 HASH_Init( &HASHcontext );
1544 if( prefix != NULL && prefix->bv_len > 0 ) {
1545 HASH_Update( &HASHcontext,
1546 prefix->bv_val, prefix->bv_len );
1548 HASH_Update( &HASHcontext,
1549 &pre, sizeof( pre ) );
1550 HASH_Update( &HASHcontext,
1551 syntax->ssyn_oid, slen );
1552 HASH_Update( &HASHcontext,
1553 mr->smr_oid, mlen );
1554 HASH_Update( &HASHcontext,
1555 values[i].bv_val, j );
1556 HASH_Final( HASHdigest, &HASHcontext );
1558 ber_dupbv( &keys[nkeys++], &digest );
1561 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1562 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1563 HASH_Init( &HASHcontext );
1564 if( prefix != NULL && prefix->bv_len > 0 ) {
1565 HASH_Update( &HASHcontext,
1566 prefix->bv_val, prefix->bv_len );
1568 HASH_Update( &HASHcontext,
1569 &pre, sizeof( pre ) );
1570 HASH_Update( &HASHcontext,
1571 syntax->ssyn_oid, slen );
1572 HASH_Update( &HASHcontext,
1573 mr->smr_oid, mlen );
1574 HASH_Update( &HASHcontext,
1575 &values[i].bv_val[values[i].bv_len-j], j );
1576 HASH_Final( HASHdigest, &HASHcontext );
1578 ber_dupbv( &keys[nkeys++], &digest );
1586 keys[nkeys].bv_val = NULL;
1593 ber_bvarray_free( tvalues );
1596 return LDAP_SUCCESS;
1599 static int caseExactIgnoreSubstringsFilter(
1604 struct berval *prefix,
1605 void * assertedValue,
1608 SubstringsAssertion *sa;
1611 ber_len_t nkeys = 0;
1612 size_t slen, mlen, klen;
1614 HASH_CONTEXT HASHcontext;
1615 unsigned char HASHdigest[HASH_BYTES];
1616 struct berval *value;
1617 struct berval digest;
1619 casefold = ( mr != caseExactSubstringsMatchingRule )
1620 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1622 sa = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1625 return LDAP_SUCCESS;
1628 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1629 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1634 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1636 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1637 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1638 /* don't bother accounting for stepping */
1639 nkeys += sa->sa_any[i].bv_len -
1640 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1645 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1646 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1652 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1653 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1654 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1657 return LDAP_SUCCESS;
1660 digest.bv_val = HASHdigest;
1661 digest.bv_len = sizeof(HASHdigest);
1663 slen = syntax->ssyn_oidlen;
1664 mlen = mr->smr_oidlen;
1666 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1669 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1670 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1672 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1673 value = &sa->sa_initial;
1675 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1676 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1678 HASH_Init( &HASHcontext );
1679 if( prefix != NULL && prefix->bv_len > 0 ) {
1680 HASH_Update( &HASHcontext,
1681 prefix->bv_val, prefix->bv_len );
1683 HASH_Update( &HASHcontext,
1684 &pre, sizeof( pre ) );
1685 HASH_Update( &HASHcontext,
1686 syntax->ssyn_oid, slen );
1687 HASH_Update( &HASHcontext,
1688 mr->smr_oid, mlen );
1689 HASH_Update( &HASHcontext,
1690 value->bv_val, klen );
1691 HASH_Final( HASHdigest, &HASHcontext );
1693 ber_dupbv( &keys[nkeys++], &digest );
1696 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1698 pre = SLAP_INDEX_SUBSTR_PREFIX;
1699 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1701 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1702 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1706 value = &sa->sa_any[i];
1709 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1710 j += SLAP_INDEX_SUBSTR_STEP )
1712 HASH_Init( &HASHcontext );
1713 if( prefix != NULL && prefix->bv_len > 0 ) {
1714 HASH_Update( &HASHcontext,
1715 prefix->bv_val, prefix->bv_len );
1717 HASH_Update( &HASHcontext,
1718 &pre, sizeof( pre ) );
1719 HASH_Update( &HASHcontext,
1720 syntax->ssyn_oid, slen );
1721 HASH_Update( &HASHcontext,
1722 mr->smr_oid, mlen );
1723 HASH_Update( &HASHcontext,
1724 &value->bv_val[j], klen );
1725 HASH_Final( HASHdigest, &HASHcontext );
1727 ber_dupbv( &keys[nkeys++], &digest );
1733 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1734 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1736 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1737 value = &sa->sa_final;
1739 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1740 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1742 HASH_Init( &HASHcontext );
1743 if( prefix != NULL && prefix->bv_len > 0 ) {
1744 HASH_Update( &HASHcontext,
1745 prefix->bv_val, prefix->bv_len );
1747 HASH_Update( &HASHcontext,
1748 &pre, sizeof( pre ) );
1749 HASH_Update( &HASHcontext,
1750 syntax->ssyn_oid, slen );
1751 HASH_Update( &HASHcontext,
1752 mr->smr_oid, mlen );
1753 HASH_Update( &HASHcontext,
1754 &value->bv_val[value->bv_len-klen], klen );
1755 HASH_Final( HASHdigest, &HASHcontext );
1757 ber_dupbv( &keys[nkeys++], &digest );
1761 keys[nkeys].bv_val = NULL;
1767 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1768 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1769 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1772 return LDAP_SUCCESS;
1781 struct berval *value,
1782 void *assertedValue )
1784 *matchp = UTF8bvnormcmp( value,
1785 (struct berval *) assertedValue,
1786 LDAP_UTF8_CASEFOLD );
1787 return LDAP_SUCCESS;
1790 /* Remove all spaces and '-' characters */
1792 telephoneNumberNormalize(
1795 struct berval *normalized )
1799 /* validator should have refused an empty string */
1800 assert( val->bv_len );
1802 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
1804 for( p = val->bv_val; *p; p++ ) {
1805 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
1811 normalized->bv_len = q - normalized->bv_val;
1813 if( normalized->bv_len == 0 ) {
1814 free( normalized->bv_val );
1815 return LDAP_INVALID_SYNTAX;
1818 return LDAP_SUCCESS;
1824 struct berval *val )
1828 if( val->bv_len == 0 ) {
1829 /* disallow empty strings */
1830 return LDAP_INVALID_SYNTAX;
1833 if( OID_LEADCHAR(val->bv_val[0]) ) {
1835 for(i=1; i < val->bv_len; i++) {
1836 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1837 if( dot++ ) return 1;
1838 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1841 return LDAP_INVALID_SYNTAX;
1845 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1847 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1848 for(i=1; i < val->bv_len; i++) {
1849 if( !DESC_CHAR(val->bv_val[i] ) ) {
1850 return LDAP_INVALID_SYNTAX;
1854 return LDAP_SUCCESS;
1857 return LDAP_INVALID_SYNTAX;
1866 struct berval *value,
1867 void *assertedValue )
1870 int vsign = 1, avsign = 1; /* default sign = '+' */
1871 struct berval *asserted;
1872 ber_len_t vlen, avlen;
1875 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
1877 vlen = value->bv_len;
1878 if( mr == integerFirstComponentMatchingRule ) {
1879 char *tmp = memchr( v, '$', vlen );
1882 while( vlen && ASCII_SPACE( v[vlen-1] ))
1885 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
1891 /* Do the same with the *assertedValue number */
1892 asserted = (struct berval *) assertedValue;
1893 av = asserted->bv_val;
1894 avlen = asserted->bv_len;
1895 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
1901 match = vsign - avsign;
1903 match = (vlen != avlen
1904 ? ( vlen < avlen ? -1 : 1 )
1905 : memcmp( v, av, vlen ));
1911 return LDAP_SUCCESS;
1917 struct berval *val )
1921 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1923 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
1924 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1925 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1926 return LDAP_INVALID_SYNTAX;
1929 for( i=1; i < val->bv_len; i++ ) {
1930 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1933 return LDAP_SUCCESS;
1940 struct berval *normalized )
1950 /* Ignore leading spaces */
1951 while ( len && ( *p == ' ' )) {
1958 negative = ( *p == '-' );
1959 if(( *p == '-' ) || ( *p == '+' )) {
1965 /* Ignore leading zeros */
1966 while ( len && ( *p == '0' )) {
1971 /* If there are no non-zero digits left, the number is zero, otherwise
1972 allocate space for the number and copy it into the buffer */
1974 normalized->bv_val = ch_strdup("0");
1975 normalized->bv_len = 1;
1978 normalized->bv_len = len+negative;
1979 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
1981 normalized->bv_val[0] = '-';
1983 AC_MEMCPY( normalized->bv_val + negative, p, len );
1984 normalized->bv_val[len+negative] = '\0';
1987 return LDAP_SUCCESS;
1990 /* Index generation function */
1991 static int integerIndexer(
1996 struct berval *prefix,
2003 HASH_CONTEXT HASHcontext;
2004 unsigned char HASHdigest[HASH_BYTES];
2005 struct berval digest;
2006 digest.bv_val = HASHdigest;
2007 digest.bv_len = sizeof(HASHdigest);
2009 for( i=0; values[i].bv_val != NULL; i++ ) {
2010 /* empty - just count them */
2013 /* we should have at least one value at this point */
2016 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2018 slen = syntax->ssyn_oidlen;
2019 mlen = mr->smr_oidlen;
2021 for( i=0; values[i].bv_val != NULL; i++ ) {
2023 integerNormalize( syntax, &values[i], &norm );
2025 HASH_Init( &HASHcontext );
2026 if( prefix != NULL && prefix->bv_len > 0 ) {
2027 HASH_Update( &HASHcontext,
2028 prefix->bv_val, prefix->bv_len );
2030 HASH_Update( &HASHcontext,
2031 syntax->ssyn_oid, slen );
2032 HASH_Update( &HASHcontext,
2033 mr->smr_oid, mlen );
2034 HASH_Update( &HASHcontext,
2035 norm.bv_val, norm.bv_len );
2036 HASH_Final( HASHdigest, &HASHcontext );
2038 ber_dupbv( &keys[i], &digest );
2039 ch_free( norm.bv_val );
2042 keys[i].bv_val = NULL;
2044 return LDAP_SUCCESS;
2047 /* Index generation function */
2048 static int integerFilter(
2053 struct berval *prefix,
2054 void * assertedValue,
2059 HASH_CONTEXT HASHcontext;
2060 unsigned char HASHdigest[HASH_BYTES];
2062 struct berval digest;
2063 digest.bv_val = HASHdigest;
2064 digest.bv_len = sizeof(HASHdigest);
2066 slen = syntax->ssyn_oidlen;
2067 mlen = mr->smr_oidlen;
2069 integerNormalize( syntax, assertedValue, &norm );
2071 keys = ch_malloc( sizeof( struct berval ) * 2 );
2073 HASH_Init( &HASHcontext );
2074 if( prefix != NULL && prefix->bv_len > 0 ) {
2075 HASH_Update( &HASHcontext,
2076 prefix->bv_val, prefix->bv_len );
2078 HASH_Update( &HASHcontext,
2079 syntax->ssyn_oid, slen );
2080 HASH_Update( &HASHcontext,
2081 mr->smr_oid, mlen );
2082 HASH_Update( &HASHcontext,
2083 norm.bv_val, norm.bv_len );
2084 HASH_Final( HASHdigest, &HASHcontext );
2086 ber_dupbv( &keys[0], &digest );
2087 keys[1].bv_val = NULL;
2088 ch_free( norm.bv_val );
2091 return LDAP_SUCCESS;
2096 countryStringValidate(
2098 struct berval *val )
2100 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2102 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2103 return LDAP_INVALID_SYNTAX;
2105 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2106 return LDAP_INVALID_SYNTAX;
2109 return LDAP_SUCCESS;
2113 printableStringValidate(
2115 struct berval *val )
2119 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2121 for(i=0; i < val->bv_len; i++) {
2122 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2123 return LDAP_INVALID_SYNTAX;
2127 return LDAP_SUCCESS;
2131 printablesStringValidate(
2133 struct berval *val )
2137 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2139 for(i=0,len=0; i < val->bv_len; i++) {
2140 int c = val->bv_val[i];
2144 return LDAP_INVALID_SYNTAX;
2148 } else if ( SLAP_PRINTABLE(c) ) {
2151 return LDAP_INVALID_SYNTAX;
2156 return LDAP_INVALID_SYNTAX;
2159 return LDAP_SUCCESS;
2165 struct berval *val )
2169 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2171 for(i=0; i < val->bv_len; i++) {
2172 if( !LDAP_ASCII(val->bv_val[i]) ) {
2173 return LDAP_INVALID_SYNTAX;
2177 return LDAP_SUCCESS;
2184 struct berval *normalized )
2188 assert( val->bv_len );
2192 /* Ignore initial whitespace */
2193 while ( ASCII_SPACE( *p ) ) {
2197 normalized->bv_val = ch_strdup( p );
2198 p = q = normalized->bv_val;
2201 if ( ASCII_SPACE( *p ) ) {
2204 /* Ignore the extra whitespace */
2205 while ( ASCII_SPACE( *p ) ) {
2213 assert( normalized->bv_val <= p );
2217 * If the string ended in space, backup the pointer one
2218 * position. One is enough because the above loop collapsed
2219 * all whitespace to a single space.
2222 if ( ASCII_SPACE( q[-1] ) ) {
2226 /* null terminate */
2229 normalized->bv_len = q - normalized->bv_val;
2231 if( normalized->bv_len == 0 ) {
2232 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2233 normalized->bv_val[0] = ' ';
2234 normalized->bv_val[1] = '\0';
2235 normalized->bv_len = 1;
2238 return LDAP_SUCCESS;
2247 struct berval *value,
2248 void *assertedValue )
2250 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2253 match = strncmp( value->bv_val,
2254 ((struct berval *) assertedValue)->bv_val,
2259 return LDAP_SUCCESS;
2263 caseExactIA5SubstringsMatch(
2268 struct berval *value,
2269 void *assertedValue )
2272 SubstringsAssertion *sub = assertedValue;
2273 struct berval left = *value;
2277 /* Add up asserted input length */
2278 if( sub->sa_initial.bv_val ) {
2279 inlen += sub->sa_initial.bv_len;
2282 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2283 inlen += sub->sa_any[i].bv_len;
2286 if( sub->sa_final.bv_val ) {
2287 inlen += sub->sa_final.bv_len;
2290 if( sub->sa_initial.bv_val ) {
2291 if( inlen > left.bv_len ) {
2296 match = strncmp( sub->sa_initial.bv_val, left.bv_val,
2297 sub->sa_initial.bv_len );
2303 left.bv_val += sub->sa_initial.bv_len;
2304 left.bv_len -= sub->sa_initial.bv_len;
2305 inlen -= sub->sa_initial.bv_len;
2308 if( sub->sa_final.bv_val ) {
2309 if( inlen > left.bv_len ) {
2314 match = strncmp( sub->sa_final.bv_val,
2315 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2316 sub->sa_final.bv_len );
2322 left.bv_len -= sub->sa_final.bv_len;
2323 inlen -= sub->sa_final.bv_len;
2327 for(i=0; sub->sa_any[i].bv_val; i++) {
2332 if( inlen > left.bv_len ) {
2333 /* not enough length */
2338 if( sub->sa_any[i].bv_len == 0 ) {
2342 p = strchr( left.bv_val, *sub->sa_any[i].bv_val );
2349 idx = p - left.bv_val;
2351 if( idx >= left.bv_len ) {
2352 /* this shouldn't happen */
2359 if( sub->sa_any[i].bv_len > left.bv_len ) {
2360 /* not enough left */
2365 match = strncmp( left.bv_val,
2366 sub->sa_any[i].bv_val,
2367 sub->sa_any[i].bv_len );
2375 left.bv_val += sub->sa_any[i].bv_len;
2376 left.bv_len -= sub->sa_any[i].bv_len;
2377 inlen -= sub->sa_any[i].bv_len;
2383 return LDAP_SUCCESS;
2386 /* Index generation function */
2387 static int caseExactIA5Indexer(
2392 struct berval *prefix,
2399 HASH_CONTEXT HASHcontext;
2400 unsigned char HASHdigest[HASH_BYTES];
2401 struct berval digest;
2402 digest.bv_val = HASHdigest;
2403 digest.bv_len = sizeof(HASHdigest);
2405 for( i=0; values[i].bv_val != NULL; i++ ) {
2406 /* empty - just count them */
2409 /* we should have at least one value at this point */
2412 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2414 slen = syntax->ssyn_oidlen;
2415 mlen = mr->smr_oidlen;
2417 for( i=0; values[i].bv_val != NULL; i++ ) {
2418 struct berval *value = &values[i];
2420 HASH_Init( &HASHcontext );
2421 if( prefix != NULL && prefix->bv_len > 0 ) {
2422 HASH_Update( &HASHcontext,
2423 prefix->bv_val, prefix->bv_len );
2425 HASH_Update( &HASHcontext,
2426 syntax->ssyn_oid, slen );
2427 HASH_Update( &HASHcontext,
2428 mr->smr_oid, mlen );
2429 HASH_Update( &HASHcontext,
2430 value->bv_val, value->bv_len );
2431 HASH_Final( HASHdigest, &HASHcontext );
2433 ber_dupbv( &keys[i], &digest );
2436 keys[i].bv_val = NULL;
2438 return LDAP_SUCCESS;
2441 /* Index generation function */
2442 static int caseExactIA5Filter(
2447 struct berval *prefix,
2448 void * assertedValue,
2453 HASH_CONTEXT HASHcontext;
2454 unsigned char HASHdigest[HASH_BYTES];
2455 struct berval *value;
2456 struct berval digest;
2457 digest.bv_val = HASHdigest;
2458 digest.bv_len = sizeof(HASHdigest);
2460 slen = syntax->ssyn_oidlen;
2461 mlen = mr->smr_oidlen;
2463 value = (struct berval *) assertedValue;
2465 keys = ch_malloc( sizeof( struct berval ) * 2 );
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 syntax->ssyn_oid, slen );
2474 HASH_Update( &HASHcontext,
2475 mr->smr_oid, mlen );
2476 HASH_Update( &HASHcontext,
2477 value->bv_val, value->bv_len );
2478 HASH_Final( HASHdigest, &HASHcontext );
2480 ber_dupbv( &keys[0], &digest );
2481 keys[1].bv_val = NULL;
2484 return LDAP_SUCCESS;
2487 /* Substrings Index generation function */
2488 static int caseExactIA5SubstringsIndexer(
2493 struct berval *prefix,
2500 HASH_CONTEXT HASHcontext;
2501 unsigned char HASHdigest[HASH_BYTES];
2502 struct berval digest;
2503 digest.bv_val = HASHdigest;
2504 digest.bv_len = sizeof(HASHdigest);
2506 /* we should have at least one value at this point */
2507 assert( values != NULL && values[0].bv_val != NULL );
2510 for( i=0; values[i].bv_val != NULL; i++ ) {
2511 /* count number of indices to generate */
2512 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2516 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2517 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2518 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2519 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2521 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2525 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2526 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2527 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2531 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2532 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2533 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2534 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2536 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2542 /* no keys to generate */
2544 return LDAP_SUCCESS;
2547 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2549 slen = syntax->ssyn_oidlen;
2550 mlen = mr->smr_oidlen;
2553 for( i=0; values[i].bv_val != NULL; i++ ) {
2555 struct berval *value;
2558 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2560 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2561 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2563 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2564 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2566 for( j=0; j<max; j++ ) {
2567 HASH_Init( &HASHcontext );
2568 if( prefix != NULL && prefix->bv_len > 0 ) {
2569 HASH_Update( &HASHcontext,
2570 prefix->bv_val, prefix->bv_len );
2573 HASH_Update( &HASHcontext,
2574 &pre, sizeof( pre ) );
2575 HASH_Update( &HASHcontext,
2576 syntax->ssyn_oid, slen );
2577 HASH_Update( &HASHcontext,
2578 mr->smr_oid, mlen );
2579 HASH_Update( &HASHcontext,
2581 SLAP_INDEX_SUBSTR_MAXLEN );
2582 HASH_Final( HASHdigest, &HASHcontext );
2584 ber_dupbv( &keys[nkeys++], &digest );
2588 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2589 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2591 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2594 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2595 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2596 HASH_Init( &HASHcontext );
2597 if( prefix != NULL && prefix->bv_len > 0 ) {
2598 HASH_Update( &HASHcontext,
2599 prefix->bv_val, prefix->bv_len );
2601 HASH_Update( &HASHcontext,
2602 &pre, sizeof( pre ) );
2603 HASH_Update( &HASHcontext,
2604 syntax->ssyn_oid, slen );
2605 HASH_Update( &HASHcontext,
2606 mr->smr_oid, mlen );
2607 HASH_Update( &HASHcontext,
2609 HASH_Final( HASHdigest, &HASHcontext );
2611 ber_dupbv( &keys[nkeys++], &digest );
2614 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2615 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2616 HASH_Init( &HASHcontext );
2617 if( prefix != NULL && prefix->bv_len > 0 ) {
2618 HASH_Update( &HASHcontext,
2619 prefix->bv_val, prefix->bv_len );
2621 HASH_Update( &HASHcontext,
2622 &pre, sizeof( pre ) );
2623 HASH_Update( &HASHcontext,
2624 syntax->ssyn_oid, slen );
2625 HASH_Update( &HASHcontext,
2626 mr->smr_oid, mlen );
2627 HASH_Update( &HASHcontext,
2628 &value->bv_val[value->bv_len-j], j );
2629 HASH_Final( HASHdigest, &HASHcontext );
2631 ber_dupbv( &keys[nkeys++], &digest );
2638 keys[nkeys].bv_val = NULL;
2645 return LDAP_SUCCESS;
2648 static int caseExactIA5SubstringsFilter(
2653 struct berval *prefix,
2654 void * assertedValue,
2657 SubstringsAssertion *sa = assertedValue;
2659 ber_len_t nkeys = 0;
2660 size_t slen, mlen, klen;
2662 HASH_CONTEXT HASHcontext;
2663 unsigned char HASHdigest[HASH_BYTES];
2664 struct berval *value;
2665 struct berval digest;
2667 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2668 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2673 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2675 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2676 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2677 /* don't bother accounting for stepping */
2678 nkeys += sa->sa_any[i].bv_len -
2679 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2684 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2685 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2692 return LDAP_SUCCESS;
2695 digest.bv_val = HASHdigest;
2696 digest.bv_len = sizeof(HASHdigest);
2698 slen = syntax->ssyn_oidlen;
2699 mlen = mr->smr_oidlen;
2701 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2704 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2705 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2707 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2708 value = &sa->sa_initial;
2710 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2711 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2713 HASH_Init( &HASHcontext );
2714 if( prefix != NULL && prefix->bv_len > 0 ) {
2715 HASH_Update( &HASHcontext,
2716 prefix->bv_val, prefix->bv_len );
2718 HASH_Update( &HASHcontext,
2719 &pre, sizeof( pre ) );
2720 HASH_Update( &HASHcontext,
2721 syntax->ssyn_oid, slen );
2722 HASH_Update( &HASHcontext,
2723 mr->smr_oid, mlen );
2724 HASH_Update( &HASHcontext,
2725 value->bv_val, klen );
2726 HASH_Final( HASHdigest, &HASHcontext );
2728 ber_dupbv( &keys[nkeys++], &digest );
2731 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2733 pre = SLAP_INDEX_SUBSTR_PREFIX;
2734 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2736 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2737 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2741 value = &sa->sa_any[i];
2744 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2745 j += SLAP_INDEX_SUBSTR_STEP )
2747 HASH_Init( &HASHcontext );
2748 if( prefix != NULL && prefix->bv_len > 0 ) {
2749 HASH_Update( &HASHcontext,
2750 prefix->bv_val, prefix->bv_len );
2752 HASH_Update( &HASHcontext,
2753 &pre, sizeof( pre ) );
2754 HASH_Update( &HASHcontext,
2755 syntax->ssyn_oid, slen );
2756 HASH_Update( &HASHcontext,
2757 mr->smr_oid, mlen );
2758 HASH_Update( &HASHcontext,
2759 &value->bv_val[j], klen );
2760 HASH_Final( HASHdigest, &HASHcontext );
2762 ber_dupbv( &keys[nkeys++], &digest );
2767 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2768 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2770 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2771 value = &sa->sa_final;
2773 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2774 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2776 HASH_Init( &HASHcontext );
2777 if( prefix != NULL && prefix->bv_len > 0 ) {
2778 HASH_Update( &HASHcontext,
2779 prefix->bv_val, prefix->bv_len );
2781 HASH_Update( &HASHcontext,
2782 &pre, sizeof( pre ) );
2783 HASH_Update( &HASHcontext,
2784 syntax->ssyn_oid, slen );
2785 HASH_Update( &HASHcontext,
2786 mr->smr_oid, mlen );
2787 HASH_Update( &HASHcontext,
2788 &value->bv_val[value->bv_len-klen], klen );
2789 HASH_Final( HASHdigest, &HASHcontext );
2791 ber_dupbv( &keys[nkeys++], &digest );
2795 keys[nkeys].bv_val = NULL;
2802 return LDAP_SUCCESS;
2811 struct berval *value,
2812 void *assertedValue )
2814 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2816 if( match == 0 && value->bv_len ) {
2817 match = strncasecmp( value->bv_val,
2818 ((struct berval *) assertedValue)->bv_val,
2823 return LDAP_SUCCESS;
2827 caseIgnoreIA5SubstringsMatch(
2832 struct berval *value,
2833 void *assertedValue )
2836 SubstringsAssertion *sub = assertedValue;
2837 struct berval left = *value;
2841 /* Add up asserted input length */
2842 if( sub->sa_initial.bv_val ) {
2843 inlen += sub->sa_initial.bv_len;
2846 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2847 inlen += sub->sa_any[i].bv_len;
2850 if( sub->sa_final.bv_val ) {
2851 inlen += sub->sa_final.bv_len;
2854 if( sub->sa_initial.bv_val ) {
2855 if( inlen > left.bv_len ) {
2860 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
2861 sub->sa_initial.bv_len );
2867 left.bv_val += sub->sa_initial.bv_len;
2868 left.bv_len -= sub->sa_initial.bv_len;
2869 inlen -= sub->sa_initial.bv_len;
2872 if( sub->sa_final.bv_val ) {
2873 if( inlen > left.bv_len ) {
2878 match = strncasecmp( sub->sa_final.bv_val,
2879 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2880 sub->sa_final.bv_len );
2886 left.bv_len -= sub->sa_final.bv_len;
2887 inlen -= sub->sa_final.bv_len;
2891 for(i=0; sub->sa_any[i].bv_val; i++) {
2896 if( inlen > left.bv_len ) {
2897 /* not enough length */
2902 if( sub->sa_any[i].bv_len == 0 ) {
2906 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
2913 assert( idx < left.bv_len );
2914 if( idx >= left.bv_len ) {
2915 /* this shouldn't happen */
2922 if( sub->sa_any[i].bv_len > left.bv_len ) {
2923 /* not enough left */
2928 match = strncasecmp( left.bv_val,
2929 sub->sa_any[i].bv_val,
2930 sub->sa_any[i].bv_len );
2939 left.bv_val += sub->sa_any[i].bv_len;
2940 left.bv_len -= sub->sa_any[i].bv_len;
2941 inlen -= sub->sa_any[i].bv_len;
2947 return LDAP_SUCCESS;
2950 /* Index generation function */
2951 static int caseIgnoreIA5Indexer(
2956 struct berval *prefix,
2961 int rc = LDAP_SUCCESS;
2964 HASH_CONTEXT HASHcontext;
2965 unsigned char HASHdigest[HASH_BYTES];
2966 struct berval digest;
2967 digest.bv_val = HASHdigest;
2968 digest.bv_len = sizeof(HASHdigest);
2970 /* we should have at least one value at this point */
2971 assert( values != NULL && values[0].bv_val != NULL );
2973 for( i=0; values[i].bv_val != NULL; i++ ) {
2974 /* just count them */
2977 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2979 slen = syntax->ssyn_oidlen;
2980 mlen = mr->smr_oidlen;
2982 for( i=0; values[i].bv_val != NULL; i++ ) {
2983 struct berval value;
2985 if( mr->smr_normalize ) {
2986 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
2987 if( rc != LDAP_SUCCESS ) {
2990 #ifndef SLAP_NVALUES
2991 } else if ( mr->smr_syntax->ssyn_normalize ) {
2992 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
2993 if( rc != LDAP_SUCCESS ) {
2998 ber_dupbv( &value, &values[i] );
3001 ldap_pvt_str2lower( value.bv_val );
3003 HASH_Init( &HASHcontext );
3004 if( prefix != NULL && prefix->bv_len > 0 ) {
3005 HASH_Update( &HASHcontext,
3006 prefix->bv_val, prefix->bv_len );
3008 HASH_Update( &HASHcontext,
3009 syntax->ssyn_oid, slen );
3010 HASH_Update( &HASHcontext,
3011 mr->smr_oid, mlen );
3012 HASH_Update( &HASHcontext,
3013 value.bv_val, value.bv_len );
3014 HASH_Final( HASHdigest, &HASHcontext );
3016 free( value.bv_val );
3018 ber_dupbv( &keys[i], &digest );
3021 keys[i].bv_val = NULL;
3022 if( rc != LDAP_SUCCESS ) {
3023 ber_bvarray_free( keys );
3030 /* Index generation function */
3031 static int caseIgnoreIA5Filter(
3036 struct berval *prefix,
3037 void * assertedValue,
3042 HASH_CONTEXT HASHcontext;
3043 unsigned char HASHdigest[HASH_BYTES];
3044 struct berval value;
3045 struct berval digest;
3046 digest.bv_val = HASHdigest;
3047 digest.bv_len = sizeof(HASHdigest);
3049 slen = syntax->ssyn_oidlen;
3050 mlen = mr->smr_oidlen;
3052 ber_dupbv( &value, (struct berval *) assertedValue );
3053 ldap_pvt_str2lower( value.bv_val );
3055 keys = ch_malloc( sizeof( struct berval ) * 2 );
3057 HASH_Init( &HASHcontext );
3058 if( prefix != NULL && prefix->bv_len > 0 ) {
3059 HASH_Update( &HASHcontext,
3060 prefix->bv_val, prefix->bv_len );
3062 HASH_Update( &HASHcontext,
3063 syntax->ssyn_oid, slen );
3064 HASH_Update( &HASHcontext,
3065 mr->smr_oid, mlen );
3066 HASH_Update( &HASHcontext,
3067 value.bv_val, value.bv_len );
3068 HASH_Final( HASHdigest, &HASHcontext );
3070 ber_dupbv( &keys[0], &digest );
3071 keys[1].bv_val = NULL;
3073 free( value.bv_val );
3077 return LDAP_SUCCESS;
3080 /* Substrings Index generation function */
3081 static int caseIgnoreIA5SubstringsIndexer(
3086 struct berval *prefix,
3093 HASH_CONTEXT HASHcontext;
3094 unsigned char HASHdigest[HASH_BYTES];
3095 struct berval digest;
3096 digest.bv_val = HASHdigest;
3097 digest.bv_len = sizeof(HASHdigest);
3099 /* we should have at least one value at this point */
3100 assert( values != NULL && values[0].bv_val != NULL );
3103 for( i=0; values[i].bv_val != NULL; i++ ) {
3104 /* count number of indices to generate */
3105 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3109 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3110 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3111 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3112 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3114 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3118 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3119 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3120 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3124 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3125 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3126 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3127 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3129 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3135 /* no keys to generate */
3137 return LDAP_SUCCESS;
3140 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3142 slen = syntax->ssyn_oidlen;
3143 mlen = mr->smr_oidlen;
3146 for( i=0; values[i].bv_val != NULL; i++ ) {
3148 struct berval value;
3150 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3152 ber_dupbv( &value, &values[i] );
3153 ldap_pvt_str2lower( value.bv_val );
3155 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3156 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3158 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3159 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3161 for( j=0; j<max; j++ ) {
3162 HASH_Init( &HASHcontext );
3163 if( prefix != NULL && prefix->bv_len > 0 ) {
3164 HASH_Update( &HASHcontext,
3165 prefix->bv_val, prefix->bv_len );
3168 HASH_Update( &HASHcontext,
3169 &pre, sizeof( pre ) );
3170 HASH_Update( &HASHcontext,
3171 syntax->ssyn_oid, slen );
3172 HASH_Update( &HASHcontext,
3173 mr->smr_oid, mlen );
3174 HASH_Update( &HASHcontext,
3176 SLAP_INDEX_SUBSTR_MAXLEN );
3177 HASH_Final( HASHdigest, &HASHcontext );
3179 ber_dupbv( &keys[nkeys++], &digest );
3183 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3184 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3186 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3189 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3190 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3191 HASH_Init( &HASHcontext );
3192 if( prefix != NULL && prefix->bv_len > 0 ) {
3193 HASH_Update( &HASHcontext,
3194 prefix->bv_val, prefix->bv_len );
3196 HASH_Update( &HASHcontext,
3197 &pre, sizeof( pre ) );
3198 HASH_Update( &HASHcontext,
3199 syntax->ssyn_oid, slen );
3200 HASH_Update( &HASHcontext,
3201 mr->smr_oid, mlen );
3202 HASH_Update( &HASHcontext,
3204 HASH_Final( HASHdigest, &HASHcontext );
3206 ber_dupbv( &keys[nkeys++], &digest );
3209 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3210 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3211 HASH_Init( &HASHcontext );
3212 if( prefix != NULL && prefix->bv_len > 0 ) {
3213 HASH_Update( &HASHcontext,
3214 prefix->bv_val, prefix->bv_len );
3216 HASH_Update( &HASHcontext,
3217 &pre, sizeof( pre ) );
3218 HASH_Update( &HASHcontext,
3219 syntax->ssyn_oid, slen );
3220 HASH_Update( &HASHcontext,
3221 mr->smr_oid, mlen );
3222 HASH_Update( &HASHcontext,
3223 &value.bv_val[value.bv_len-j], j );
3224 HASH_Final( HASHdigest, &HASHcontext );
3226 ber_dupbv( &keys[nkeys++], &digest );
3231 free( value.bv_val );
3235 keys[nkeys].bv_val = NULL;
3242 return LDAP_SUCCESS;
3245 static int caseIgnoreIA5SubstringsFilter(
3250 struct berval *prefix,
3251 void * assertedValue,
3254 SubstringsAssertion *sa = assertedValue;
3256 ber_len_t nkeys = 0;
3257 size_t slen, mlen, klen;
3259 HASH_CONTEXT HASHcontext;
3260 unsigned char HASHdigest[HASH_BYTES];
3261 struct berval value;
3262 struct berval digest;
3264 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3265 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3270 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3272 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3273 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3274 /* don't bother accounting for stepping */
3275 nkeys += sa->sa_any[i].bv_len -
3276 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3281 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3282 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3289 return LDAP_SUCCESS;
3292 digest.bv_val = HASHdigest;
3293 digest.bv_len = sizeof(HASHdigest);
3295 slen = syntax->ssyn_oidlen;
3296 mlen = mr->smr_oidlen;
3298 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3301 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3302 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3304 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3305 ber_dupbv( &value, &sa->sa_initial );
3306 ldap_pvt_str2lower( value.bv_val );
3308 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3309 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3311 HASH_Init( &HASHcontext );
3312 if( prefix != NULL && prefix->bv_len > 0 ) {
3313 HASH_Update( &HASHcontext,
3314 prefix->bv_val, prefix->bv_len );
3316 HASH_Update( &HASHcontext,
3317 &pre, sizeof( pre ) );
3318 HASH_Update( &HASHcontext,
3319 syntax->ssyn_oid, slen );
3320 HASH_Update( &HASHcontext,
3321 mr->smr_oid, mlen );
3322 HASH_Update( &HASHcontext,
3323 value.bv_val, klen );
3324 HASH_Final( HASHdigest, &HASHcontext );
3326 free( value.bv_val );
3327 ber_dupbv( &keys[nkeys++], &digest );
3330 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3332 pre = SLAP_INDEX_SUBSTR_PREFIX;
3333 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3335 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3336 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3340 ber_dupbv( &value, &sa->sa_any[i] );
3341 ldap_pvt_str2lower( value.bv_val );
3344 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3345 j += SLAP_INDEX_SUBSTR_STEP )
3347 HASH_Init( &HASHcontext );
3348 if( prefix != NULL && prefix->bv_len > 0 ) {
3349 HASH_Update( &HASHcontext,
3350 prefix->bv_val, prefix->bv_len );
3352 HASH_Update( &HASHcontext,
3353 &pre, sizeof( pre ) );
3354 HASH_Update( &HASHcontext,
3355 syntax->ssyn_oid, slen );
3356 HASH_Update( &HASHcontext,
3357 mr->smr_oid, mlen );
3358 HASH_Update( &HASHcontext,
3359 &value.bv_val[j], klen );
3360 HASH_Final( HASHdigest, &HASHcontext );
3362 ber_dupbv( &keys[nkeys++], &digest );
3365 free( value.bv_val );
3369 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3370 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3372 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3373 ber_dupbv( &value, &sa->sa_final );
3374 ldap_pvt_str2lower( value.bv_val );
3376 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3377 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3379 HASH_Init( &HASHcontext );
3380 if( prefix != NULL && prefix->bv_len > 0 ) {
3381 HASH_Update( &HASHcontext,
3382 prefix->bv_val, prefix->bv_len );
3384 HASH_Update( &HASHcontext,
3385 &pre, sizeof( pre ) );
3386 HASH_Update( &HASHcontext,
3387 syntax->ssyn_oid, slen );
3388 HASH_Update( &HASHcontext,
3389 mr->smr_oid, mlen );
3390 HASH_Update( &HASHcontext,
3391 &value.bv_val[value.bv_len-klen], klen );
3392 HASH_Final( HASHdigest, &HASHcontext );
3394 free( value.bv_val );
3395 ber_dupbv( &keys[nkeys++], &digest );
3399 keys[nkeys].bv_val = NULL;
3406 return LDAP_SUCCESS;
3410 numericStringValidate(
3416 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3418 for(i=0; i < in->bv_len; i++) {
3419 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3420 return LDAP_INVALID_SYNTAX;
3424 return LDAP_SUCCESS;
3428 numericStringNormalize(
3431 struct berval *normalized )
3433 /* removal all spaces */
3436 assert( val->bv_len );
3438 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3441 q = normalized->bv_val;
3444 if ( ASCII_SPACE( *p ) ) {
3445 /* Ignore whitespace */
3452 /* we should have copied no more then is in val */
3453 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3455 /* null terminate */
3458 normalized->bv_len = q - normalized->bv_val;
3460 if( normalized->bv_len == 0 ) {
3461 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3462 normalized->bv_val[0] = ' ';
3463 normalized->bv_val[1] = '\0';
3464 normalized->bv_len = 1;
3467 return LDAP_SUCCESS;
3471 objectIdentifierFirstComponentMatch(
3476 struct berval *value,
3477 void *assertedValue )
3479 int rc = LDAP_SUCCESS;
3481 struct berval *asserted = (struct berval *) assertedValue;
3485 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3486 return LDAP_INVALID_SYNTAX;
3489 /* trim leading white space */
3490 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3494 /* grab next word */
3495 oid.bv_val = &value->bv_val[i];
3496 j = value->bv_len - i;
3497 for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
3502 /* insert attributeTypes, objectclass check here */
3503 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3504 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3507 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3508 MatchingRule *asserted_mr = mr_bvfind( asserted );
3509 MatchingRule *stored_mr = mr_bvfind( &oid );
3511 if( asserted_mr == NULL ) {
3512 rc = SLAPD_COMPARE_UNDEFINED;
3514 match = asserted_mr != stored_mr;
3517 } else if ( !strcmp( syntax->ssyn_oid,
3518 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3520 AttributeType *asserted_at = at_bvfind( asserted );
3521 AttributeType *stored_at = at_bvfind( &oid );
3523 if( asserted_at == NULL ) {
3524 rc = SLAPD_COMPARE_UNDEFINED;
3526 match = asserted_at != stored_at;
3529 } else if ( !strcmp( syntax->ssyn_oid,
3530 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3532 ObjectClass *asserted_oc = oc_bvfind( asserted );
3533 ObjectClass *stored_oc = oc_bvfind( &oid );
3535 if( asserted_oc == NULL ) {
3536 rc = SLAPD_COMPARE_UNDEFINED;
3538 match = asserted_oc != stored_oc;
3544 LDAP_LOG( CONFIG, ENTRY,
3545 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3546 match, value->bv_val, asserted->bv_val );
3548 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3549 "%d\n\t\"%s\"\n\t\"%s\"\n",
3550 match, value->bv_val, asserted->bv_val );
3553 if( rc == LDAP_SUCCESS ) *matchp = match;
3563 struct berval *value,
3564 void *assertedValue )
3566 long lValue, lAssertedValue;
3568 /* safe to assume integers are NUL terminated? */
3569 lValue = strtol(value->bv_val, NULL, 10);
3570 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3571 return LDAP_CONSTRAINT_VIOLATION;
3574 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3575 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3576 && errno == ERANGE )
3578 return LDAP_CONSTRAINT_VIOLATION;
3581 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3582 return LDAP_SUCCESS;
3591 struct berval *value,
3592 void *assertedValue )
3594 long lValue, lAssertedValue;
3596 /* safe to assume integers are NUL terminated? */
3597 lValue = strtol(value->bv_val, NULL, 10);
3598 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3599 return LDAP_CONSTRAINT_VIOLATION;
3602 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3603 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3604 && errno == ERANGE )
3606 return LDAP_CONSTRAINT_VIOLATION;
3609 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3610 return LDAP_SUCCESS;
3614 #include <openssl/x509.h>
3615 #include <openssl/err.h>
3618 * Next function returns a string representation of a ASN1_INTEGER.
3619 * It works for unlimited lengths.
3622 static struct berval *
3623 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3627 static char digit[] = "0123456789";
3629 /* We work backwards, make it fill from the end of buf */
3630 p = buf + sizeof(buf) - 1;
3633 if ( a == NULL || a->length == 0 ) {
3641 /* We want to preserve the original */
3642 copy = ch_malloc(n*sizeof(unsigned int));
3643 for (i = 0; i<n; i++) {
3644 copy[i] = a->data[i];
3648 * base indicates the index of the most significant
3649 * byte that might be nonzero. When it goes off the
3650 * end, we now there is nothing left to do.
3656 for (i = base; i<n; i++ ) {
3657 copy[i] += carry*256;
3658 carry = copy[i] % 10;
3663 * Way too large, we need to leave
3664 * room for sign if negative
3669 *--p = digit[carry];
3671 if (copy[base] == 0) base++;
3676 if ( a->type == V_ASN1_NEG_INTEGER ) {
3680 return ber_str2bv( p, 0, 1, bv );
3684 * Given a certificate in DER format, extract the corresponding
3685 * assertion value for certificateExactMatch
3688 certificateExactConvert(
3690 struct berval * out )
3693 unsigned char *p = in->bv_val;
3694 struct berval serial;
3695 struct berval issuer_dn;
3697 xcert = d2i_X509(NULL, &p, in->bv_len);
3700 LDAP_LOG( CONFIG, ENTRY,
3701 "certificateExactConvert: error parsing cert: %s\n",
3702 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3704 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3705 "error parsing cert: %s\n",
3706 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3708 return LDAP_INVALID_SYNTAX;
3711 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3713 return LDAP_INVALID_SYNTAX;
3715 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
3719 ber_memfree(serial.bv_val);
3720 return LDAP_INVALID_SYNTAX;
3725 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
3726 out->bv_val = ch_malloc(out->bv_len);
3728 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
3730 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
3732 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
3733 p += issuer_dn.bv_len;
3737 LDAP_LOG( CONFIG, ARGS,
3738 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
3740 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3742 out->bv_val, NULL, NULL );
3745 ber_memfree(serial.bv_val);
3746 ber_memfree(issuer_dn.bv_val);
3748 return LDAP_SUCCESS;
3752 serial_and_issuer_parse(
3753 struct berval *assertion,
3754 struct berval *serial,
3755 struct berval *issuer_dn
3763 begin = assertion->bv_val;
3764 end = assertion->bv_val+assertion->bv_len-1;
3765 for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
3766 if ( p > end ) return LDAP_INVALID_SYNTAX;
3768 /* p now points at the $ sign, now use
3769 * begin and end to delimit the serial number
3771 while (ASCII_SPACE(*begin)) begin++;
3773 while (ASCII_SPACE(*end)) end--;
3775 if( end <= begin ) return LDAP_INVALID_SYNTAX;
3777 bv.bv_len = end-begin+1;
3779 ber_dupbv(serial, &bv);
3781 /* now extract the issuer, remember p was at the dollar sign */
3783 end = assertion->bv_val+assertion->bv_len-1;
3784 while (ASCII_SPACE(*begin)) begin++;
3785 /* should we trim spaces at the end too? is it safe always? no, no */
3787 if( end <= begin ) return LDAP_INVALID_SYNTAX;
3790 bv.bv_len = end-begin+1;
3793 dnNormalize2( NULL, &bv, issuer_dn );
3796 return LDAP_SUCCESS;
3800 certificateExactMatch(
3805 struct berval *value,
3806 void *assertedValue )
3809 unsigned char *p = value->bv_val;
3810 struct berval serial;
3811 struct berval issuer_dn;
3812 struct berval asserted_serial;
3813 struct berval asserted_issuer_dn;
3816 xcert = d2i_X509(NULL, &p, value->bv_len);
3819 LDAP_LOG( CONFIG, ENTRY,
3820 "certificateExactMatch: error parsing cert: %s\n",
3821 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3823 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
3824 "error parsing cert: %s\n",
3825 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3827 return LDAP_INVALID_SYNTAX;
3830 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3831 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
3835 serial_and_issuer_parse(assertedValue,
3836 &asserted_serial, &asserted_issuer_dn);
3841 slap_schema.si_syn_integer,
3842 slap_schema.si_mr_integerMatch,
3845 if ( ret == LDAP_SUCCESS ) {
3846 if ( *matchp == 0 ) {
3847 /* We need to normalize everything for dnMatch */
3851 slap_schema.si_syn_distinguishedName,
3852 slap_schema.si_mr_distinguishedNameMatch,
3854 &asserted_issuer_dn);
3859 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
3860 "%d\n\t\"%s $ %s\"\n",
3861 *matchp, serial.bv_val, issuer_dn.bv_val );
3862 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
3863 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3866 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3867 "%d\n\t\"%s $ %s\"\n",
3868 *matchp, serial.bv_val, issuer_dn.bv_val );
3869 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3870 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
3874 ber_memfree(serial.bv_val);
3875 ber_memfree(issuer_dn.bv_val);
3876 ber_memfree(asserted_serial.bv_val);
3877 ber_memfree(asserted_issuer_dn.bv_val);
3883 * Index generation function
3884 * We just index the serials, in most scenarios the issuer DN is one of
3885 * a very small set of values.
3887 static int certificateExactIndexer(
3892 struct berval *prefix,
3900 struct berval serial;
3902 /* we should have at least one value at this point */
3903 assert( values != NULL && values[0].bv_val != NULL );
3905 for( i=0; values[i].bv_val != NULL; i++ ) {
3906 /* empty -- just count them */
3909 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3911 for( i=0; values[i].bv_val != NULL; i++ ) {
3912 p = values[i].bv_val;
3913 xcert = d2i_X509(NULL, &p, values[i].bv_len);
3916 LDAP_LOG( CONFIG, ENTRY,
3917 "certificateExactIndexer: error parsing cert: %s\n",
3918 ERR_error_string(ERR_get_error(),NULL), 0, 0);
3920 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3921 "error parsing cert: %s\n",
3922 ERR_error_string(ERR_get_error(),NULL),
3925 /* Do we leak keys on error? */
3926 return LDAP_INVALID_SYNTAX;
3929 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
3931 integerNormalize( slap_schema.si_syn_integer,
3932 &serial, &keys[i] );
3933 ber_memfree(serial.bv_val);
3935 LDAP_LOG( CONFIG, ENTRY,
3936 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
3938 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3945 keys[i].bv_val = NULL;
3947 return LDAP_SUCCESS;
3950 /* Index generation function */
3951 /* We think this is always called with a value in matching rule syntax */
3952 static int certificateExactFilter(
3957 struct berval *prefix,
3958 void * assertedValue,
3962 struct berval asserted_serial;
3965 ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
3966 if( ret != LDAP_SUCCESS ) return ret;
3968 keys = ch_malloc( sizeof( struct berval ) * 2 );
3969 integerNormalize( syntax, &asserted_serial, &keys[0] );
3970 keys[1].bv_val = NULL;
3973 ber_memfree(asserted_serial.bv_val);
3974 return LDAP_SUCCESS;
3979 check_time_syntax (struct berval *val,
3983 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3984 static int mdays[2][12] = {
3985 /* non-leap years */
3986 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3988 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3991 int part, c, tzoffset, leapyear = 0 ;
3993 if( val->bv_len == 0 ) {
3994 return LDAP_INVALID_SYNTAX;
3997 p = (char *)val->bv_val;
3998 e = p + val->bv_len;
4000 /* Ignore initial whitespace */
4001 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4005 if (e - p < 13 - (2 * start)) {
4006 return LDAP_INVALID_SYNTAX;
4009 for (part = 0; part < 9; part++) {
4013 for (part = start; part < 7; part++) {
4015 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4022 return LDAP_INVALID_SYNTAX;
4024 if (c < 0 || c > 9) {
4025 return LDAP_INVALID_SYNTAX;
4031 return LDAP_INVALID_SYNTAX;
4033 if (c < 0 || c > 9) {
4034 return LDAP_INVALID_SYNTAX;
4039 if (part == 2 || part == 3) {
4042 if (parts[part] < 0) {
4043 return LDAP_INVALID_SYNTAX;
4045 if (parts[part] > ceiling[part]) {
4046 return LDAP_INVALID_SYNTAX;
4050 /* leapyear check for the Gregorian calendar (year>1581) */
4051 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4052 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4057 if (parts[3] > mdays[leapyear][parts[2]]) {
4058 return LDAP_INVALID_SYNTAX;
4063 tzoffset = 0; /* UTC */
4064 } else if (c != '+' && c != '-') {
4065 return LDAP_INVALID_SYNTAX;
4069 } else /* c == '+' */ {
4074 return LDAP_INVALID_SYNTAX;
4077 for (part = 7; part < 9; part++) {
4079 if (c < 0 || c > 9) {
4080 return LDAP_INVALID_SYNTAX;
4085 if (c < 0 || c > 9) {
4086 return LDAP_INVALID_SYNTAX;
4090 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4091 return LDAP_INVALID_SYNTAX;
4096 /* Ignore trailing whitespace */
4097 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4101 return LDAP_INVALID_SYNTAX;
4104 switch ( tzoffset ) {
4105 case -1: /* negativ offset to UTC, ie west of Greenwich */
4106 parts[4] += parts[7];
4107 parts[5] += parts[8];
4108 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4112 c = mdays[leapyear][parts[2]];
4114 if (parts[part] > c) {
4115 parts[part] -= c + 1;
4120 case 1: /* positive offset to UTC, ie east of Greenwich */
4121 parts[4] -= parts[7];
4122 parts[5] -= parts[8];
4123 for (part = 6; --part > 0; ) {
4127 /* first arg to % needs to be non negativ */
4128 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4130 if (parts[part] < 0) {
4131 parts[part] += c + 1;
4136 case 0: /* already UTC */
4140 return LDAP_SUCCESS;
4143 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4148 struct berval *normalized )
4152 rc = check_time_syntax(val, 1, parts);
4153 if (rc != LDAP_SUCCESS) {
4157 normalized->bv_val = ch_malloc( 14 );
4158 if ( normalized->bv_val == NULL ) {
4159 return LBER_ERROR_MEMORY;
4162 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4163 parts[1], parts[2] + 1, parts[3] + 1,
4164 parts[4], parts[5], parts[6] );
4165 normalized->bv_len = 13;
4167 return LDAP_SUCCESS;
4171 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4179 return check_time_syntax(in, 1, parts);
4184 generalizedTimeValidate(
4190 return check_time_syntax(in, 0, parts);
4194 generalizedTimeNormalize(
4197 struct berval *normalized )
4201 rc = check_time_syntax(val, 0, parts);
4202 if (rc != LDAP_SUCCESS) {
4206 normalized->bv_val = ch_malloc( 16 );
4207 if ( normalized->bv_val == NULL ) {
4208 return LBER_ERROR_MEMORY;
4211 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4212 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4213 parts[4], parts[5], parts[6] );
4214 normalized->bv_len = 15;
4216 return LDAP_SUCCESS;
4220 nisNetgroupTripleValidate(
4222 struct berval *val )
4227 if ( val->bv_len == 0 ) {
4228 return LDAP_INVALID_SYNTAX;
4231 p = (char *)val->bv_val;
4232 e = p + val->bv_len;
4234 if ( *p != '(' /*')'*/ ) {
4235 return LDAP_INVALID_SYNTAX;
4238 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4242 return LDAP_INVALID_SYNTAX;
4245 } else if ( !AD_CHAR( *p ) ) {
4246 return LDAP_INVALID_SYNTAX;
4250 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4251 return LDAP_INVALID_SYNTAX;
4257 return LDAP_INVALID_SYNTAX;
4260 return LDAP_SUCCESS;
4264 bootParameterValidate(
4266 struct berval *val )
4270 if ( val->bv_len == 0 ) {
4271 return LDAP_INVALID_SYNTAX;
4274 p = (char *)val->bv_val;
4275 e = p + val->bv_len;
4278 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4279 if ( !AD_CHAR( *p ) ) {
4280 return LDAP_INVALID_SYNTAX;
4285 return LDAP_INVALID_SYNTAX;
4289 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4290 if ( !AD_CHAR( *p ) ) {
4291 return LDAP_INVALID_SYNTAX;
4296 return LDAP_INVALID_SYNTAX;
4300 for ( p++; p < e; p++ ) {
4301 if ( !SLAP_PRINTABLE( *p ) ) {
4302 return LDAP_INVALID_SYNTAX;
4306 return LDAP_SUCCESS;
4309 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4310 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4312 static slap_syntax_defs_rec syntax_defs[] = {
4313 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4314 X_BINARY X_NOT_H_R ")",
4315 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4316 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4317 0, NULL, NULL, NULL},
4318 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4319 0, NULL, NULL, NULL},
4320 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4322 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4323 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4325 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4326 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4327 0, bitStringValidate, NULL, NULL },
4328 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4329 0, booleanValidate, NULL, NULL},
4330 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4331 X_BINARY X_NOT_H_R ")",
4332 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4333 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4334 X_BINARY X_NOT_H_R ")",
4335 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4336 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4337 X_BINARY X_NOT_H_R ")",
4338 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4339 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4340 0, countryStringValidate, IA5StringNormalize, NULL},
4341 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4342 0, dnValidate, dnNormalize2, dnPretty2},
4343 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4344 0, NULL, NULL, NULL},
4345 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4346 0, NULL, NULL, NULL},
4347 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4348 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4349 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4350 0, NULL, NULL, NULL},
4351 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4352 0, NULL, NULL, NULL},
4353 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4354 0, NULL, NULL, NULL},
4355 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4356 0, NULL, NULL, NULL},
4357 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4358 0, NULL, NULL, NULL},
4359 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4360 0, printablesStringValidate, telephoneNumberNormalize, NULL},
4361 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4362 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4363 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4364 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4365 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4366 0, NULL, NULL, NULL},
4367 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4368 0, IA5StringValidate, IA5StringNormalize, NULL},
4369 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4370 0, integerValidate, integerNormalize, NULL},
4371 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4372 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4373 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4374 0, NULL, NULL, NULL},
4375 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4376 0, NULL, NULL, NULL},
4377 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4378 0, NULL, NULL, NULL},
4379 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4380 0, NULL, NULL, NULL},
4381 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4382 0, NULL, NULL, NULL},
4383 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4384 0, nameUIDValidate, nameUIDNormalize, NULL},
4385 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4386 0, NULL, NULL, NULL},
4387 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4388 0, numericStringValidate, numericStringNormalize, NULL},
4389 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4390 0, NULL, NULL, NULL},
4391 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4392 0, oidValidate, NULL, NULL},
4393 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4394 0, IA5StringValidate, IA5StringNormalize, NULL},
4395 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4396 0, blobValidate, NULL, NULL},
4397 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4398 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4399 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4400 0, NULL, NULL, NULL},
4401 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4402 0, NULL, NULL, NULL},
4403 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4404 0, printableStringValidate, IA5StringNormalize, NULL},
4405 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4406 X_BINARY X_NOT_H_R ")",
4407 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4408 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4409 X_BINARY X_NOT_H_R ")",
4410 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4411 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4412 0, printableStringValidate, telephoneNumberNormalize, NULL},
4413 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4414 0, NULL, NULL, NULL},
4415 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4416 0, printablesStringValidate, IA5StringNormalize, NULL},
4417 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4418 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4419 0, utcTimeValidate, utcTimeNormalize, NULL},
4421 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4422 0, NULL, NULL, NULL},
4423 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4424 0, NULL, NULL, NULL},
4425 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4426 0, NULL, NULL, NULL},
4427 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4428 0, NULL, NULL, NULL},
4429 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4430 0, NULL, NULL, NULL},
4432 /* RFC 2307 NIS Syntaxes */
4433 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4434 0, nisNetgroupTripleValidate, NULL, NULL},
4435 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4436 0, bootParameterValidate, NULL, NULL},
4440 /* These OIDs are not published yet, but will be in the next
4441 * I-D for PKIX LDAPv3 schema as have been advanced by David
4442 * Chadwick in private mail.
4444 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4445 0, UTF8StringValidate, NULL, NULL},
4448 /* OpenLDAP Experimental Syntaxes */
4449 #ifdef SLAPD_ACI_ENABLED
4450 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4452 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4456 #ifdef SLAPD_AUTHPASSWD
4457 /* needs updating */
4458 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4459 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4462 /* OpenLDAP Void Syntax */
4463 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4464 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4465 {NULL, 0, NULL, NULL, NULL}
4469 char *certificateExactMatchSyntaxes[] = {
4470 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4474 char *directoryStringSyntaxes[] = {
4475 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4478 char *integerFirstComponentMatchSyntaxes[] = {
4479 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4480 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4483 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4484 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4485 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4486 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4487 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4488 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4489 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4490 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4491 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4496 * Other matching rules in X.520 that we do not use (yet):
4498 * 2.5.13.9 numericStringOrderingMatch
4499 * 2.5.13.19 octetStringSubstringsMatch
4500 * 2.5.13.25 uTCTimeMatch
4501 * 2.5.13.26 uTCTimeOrderingMatch
4502 * 2.5.13.31 directoryStringFirstComponentMatch
4503 * 2.5.13.32 wordMatch
4504 * 2.5.13.33 keywordMatch
4505 * 2.5.13.35 certificateMatch
4506 * 2.5.13.36 certificatePairExactMatch
4507 * 2.5.13.37 certificatePairMatch
4508 * 2.5.13.38 certificateListExactMatch
4509 * 2.5.13.39 certificateListMatch
4510 * 2.5.13.40 algorithmIdentifierMatch
4511 * 2.5.13.41 storedPrefixMatch
4512 * 2.5.13.42 attributeCertificateMatch
4513 * 2.5.13.43 readerAndKeyIDMatch
4514 * 2.5.13.44 attributeIntegrityMatch
4516 static slap_mrule_defs_rec mrule_defs[] = {
4518 * EQUALITY matching rules must be listed after associated APPROX
4519 * matching rules. So, we list all APPROX matching rules first.
4521 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4522 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4523 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4525 directoryStringApproxMatch,
4526 directoryStringApproxIndexer,
4527 directoryStringApproxFilter,
4530 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4531 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4532 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4534 IA5StringApproxMatch,
4535 IA5StringApproxIndexer,
4536 IA5StringApproxFilter,
4540 * Other matching rules
4543 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4544 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4545 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4547 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4550 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4551 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4552 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4554 dnMatch, dnIndexer, dnFilter,
4557 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4558 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4559 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4560 directoryStringSyntaxes,
4562 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4563 directoryStringApproxMatchOID },
4565 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4566 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4567 SLAP_MR_ORDERING, directoryStringSyntaxes,
4569 caseIgnoreOrderingMatch, NULL, NULL,
4572 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4573 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4574 SLAP_MR_SUBSTR, NULL,
4576 caseExactIgnoreSubstringsMatch,
4577 caseExactIgnoreSubstringsIndexer,
4578 caseExactIgnoreSubstringsFilter,
4581 {"( 2.5.13.5 NAME 'caseExactMatch' "
4582 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4583 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4585 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4586 directoryStringApproxMatchOID },
4588 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4589 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4590 SLAP_MR_ORDERING, directoryStringSyntaxes,
4592 caseExactOrderingMatch, NULL, NULL,
4595 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4596 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4597 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4599 caseExactIgnoreSubstringsMatch,
4600 caseExactIgnoreSubstringsIndexer,
4601 caseExactIgnoreSubstringsFilter,
4604 {"( 2.5.13.8 NAME 'numericStringMatch' "
4605 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4606 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4609 caseIgnoreIA5Indexer,
4610 caseIgnoreIA5Filter,
4613 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4614 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4615 SLAP_MR_SUBSTR, NULL,
4617 caseIgnoreIA5SubstringsMatch,
4618 caseIgnoreIA5SubstringsIndexer,
4619 caseIgnoreIA5SubstringsFilter,
4622 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4623 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4624 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4626 caseIgnoreListMatch, NULL, NULL,
4629 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4630 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4631 SLAP_MR_SUBSTR, NULL,
4633 caseIgnoreListSubstringsMatch, NULL, NULL,
4636 {"( 2.5.13.13 NAME 'booleanMatch' "
4637 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4638 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4640 booleanMatch, NULL, NULL,
4643 {"( 2.5.13.14 NAME 'integerMatch' "
4644 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4645 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4647 integerMatch, integerIndexer, integerFilter,
4650 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4651 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4652 SLAP_MR_ORDERING, NULL,
4654 integerOrderingMatch, NULL, NULL,
4657 {"( 2.5.13.16 NAME 'bitStringMatch' "
4658 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4659 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4661 bitStringMatch, bitStringIndexer, bitStringFilter,
4664 {"( 2.5.13.17 NAME 'octetStringMatch' "
4665 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4666 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4668 octetStringMatch, octetStringIndexer, octetStringFilter,
4671 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4672 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4673 SLAP_MR_ORDERING, NULL,
4675 octetStringOrderingMatch, NULL, NULL,
4678 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4679 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4680 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4682 telephoneNumberMatch,
4683 telephoneNumberIndexer,
4684 telephoneNumberFilter,
4687 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4688 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4689 SLAP_MR_SUBSTR, NULL,
4691 telephoneNumberSubstringsMatch,
4692 telephoneNumberSubstringsIndexer,
4693 telephoneNumberSubstringsFilter,
4696 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4697 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4698 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4703 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4704 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4705 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4707 uniqueMemberMatch, NULL, NULL,
4710 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4711 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4712 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4714 protocolInformationMatch, NULL, NULL,
4717 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4718 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4719 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4721 generalizedTimeMatch, NULL, NULL,
4724 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4725 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4726 SLAP_MR_ORDERING, NULL,
4728 generalizedTimeOrderingMatch, NULL, NULL,
4731 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4732 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4733 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
4735 integerFirstComponentMatch, NULL, NULL,
4738 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4739 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4740 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4741 objectIdentifierFirstComponentMatchSyntaxes,
4743 objectIdentifierFirstComponentMatch, NULL, NULL,
4747 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4748 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4749 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
4750 certificateExactConvert, NULL,
4751 certificateExactMatch,
4752 certificateExactIndexer, certificateExactFilter,
4756 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4757 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4758 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4760 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4761 IA5StringApproxMatchOID },
4763 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4764 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4765 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4767 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4768 IA5StringApproxMatchOID },
4770 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4771 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4772 SLAP_MR_SUBSTR, NULL,
4774 caseIgnoreIA5SubstringsMatch,
4775 caseIgnoreIA5SubstringsIndexer,
4776 caseIgnoreIA5SubstringsFilter,
4779 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4780 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4781 SLAP_MR_SUBSTR, NULL,
4783 caseExactIA5SubstringsMatch,
4784 caseExactIA5SubstringsIndexer,
4785 caseExactIA5SubstringsFilter,
4788 #ifdef SLAPD_AUTHPASSWD
4789 /* needs updating */
4790 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4791 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4792 SLAP_MR_EQUALITY, NULL,
4794 authPasswordMatch, NULL, NULL,
4798 #ifdef SLAPD_ACI_ENABLED
4799 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4800 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4801 SLAP_MR_EQUALITY, NULL,
4803 OpenLDAPaciMatch, NULL, NULL,
4807 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4808 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4811 integerBitAndMatch, NULL, NULL,
4814 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4815 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4818 integerBitOrMatch, NULL, NULL,
4821 {NULL, SLAP_MR_NONE, NULL,
4822 NULL, NULL, NULL, NULL, NULL,
4827 slap_schema_init( void )
4832 /* we should only be called once (from main) */
4833 assert( schema_init_done == 0 );
4835 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4836 res = register_syntax( &syntax_defs[i] );
4839 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
4840 syntax_defs[i].sd_desc );
4845 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4846 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
4847 mrule_defs[i].mrd_compat_syntaxes == NULL )
4850 "slap_schema_init: Ingoring unusable matching rule %s\n",
4851 mrule_defs[i].mrd_desc );
4855 res = register_matching_rule( &mrule_defs[i] );
4859 "slap_schema_init: Error registering matching rule %s\n",
4860 mrule_defs[i].mrd_desc );
4865 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4866 *mr_ptr[i].mr = mr_find( mr_ptr[i].oid );
4868 res = slap_schema_load();
4869 schema_init_done = 1;
4874 schema_destroy( void )
4880 for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
4881 *mr_ptr[i].mr = NULL;