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)
33 #define SLAP_MR_DN_FOLD (0)
35 #define SLAP_MR_ASSOCIATED(mr, with) \
36 ((mr) == (with) || (mr)->smr_associated == (with))
38 #define xUTF8StringNormalize NULL
39 #define xIA5StringNormalize NULL
40 #define xtelephoneNumberNormalize NULL
41 #define xgeneralizedTimeNormalize NULL
42 #define xintegerNormalize NULL
43 #define xnumericStringNormalize NULL
44 #define xnameUIDNormalize NULL
45 #define xdnNormalize NULL
47 /* (new) normalization routines */
48 #define caseExactIA5Normalize IA5StringNormalize
49 #define caseIgnoreIA5Normalize IA5StringNormalize
50 #define caseExactNormalize UTF8StringNormalize
51 #define caseIgnoreNormalize UTF8StringNormalize
53 #define integerNormalize NULL
54 #define integerFirstComponentNormalize NULL
55 #define numericStringNormalize NULL
56 #define objectIdentifierNormalize NULL
57 #define objectIdentifierFirstComponentNormalize NULL
58 #define generalizedTimeNormalize NULL
59 #define bitStringNormalize NULL
60 #define telephoneNumberNormalize NULL
62 #define distinguishedNameNormalize dnNormalize
63 #define distinguishedNameMatch dnMatch
64 #define distinguishedNameIndexer octetStringIndexer
65 #define distinguishedNameFilter octetStringFilter
67 #define uniqueMemberMatch dnMatch
69 #define objectIdentifierMatch octetStringMatch
70 #define objectIdentifierIndexer octetStringIndexer
71 #define objectIdentifierFilter octetStringFilter
73 #define OpenLDAPaciMatch NULL
75 #define bitStringMatch octetStringMatch
76 #define bitStringIndexer octetStringIndexer
77 #define bitStringFilter octetStringFilter
79 #define integerMatch NULL
80 #define integerOrderingMatch NULL
81 #define integerIndexer NULL
82 #define integerFilter NULL
84 #define generalizedTimeMatch NULL
85 #define generalizedTimeOrderingMatch NULL
87 #define caseIgnoreMatch octetStringMatch
88 #define caseIgnoreOrderingMatch octetStringOrderingMatch
89 #define caseIgnoreIndexer octetStringIndexer
90 #define caseIgnoreFilter octetStringFilter
92 #define caseIgnoreSubstringsMatch octetStringSubstringsMatch
93 #define caseIgnoreSubstringsIndexer NULL
94 #define caseIgnoreSubstringsFilter NULL
96 #define caseExactMatch octetStringMatch
97 #define caseExactOrderingMatch octetStringOrderingMatch
98 #define caseExactIndexer octetStringIndexer
99 #define caseExactFilter octetStringFilter
101 #define caseExactSubstringsMatch octetStringSubstringsMatch
102 #define caseExactSubstringsIndexer NULL
103 #define caseExactSubstringsFilter NULL
105 #define caseExactIA5Match octetStringMatch
106 #define caseExactIA5Indexer octetStringIndexer
107 #define caseExactIA5Filter octetStringFilter
109 #define caseExactIA5SubstringsMatch octetStringSubstringsMatch
110 #define caseExactIA5SubstringsIndexer NULL
111 #define caseExactIA5SubstringsFilter NULL
113 #define caseIgnoreIA5Match octetStringMatch
114 #define caseIgnoreIA5Indexer octetStringIndexer
115 #define caseIgnoreIA5Filter octetStringFilter
117 #define caseIgnoreIA5SubstringsMatch caseExactIA5SubstringsMatch
118 #define caseIgnoreIA5SubstringsIndexer caseExactIA5SubstringsIndexer
119 #define caseIgnoreIA5SubstringsFilter caseExactIA5SubstringsFilter
121 #define numericStringMatch octetStringMatch
122 #define numericStringIndexer octetStringIndexer
123 #define numericStringFilter octetStringFilter
125 #define numericStringSubstringsMatch caseExactIA5SubstringsMatch
126 #define numericStringSubstringsIndexer caseExactIA5SubstringsIndexer
127 #define numericStringSubstringsFilter caseExactIA5SubstringsFilter
129 #define telephoneNumberMatch octetStringMatch
130 #define telephoneNumberIndexer octetStringIndexer
131 #define telephoneNumberFilter octetStringFilter
133 #define telephoneNumberSubstringsMatch caseExactIA5SubstringsMatch
134 #define telephoneNumberSubstringsIndexer caseExactIA5SubstringsIndexer
135 #define telephoneNumberSubstringsFilter caseExactIA5SubstringsFilter
139 /* validatation routines */
140 #define berValidate blobValidate
142 /* approx matching rules */
144 #define directoryStringApproxMatchOID NULL
145 #define IA5StringApproxMatchOID NULL
147 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
148 #define directoryStringApproxMatch approxMatch
149 #define directoryStringApproxIndexer approxIndexer
150 #define directoryStringApproxFilter approxFilter
151 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
152 #define IA5StringApproxMatch approxMatch
153 #define IA5StringApproxIndexer approxIndexer
154 #define IA5StringApproxFilter approxFilter
159 #define xdnNormalize dnNormalize
161 /* (new) normalization routines */
162 #define caseExactNormalize NULL
163 #define caseExactIA5Normalize NULL
164 #define caseIgnoreNormalize NULL
165 #define caseIgnoreIA5Normalize NULL
166 #define distinguishedNameNormalize NULL
167 #define integerNormalize NULL
168 #define integerFirstComponentNormalize NULL
169 #define numericStringNormalize NULL
170 #define objectIdentifierNormalize NULL
171 #define objectIdentifierFirstComponentNormalize NULL
172 #define generalizedTimeNormalize NULL
173 #define uniqueMemberNormalize NULL
174 #define bitStringNormalize NULL
175 #define telephoneNumberNormalize NULL
178 /* matching routines */
179 #define bitStringMatch octetStringMatch
180 #define bitStringIndexer octetStringIndexer
181 #define bitStringFilter octetStringFilter
183 #define numericStringMatch caseIgnoreIA5Match
184 #define numericStringIndexer NULL
185 #define numericStringFilter NULL
186 #define numericStringSubstringsIndexer NULL
187 #define numericStringSubstringsFilter NULL
189 #define objectIdentifierMatch octetStringMatch
190 #define objectIdentifierIndexer caseIgnoreIA5Indexer
191 #define objectIdentifierFilter caseIgnoreIA5Filter
193 #define octetStringSubstringsMatch NULL
194 #define OpenLDAPaciMatch NULL
196 #define generalizedTimeMatch caseIgnoreIA5Match
197 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
199 #define uniqueMemberMatch dnMatch
200 #define numericStringSubstringsMatch NULL
202 #define caseExactIndexer caseExactIgnoreIndexer
203 #define caseExactFilter caseExactIgnoreFilter
204 #define caseExactOrderingMatch caseExactMatch
205 #define caseExactSubstringsMatch caseExactIgnoreSubstringsMatch
206 #define caseExactSubstringsIndexer caseExactIgnoreSubstringsIndexer
207 #define caseExactSubstringsFilter caseExactIgnoreSubstringsFilter
208 #define caseIgnoreIndexer caseExactIgnoreIndexer
209 #define caseIgnoreFilter caseExactIgnoreFilter
210 #define caseIgnoreOrderingMatch caseIgnoreMatch
211 #define caseIgnoreSubstringsMatch caseExactIgnoreSubstringsMatch
212 #define caseIgnoreSubstringsIndexer caseExactIgnoreSubstringsIndexer
213 #define caseIgnoreSubstringsFilter caseExactIgnoreSubstringsFilter
215 #define integerOrderingMatch integerMatch
216 #define integerFirstComponentMatch integerMatch
218 #define distinguishedNameMatch dnMatch
219 #define distinguishedNameIndexer caseExactIgnoreIndexer
220 #define distinguishedNameFilter caseExactIgnoreFilter
222 #define telephoneNumberMatch caseIgnoreIA5Match
223 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
224 #define telephoneNumberIndexer caseIgnoreIA5Indexer
225 #define telephoneNumberFilter caseIgnoreIA5Filter
226 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
227 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
231 static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len )
234 char lower = TOLOWER( c );
235 char upper = TOUPPER( c );
237 if( c == 0 ) return NULL;
239 for( i=0; i < bv->bv_len; i++ ) {
240 if( upper == bv->bv_val[i] || lower == bv->bv_val[i] ) {
242 return &bv->bv_val[i];
255 struct berval *value,
256 void *assertedValue )
258 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
261 match = memcmp( value->bv_val,
262 ((struct berval *) assertedValue)->bv_val,
271 octetStringOrderingMatch(
276 struct berval *value,
277 void *assertedValue )
279 ber_len_t v_len = value->bv_len;
280 ber_len_t av_len = ((struct berval *) assertedValue)->bv_len;
282 int match = memcmp( value->bv_val,
283 ((struct berval *) assertedValue)->bv_val,
284 (v_len < av_len ? v_len : av_len) );
286 if( match == 0 ) match = v_len - av_len;
292 /* Index generation function */
293 int octetStringIndexer(
298 struct berval *prefix,
305 HASH_CONTEXT HASHcontext;
306 unsigned char HASHdigest[HASH_BYTES];
307 struct berval digest;
308 digest.bv_val = HASHdigest;
309 digest.bv_len = sizeof(HASHdigest);
311 for( i=0; values[i].bv_val != NULL; i++ ) {
312 /* just count them */
315 /* we should have at least one value at this point */
318 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
320 slen = syntax->ssyn_oidlen;
321 mlen = mr->smr_oidlen;
323 for( i=0; values[i].bv_val != NULL; i++ ) {
324 HASH_Init( &HASHcontext );
325 if( prefix != NULL && prefix->bv_len > 0 ) {
326 HASH_Update( &HASHcontext,
327 prefix->bv_val, prefix->bv_len );
329 HASH_Update( &HASHcontext,
330 syntax->ssyn_oid, slen );
331 HASH_Update( &HASHcontext,
333 HASH_Update( &HASHcontext,
334 values[i].bv_val, values[i].bv_len );
335 HASH_Final( HASHdigest, &HASHcontext );
337 ber_dupbv( &keys[i], &digest );
340 keys[i].bv_val = NULL;
348 /* Index generation function */
349 int octetStringFilter(
354 struct berval *prefix,
355 void * assertedValue,
360 HASH_CONTEXT HASHcontext;
361 unsigned char HASHdigest[HASH_BYTES];
362 struct berval *value = (struct berval *) assertedValue;
363 struct berval digest;
364 digest.bv_val = HASHdigest;
365 digest.bv_len = sizeof(HASHdigest);
367 slen = syntax->ssyn_oidlen;
368 mlen = mr->smr_oidlen;
370 keys = ch_malloc( sizeof( struct berval ) * 2 );
372 HASH_Init( &HASHcontext );
373 if( prefix != NULL && prefix->bv_len > 0 ) {
374 HASH_Update( &HASHcontext,
375 prefix->bv_val, prefix->bv_len );
377 HASH_Update( &HASHcontext,
378 syntax->ssyn_oid, slen );
379 HASH_Update( &HASHcontext,
381 HASH_Update( &HASHcontext,
382 value->bv_val, value->bv_len );
383 HASH_Final( HASHdigest, &HASHcontext );
385 ber_dupbv( keys, &digest );
386 keys[1].bv_val = NULL;
399 /* no value allowed */
400 return LDAP_INVALID_SYNTAX;
408 /* any value allowed */
419 /* very unforgiving validation, requires no normalization
420 * before simplistic matching
422 if( in->bv_len < 3 ) {
423 return LDAP_INVALID_SYNTAX;
427 * rfc 2252 section 6.3 Bit String
428 * bitstring = "'" *binary-digit "'"
429 * binary-digit = "0" / "1"
430 * example: '0101111101'B
433 if( in->bv_val[0] != '\'' ||
434 in->bv_val[in->bv_len-2] != '\'' ||
435 in->bv_val[in->bv_len-1] != 'B' )
437 return LDAP_INVALID_SYNTAX;
440 for( i=in->bv_len-3; i>0; i-- ) {
441 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
442 return LDAP_INVALID_SYNTAX;
457 if( in->bv_len == 0 ) return LDAP_SUCCESS;
459 ber_dupbv( &dn, in );
460 if( !dn.bv_val ) return LDAP_OTHER;
462 if( dn.bv_val[dn.bv_len-1] == 'B'
463 && dn.bv_val[dn.bv_len-2] == '\'' )
465 /* assume presence of optional UID */
468 for(i=dn.bv_len-3; i>1; i--) {
469 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
473 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
474 ber_memfree( dn.bv_val );
475 return LDAP_INVALID_SYNTAX;
478 /* trim the UID to allow use of dnValidate */
479 dn.bv_val[i-1] = '\0';
483 rc = dnValidate( NULL, &dn );
485 ber_memfree( dn.bv_val );
491 uniqueMemberNormalize(
496 struct berval *normalized )
502 struct berval *normalized )
508 ber_dupbv( &out, val );
509 if( out.bv_len != 0 ) {
510 struct berval uid = { 0, NULL };
512 if( out.bv_val[out.bv_len-1] == 'B'
513 && out.bv_val[out.bv_len-2] == '\'' )
515 /* assume presence of optional UID */
516 uid.bv_val = strrchr( out.bv_val, '#' );
518 if( uid.bv_val == NULL ) {
520 return LDAP_INVALID_SYNTAX;
523 uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
524 out.bv_len -= uid.bv_len--;
526 /* temporarily trim the UID */
527 *(uid.bv_val++) = '\0';
530 rc = dnNormalize2( NULL, &out, normalized );
532 if( rc != LDAP_SUCCESS ) {
534 return LDAP_INVALID_SYNTAX;
538 normalized->bv_val = ch_realloc( normalized->bv_val,
539 normalized->bv_len + uid.bv_len + sizeof("#") );
541 /* insert the separator */
542 normalized->bv_val[normalized->bv_len++] = '#';
545 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
546 uid.bv_val, uid.bv_len );
547 normalized->bv_len += uid.bv_len;
550 normalized->bv_val[normalized->bv_len] = '\0';
560 * Handling boolean syntax and matching is quite rigid.
561 * A more flexible approach would be to allow a variety
562 * of strings to be normalized and prettied into TRUE
570 /* very unforgiving validation, requires no normalization
571 * before simplistic matching
574 if( in->bv_len == 4 ) {
575 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
578 } else if( in->bv_len == 5 ) {
579 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
584 return LDAP_INVALID_SYNTAX;
593 struct berval *value,
594 void *assertedValue )
596 /* simplistic matching allowed by rigid validation */
597 struct berval *asserted = (struct berval *) assertedValue;
598 *matchp = value->bv_len != asserted->bv_len;
602 /*-------------------------------------------------------------------
603 LDAP/X.500 string syntax / matching rules have a few oddities. This
604 comment attempts to detail how slapd(8) treats them.
607 StringSyntax X.500 LDAP Matching/Comments
608 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
609 PrintableString subset subset i/e + ignore insignificant spaces
610 PrintableString subset subset i/e + ignore insignificant spaces
611 NumericString subset subset ignore all spaces
612 IA5String ASCII ASCII i/e + ignore insignificant spaces
613 TeletexString T.61 T.61 i/e + ignore insignificant spaces
615 TelephoneNumber subset subset i + ignore all spaces and "-"
617 See draft-ietf-ldapbis-strpro for details (once published).
621 In X.500(93), a directory string can be either a PrintableString,
622 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
623 In later versions, more CHOICEs were added. In all cases the string
626 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
627 A directory string cannot be zero length.
629 For matching, there are both case ignore and exact rules. Both
630 also require that "insignificant" spaces be ignored.
631 spaces before the first non-space are ignored;
632 spaces after the last non-space are ignored;
633 spaces after a space are ignored.
634 Note: by these rules (and as clarified in X.520), a string of only
635 spaces is to be treated as if held one space, not empty (which
636 would be a syntax error).
639 In ASN.1, numeric string is just a string of digits and spaces
640 and could be empty. However, in X.500, all attribute values of
641 numeric string carry a non-empty constraint. For example:
643 internationalISDNNumber ATTRIBUTE ::= {
644 WITH SYNTAX InternationalISDNNumber
645 EQUALITY MATCHING RULE numericStringMatch
646 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
647 ID id-at-internationalISDNNumber }
648 InternationalISDNNumber ::=
649 NumericString (SIZE(1..ub-international-isdn-number))
651 Unforunately, some assertion values are don't carry the same
652 constraint (but its unclear how such an assertion could ever
653 be true). In LDAP, there is one syntax (numericString) not two
654 (numericString with constraint, numericString without constraint).
655 This should be treated as numericString with non-empty constraint.
656 Note that while someone may have no ISDN number, there are no ISDN
657 numbers which are zero length.
659 In matching, spaces are ignored.
662 In ASN.1, Printable string is just a string of printable characters
663 and can be empty. In X.500, semantics much like NumericString (see
664 serialNumber for a like example) excepting uses insignificant space
665 handling instead of ignore all spaces.
668 Basically same as PrintableString. There are no examples in X.500,
669 but same logic applies. So we require them to be non-empty as
672 -------------------------------------------------------------------*/
681 unsigned char *u = in->bv_val;
683 if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
684 /* directory strings cannot be empty */
685 return LDAP_INVALID_SYNTAX;
688 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
689 /* get the length indicated by the first byte */
690 len = LDAP_UTF8_CHARLEN2( u, len );
692 /* very basic checks */
695 if( (u[5] & 0xC0) != 0x80 ) {
696 return LDAP_INVALID_SYNTAX;
699 if( (u[4] & 0xC0) != 0x80 ) {
700 return LDAP_INVALID_SYNTAX;
703 if( (u[3] & 0xC0) != 0x80 ) {
704 return LDAP_INVALID_SYNTAX;
707 if( (u[2] & 0xC0 )!= 0x80 ) {
708 return LDAP_INVALID_SYNTAX;
711 if( (u[1] & 0xC0) != 0x80 ) {
712 return LDAP_INVALID_SYNTAX;
715 /* CHARLEN already validated it */
718 return LDAP_INVALID_SYNTAX;
721 /* make sure len corresponds with the offset
722 to the next character */
723 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
727 return LDAP_INVALID_SYNTAX;
740 struct berval *normalized )
742 struct berval tmp, nvalue;
746 if( val->bv_val == NULL ) {
747 /* assume we're dealing with a syntax (e.g., UTF8String)
748 * which allows empty strings
750 normalized->bv_len = 0;
751 normalized->bv_val = NULL;
755 flags = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactMatch )
756 ? LDAP_UTF8_NOCASEFOLD : LDAP_UTF8_CASEFOLD;
757 flags |= ( use & SLAP_MR_EQUALITY_APPROX == SLAP_MR_EQUALITY_APPROX )
758 ? LDAP_UTF8_APPROX : 0;
760 val = UTF8bvnormalize( val, &tmp, flags );
765 /* collapse spaces (in place) */
767 nvalue.bv_val = tmp.bv_val;
769 wasspace=1; /* trim leading spaces */
770 for( i=0; i<tmp.bv_len; i++) {
771 if ( ASCII_SPACE( tmp.bv_val[i] )) {
772 if( wasspace++ == 0 ) {
773 /* trim repeated spaces */
774 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
778 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
782 if( nvalue.bv_len ) {
784 /* last character was a space, trim it */
787 nvalue.bv_val[nvalue.bv_len] = '\0';
790 /* string of all spaces is treated as one space */
791 nvalue.bv_val[0] = ' ';
792 nvalue.bv_val[1] = '\0';
796 *normalized = nvalue;
802 xUTF8StringNormalize(
805 struct berval *normalized )
810 /* validator should have refused an empty string */
811 assert( val->bv_len );
815 /* Ignore initial whitespace */
816 /* All space is ASCII. All ASCII is 1 byte */
817 for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ );
819 normalized->bv_len = val->bv_len - (p - val->bv_val);
821 if( !normalized->bv_len ) {
822 ber_mem2bv( " ", 1, 1, normalized );
826 ber_mem2bv( p, normalized->bv_len, 1, normalized );
827 e = normalized->bv_val + normalized->bv_len;
829 assert( normalized->bv_val );
831 p = q = normalized->bv_val;
836 if ( ASCII_SPACE( *p ) ) {
841 /* Ignore the extra whitespace */
842 while ( ASCII_SPACE( *p ) ) {
846 len = LDAP_UTF8_COPY(q,p);
852 assert( normalized->bv_val <= p );
853 assert( q+len <= p );
855 /* cannot start with a space */
856 assert( !ASCII_SPACE( normalized->bv_val[0] ) );
859 * If the string ended in space, backup the pointer one
860 * position. One is enough because the above loop collapsed
861 * all whitespace to a single space.
869 /* cannot end with a space */
870 assert( !ASCII_SPACE( *q ) );
877 normalized->bv_len = q - normalized->bv_val;
882 /* Returns Unicode canonically normalized copy of a substring assertion
883 * Skipping attribute description */
884 static SubstringsAssertion *
885 UTF8SubstringsAssertionNormalize(
886 SubstringsAssertion *sa,
889 SubstringsAssertion *nsa;
892 nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) );
897 if( sa->sa_initial.bv_val != NULL ) {
898 UTF8bvnormalize( &sa->sa_initial, &nsa->sa_initial, casefold );
899 if( nsa->sa_initial.bv_val == NULL ) {
904 if( sa->sa_any != NULL ) {
905 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
908 nsa->sa_any = (struct berval *)
909 SLAP_MALLOC( (i + 1) * sizeof(struct berval) );
910 if( nsa->sa_any == NULL ) {
914 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
915 UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i],
917 if( nsa->sa_any[i].bv_val == NULL ) {
921 nsa->sa_any[i].bv_val = NULL;
924 if( sa->sa_final.bv_val != NULL ) {
925 UTF8bvnormalize( &sa->sa_final, &nsa->sa_final, casefold );
926 if( nsa->sa_final.bv_val == NULL ) {
934 if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val );
935 if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any );
936 if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val );
941 #ifndef SLAPD_APPROX_OLDSINGLESTRING
943 #if defined(SLAPD_APPROX_INITIALS)
944 #define SLAPD_APPROX_DELIMITER "._ "
945 #define SLAPD_APPROX_WORDLEN 2
947 #define SLAPD_APPROX_DELIMITER " "
948 #define SLAPD_APPROX_WORDLEN 1
957 struct berval *value,
958 void *assertedValue )
960 struct berval *nval, *assertv;
961 char *val, **values, **words, *c;
962 int i, count, len, nextchunk=0, nextavail=0;
964 /* Yes, this is necessary */
965 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX );
971 /* Yes, this is necessary */
972 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
973 NULL, LDAP_UTF8_APPROX );
974 if( assertv == NULL ) {
980 /* Isolate how many words there are */
981 for ( c = nval->bv_val, count = 1; *c; c++ ) {
982 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
983 if ( c == NULL ) break;
988 /* Get a phonetic copy of each word */
989 words = (char **)ch_malloc( count * sizeof(char *) );
990 values = (char **)ch_malloc( count * sizeof(char *) );
991 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
993 values[i] = phonetic(c);
996 /* Work through the asserted value's words, to see if at least some
997 of the words are there, in the same order. */
999 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
1000 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
1005 #if defined(SLAPD_APPROX_INITIALS)
1006 else if( len == 1 ) {
1007 /* Single letter words need to at least match one word's initial */
1008 for( i=nextavail; i<count; i++ )
1009 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
1016 /* Isolate the next word in the asserted value and phonetic it */
1017 assertv->bv_val[nextchunk+len] = '\0';
1018 val = phonetic( assertv->bv_val + nextchunk );
1020 /* See if this phonetic chunk is in the remaining words of *value */
1021 for( i=nextavail; i<count; i++ ){
1022 if( !strcmp( val, values[i] ) ){
1030 /* This chunk in the asserted value was NOT within the *value. */
1036 /* Go on to the next word in the asserted value */
1040 /* If some of the words were seen, call it a match */
1041 if( nextavail > 0 ) {
1048 /* Cleanup allocs */
1049 ber_bvfree( assertv );
1050 for( i=0; i<count; i++ ) {
1051 ch_free( values[i] );
1057 return LDAP_SUCCESS;
1066 struct berval *prefix,
1071 int i,j, len, wordcount, keycount=0;
1072 struct berval *newkeys;
1073 BerVarray keys=NULL;
1075 for( j=0; values[j].bv_val != NULL; j++ ) {
1076 struct berval val = { 0, NULL };
1077 /* Yes, this is necessary */
1078 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX );
1079 assert( val.bv_val != NULL );
1081 /* Isolate how many words there are. There will be a key for each */
1082 for( wordcount = 0, c = val.bv_val; *c; c++) {
1083 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1084 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1086 if (*c == '\0') break;
1090 /* Allocate/increase storage to account for new keys */
1091 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
1092 * sizeof(struct berval) );
1093 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
1094 if( keys ) ch_free( keys );
1097 /* Get a phonetic copy of each word */
1098 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
1100 if( len < SLAPD_APPROX_WORDLEN ) continue;
1101 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
1106 ber_memfree( val.bv_val );
1108 keys[keycount].bv_val = NULL;
1111 return LDAP_SUCCESS;
1120 struct berval *prefix,
1121 void * assertedValue,
1129 /* Yes, this is necessary */
1130 val = UTF8bvnormalize( ((struct berval *)assertedValue),
1131 NULL, LDAP_UTF8_APPROX );
1132 if( val == NULL || val->bv_val == NULL ) {
1133 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
1134 keys[0].bv_val = NULL;
1137 return LDAP_SUCCESS;
1140 /* Isolate how many words there are. There will be a key for each */
1141 for( count = 0,c = val->bv_val; *c; c++) {
1142 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1143 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1145 if (*c == '\0') break;
1149 /* Allocate storage for new keys */
1150 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
1152 /* Get a phonetic copy of each word */
1153 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
1155 if( len < SLAPD_APPROX_WORDLEN ) continue;
1156 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
1162 keys[count].bv_val = NULL;
1165 return LDAP_SUCCESS;
1170 /* No other form of Approximate Matching is defined */
1178 struct berval *value,
1179 void *assertedValue )
1181 char *vapprox, *avapprox;
1184 /* Yes, this is necessary */
1185 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1188 return LDAP_SUCCESS;
1191 /* Yes, this is necessary */
1192 t = UTF8normalize( ((struct berval *)assertedValue),
1197 return LDAP_SUCCESS;
1200 vapprox = phonetic( strip8bitChars( s ) );
1201 avapprox = phonetic( strip8bitChars( t ) );
1206 *matchp = strcmp( vapprox, avapprox );
1209 ch_free( avapprox );
1211 return LDAP_SUCCESS;
1220 struct berval *prefix,
1228 for( i=0; values[i].bv_val != NULL; i++ ) {
1229 /* empty - just count them */
1232 /* we should have at least one value at this point */
1235 keys = (struct berval *)ch_malloc( sizeof( struct berval ) * (i+1) );
1237 /* Copy each value and run it through phonetic() */
1238 for( i=0; values[i].bv_val != NULL; i++ ) {
1239 /* Yes, this is necessary */
1240 s = UTF8normalize( &values[i], UTF8_NOCASEFOLD );
1242 /* strip 8-bit chars and run through phonetic() */
1243 ber_str2bv( phonetic( strip8bitChars( s ) ), 0, 0, &keys[i] );
1246 keys[i].bv_val = NULL;
1249 return LDAP_SUCCESS;
1259 struct berval *prefix,
1260 void * assertedValue,
1266 keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 );
1268 /* Yes, this is necessary */
1269 s = UTF8normalize( ((struct berval *)assertedValue),
1274 /* strip 8-bit chars and run through phonetic() */
1275 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1281 return LDAP_SUCCESS;
1292 struct berval *value,
1293 void *assertedValue )
1295 *matchp = UTF8bvnormcmp( value,
1296 (struct berval *) assertedValue,
1297 LDAP_UTF8_NOCASEFOLD );
1298 return LDAP_SUCCESS;
1302 caseExactIgnoreSubstringsMatch(
1307 struct berval *value,
1308 void *assertedValue )
1311 SubstringsAssertion *sub = NULL;
1312 struct berval left = { 0, NULL };
1318 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1319 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1321 if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) {
1327 sub = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1333 /* Add up asserted input length */
1334 if( sub->sa_initial.bv_val ) {
1335 inlen += sub->sa_initial.bv_len;
1338 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
1339 inlen += sub->sa_any[i].bv_len;
1342 if( sub->sa_final.bv_val ) {
1343 inlen += sub->sa_final.bv_len;
1346 if( sub->sa_initial.bv_val ) {
1347 if( inlen > left.bv_len ) {
1352 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
1353 sub->sa_initial.bv_len );
1359 left.bv_val += sub->sa_initial.bv_len;
1360 left.bv_len -= sub->sa_initial.bv_len;
1361 inlen -= sub->sa_initial.bv_len;
1364 if( sub->sa_final.bv_val ) {
1365 if( inlen > left.bv_len ) {
1370 match = memcmp( sub->sa_final.bv_val,
1371 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
1372 sub->sa_final.bv_len );
1378 left.bv_len -= sub->sa_final.bv_len;
1379 inlen -= sub->sa_final.bv_len;
1383 for(i=0; sub->sa_any[i].bv_val; i++) {
1388 if( inlen > left.bv_len ) {
1389 /* not enough length */
1394 if( sub->sa_any[i].bv_len == 0 ) {
1398 p = ber_bvchr( &left, *sub->sa_any[i].bv_val );
1404 idx = p - left.bv_val;
1406 if( idx >= left.bv_len ) {
1407 /* this shouldn't happen */
1409 if ( sub->sa_final.bv_val )
1410 ch_free( sub->sa_final.bv_val );
1412 ber_bvarray_free( sub->sa_any );
1413 if ( sub->sa_initial.bv_val )
1414 ch_free( sub->sa_initial.bv_val );
1422 if( sub->sa_any[i].bv_len > left.bv_len ) {
1423 /* not enough left */
1428 match = memcmp( left.bv_val,
1429 sub->sa_any[i].bv_val,
1430 sub->sa_any[i].bv_len );
1438 left.bv_val += sub->sa_any[i].bv_len;
1439 left.bv_len -= sub->sa_any[i].bv_len;
1440 inlen -= sub->sa_any[i].bv_len;
1447 if ( sub->sa_final.bv_val ) free( sub->sa_final.bv_val );
1448 if ( sub->sa_any ) ber_bvarray_free( sub->sa_any );
1449 if ( sub->sa_initial.bv_val ) free( sub->sa_initial.bv_val );
1453 return LDAP_SUCCESS;
1456 /* Index generation function */
1457 static int caseExactIgnoreIndexer(
1462 struct berval *prefix,
1467 unsigned casefold,wasspace;
1470 HASH_CONTEXT HASHcontext;
1471 unsigned char HASHdigest[HASH_BYTES];
1472 struct berval digest;
1473 digest.bv_val = HASHdigest;
1474 digest.bv_len = sizeof(HASHdigest);
1476 for( i=0; values[i].bv_val != NULL; i++ ) {
1477 /* empty - just count them */
1480 /* we should have at least one value at this point */
1483 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
1485 slen = syntax->ssyn_oidlen;
1486 mlen = mr->smr_oidlen;
1488 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1489 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1491 for( i=0; values[i].bv_val != NULL; i++ ) {
1492 struct berval value, nvalue;
1493 UTF8bvnormalize( &values[i], &value, casefold );
1495 /* collapse spaces (in place) */
1497 nvalue.bv_val = value.bv_val;
1500 for( j=0; j<value.bv_len; j++) {
1501 if ( ASCII_SPACE( value.bv_val[j] )) {
1502 if( wasspace++ == 0 ) {
1503 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1507 nvalue.bv_val[nvalue.bv_len++] = value.bv_val[j];
1511 if( nvalue.bv_len == 0 ) {
1512 nvalue.bv_val = " ";
1513 nvalue.bv_len = sizeof(" ")-1;
1515 if( wasspace ) --nvalue.bv_len;
1516 nvalue.bv_val[nvalue.bv_len] = '\0';
1519 HASH_Init( &HASHcontext );
1520 if( prefix != NULL && prefix->bv_len > 0 ) {
1521 HASH_Update( &HASHcontext,
1522 prefix->bv_val, prefix->bv_len );
1524 HASH_Update( &HASHcontext,
1525 syntax->ssyn_oid, slen );
1526 HASH_Update( &HASHcontext,
1527 mr->smr_oid, mlen );
1528 HASH_Update( &HASHcontext,
1529 nvalue.bv_val, nvalue.bv_len );
1530 HASH_Final( HASHdigest, &HASHcontext );
1532 free( value.bv_val );
1533 ber_dupbv( &keys[i], &digest );
1536 keys[i].bv_val = NULL;
1538 return LDAP_SUCCESS;
1541 /* Index generation function */
1542 static int caseExactIgnoreFilter(
1547 struct berval *prefix,
1548 void * assertedValue,
1554 HASH_CONTEXT HASHcontext;
1555 unsigned char HASHdigest[HASH_BYTES];
1556 struct berval value = { 0, NULL };
1557 struct berval digest;
1559 digest.bv_val = HASHdigest;
1560 digest.bv_len = sizeof(HASHdigest);
1562 slen = syntax->ssyn_oidlen;
1563 mlen = mr->smr_oidlen;
1565 casefold = ( mr != slap_schema.si_mr_caseExactMatch )
1566 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1568 UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold );
1569 /* This usually happens if filter contains bad UTF8 */
1570 if( value.bv_val == NULL ) {
1571 keys = ch_malloc( sizeof( struct berval ) );
1572 keys[0].bv_val = NULL;
1573 return LDAP_SUCCESS;
1576 keys = ch_malloc( sizeof( struct berval ) * 2 );
1578 HASH_Init( &HASHcontext );
1579 if( prefix != NULL && prefix->bv_len > 0 ) {
1580 HASH_Update( &HASHcontext,
1581 prefix->bv_val, prefix->bv_len );
1583 HASH_Update( &HASHcontext,
1584 syntax->ssyn_oid, slen );
1585 HASH_Update( &HASHcontext,
1586 mr->smr_oid, mlen );
1587 HASH_Update( &HASHcontext,
1588 value.bv_val, value.bv_len );
1589 HASH_Final( HASHdigest, &HASHcontext );
1591 ber_dupbv( keys, &digest );
1592 keys[1].bv_val = NULL;
1594 free( value.bv_val );
1597 return LDAP_SUCCESS;
1600 /* Substrings Index generation function */
1601 static int caseExactIgnoreSubstringsIndexer(
1606 struct berval *prefix,
1610 unsigned casefold, wasspace;
1611 ber_len_t i, j, nkeys;
1614 BerVarray tvalues, nvalues;
1616 HASH_CONTEXT HASHcontext;
1617 unsigned char HASHdigest[HASH_BYTES];
1618 struct berval digest;
1619 digest.bv_val = HASHdigest;
1620 digest.bv_len = sizeof(HASHdigest);
1624 for( i=0; values[i].bv_val != NULL; i++ ) {
1625 /* empty - just count them */
1628 /* we should have at least one value at this point */
1631 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1632 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1634 tvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1635 nvalues = ch_malloc( sizeof( struct berval ) * (i+1) );
1637 for( i=0; values[i].bv_val != NULL; i++ ) {
1638 UTF8bvnormalize( &values[i], &tvalues[i], casefold );
1640 /* collapse spaces (in place) */
1641 nvalues[i].bv_len = 0;
1642 nvalues[i].bv_val = tvalues[i].bv_val;
1645 for( j=0; j<tvalues[i].bv_len; j++) {
1646 if ( ASCII_SPACE( tvalues[i].bv_val[j] )) {
1647 if( wasspace++ == 0 ) {
1648 nvalues[i].bv_val[nvalues[i].bv_len++] =
1649 tvalues[i].bv_val[j];
1653 nvalues[i].bv_val[nvalues[i].bv_len++] = tvalues[i].bv_val[j];
1657 if( nvalues[i].bv_len == 0 ) {
1658 nvalues[i].bv_val = " ";
1659 nvalues[i].bv_len = sizeof(" ")-1;
1661 if( wasspace ) --nvalues[i].bv_len;
1662 nvalues[i].bv_val[nvalues[i].bv_len] = '\0';
1666 tvalues[i].bv_val = NULL;
1667 nvalues[i].bv_val = NULL;
1670 for( i=0; values[i].bv_val != NULL; i++ ) {
1671 /* count number of indices to generate */
1672 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1676 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1677 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1678 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1679 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1681 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1685 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1686 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1687 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1691 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1692 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1693 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1694 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1696 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1702 /* no keys to generate */
1704 ber_bvarray_free( tvalues );
1706 return LDAP_SUCCESS;
1709 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1711 slen = syntax->ssyn_oidlen;
1712 mlen = mr->smr_oidlen;
1715 for( i=0; values[i].bv_val != NULL; i++ ) {
1718 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1720 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1721 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1723 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1724 max = values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1726 for( j=0; j<max; j++ ) {
1727 HASH_Init( &HASHcontext );
1728 if( prefix != NULL && prefix->bv_len > 0 ) {
1729 HASH_Update( &HASHcontext,
1730 prefix->bv_val, prefix->bv_len );
1733 HASH_Update( &HASHcontext,
1734 &pre, sizeof( pre ) );
1735 HASH_Update( &HASHcontext,
1736 syntax->ssyn_oid, slen );
1737 HASH_Update( &HASHcontext,
1738 mr->smr_oid, mlen );
1739 HASH_Update( &HASHcontext,
1740 &values[i].bv_val[j],
1741 SLAP_INDEX_SUBSTR_MAXLEN );
1742 HASH_Final( HASHdigest, &HASHcontext );
1744 ber_dupbv( &keys[nkeys++], &digest );
1748 max = SLAP_INDEX_SUBSTR_MAXLEN < values[i].bv_len
1749 ? SLAP_INDEX_SUBSTR_MAXLEN : values[i].bv_len;
1751 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1754 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1755 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1756 HASH_Init( &HASHcontext );
1757 if( prefix != NULL && prefix->bv_len > 0 ) {
1758 HASH_Update( &HASHcontext,
1759 prefix->bv_val, prefix->bv_len );
1761 HASH_Update( &HASHcontext,
1762 &pre, sizeof( pre ) );
1763 HASH_Update( &HASHcontext,
1764 syntax->ssyn_oid, slen );
1765 HASH_Update( &HASHcontext,
1766 mr->smr_oid, mlen );
1767 HASH_Update( &HASHcontext,
1768 values[i].bv_val, j );
1769 HASH_Final( HASHdigest, &HASHcontext );
1771 ber_dupbv( &keys[nkeys++], &digest );
1774 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1775 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1776 HASH_Init( &HASHcontext );
1777 if( prefix != NULL && prefix->bv_len > 0 ) {
1778 HASH_Update( &HASHcontext,
1779 prefix->bv_val, prefix->bv_len );
1781 HASH_Update( &HASHcontext,
1782 &pre, sizeof( pre ) );
1783 HASH_Update( &HASHcontext,
1784 syntax->ssyn_oid, slen );
1785 HASH_Update( &HASHcontext,
1786 mr->smr_oid, mlen );
1787 HASH_Update( &HASHcontext,
1788 &values[i].bv_val[values[i].bv_len-j], j );
1789 HASH_Final( HASHdigest, &HASHcontext );
1791 ber_dupbv( &keys[nkeys++], &digest );
1799 keys[nkeys].bv_val = NULL;
1806 ber_bvarray_free( tvalues );
1809 return LDAP_SUCCESS;
1812 static int caseExactIgnoreSubstringsFilter(
1817 struct berval *prefix,
1818 void * assertedValue,
1821 SubstringsAssertion *sa;
1824 ber_len_t nkeys = 0;
1825 size_t slen, mlen, klen;
1827 HASH_CONTEXT HASHcontext;
1828 unsigned char HASHdigest[HASH_BYTES];
1829 struct berval *value;
1830 struct berval digest;
1832 casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch )
1833 ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
1835 sa = UTF8SubstringsAssertionNormalize( assertedValue, casefold );
1838 return LDAP_SUCCESS;
1841 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1842 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1847 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1849 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1850 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1851 /* don't bother accounting for stepping */
1852 nkeys += sa->sa_any[i].bv_len -
1853 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1858 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1859 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1865 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1866 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1867 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1870 return LDAP_SUCCESS;
1873 digest.bv_val = HASHdigest;
1874 digest.bv_len = sizeof(HASHdigest);
1876 slen = syntax->ssyn_oidlen;
1877 mlen = mr->smr_oidlen;
1879 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
1882 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
1883 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1885 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1886 value = &sa->sa_initial;
1888 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1889 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1891 HASH_Init( &HASHcontext );
1892 if( prefix != NULL && prefix->bv_len > 0 ) {
1893 HASH_Update( &HASHcontext,
1894 prefix->bv_val, prefix->bv_len );
1896 HASH_Update( &HASHcontext,
1897 &pre, sizeof( pre ) );
1898 HASH_Update( &HASHcontext,
1899 syntax->ssyn_oid, slen );
1900 HASH_Update( &HASHcontext,
1901 mr->smr_oid, mlen );
1902 HASH_Update( &HASHcontext,
1903 value->bv_val, klen );
1904 HASH_Final( HASHdigest, &HASHcontext );
1906 ber_dupbv( &keys[nkeys++], &digest );
1909 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1911 pre = SLAP_INDEX_SUBSTR_PREFIX;
1912 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1914 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
1915 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1919 value = &sa->sa_any[i];
1922 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1923 j += SLAP_INDEX_SUBSTR_STEP )
1925 HASH_Init( &HASHcontext );
1926 if( prefix != NULL && prefix->bv_len > 0 ) {
1927 HASH_Update( &HASHcontext,
1928 prefix->bv_val, prefix->bv_len );
1930 HASH_Update( &HASHcontext,
1931 &pre, sizeof( pre ) );
1932 HASH_Update( &HASHcontext,
1933 syntax->ssyn_oid, slen );
1934 HASH_Update( &HASHcontext,
1935 mr->smr_oid, mlen );
1936 HASH_Update( &HASHcontext,
1937 &value->bv_val[j], klen );
1938 HASH_Final( HASHdigest, &HASHcontext );
1940 ber_dupbv( &keys[nkeys++], &digest );
1946 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
1947 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1949 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1950 value = &sa->sa_final;
1952 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1953 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1955 HASH_Init( &HASHcontext );
1956 if( prefix != NULL && prefix->bv_len > 0 ) {
1957 HASH_Update( &HASHcontext,
1958 prefix->bv_val, prefix->bv_len );
1960 HASH_Update( &HASHcontext,
1961 &pre, sizeof( pre ) );
1962 HASH_Update( &HASHcontext,
1963 syntax->ssyn_oid, slen );
1964 HASH_Update( &HASHcontext,
1965 mr->smr_oid, mlen );
1966 HASH_Update( &HASHcontext,
1967 &value->bv_val[value->bv_len-klen], klen );
1968 HASH_Final( HASHdigest, &HASHcontext );
1970 ber_dupbv( &keys[nkeys++], &digest );
1974 keys[nkeys].bv_val = NULL;
1980 if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val );
1981 if ( sa->sa_any ) ber_bvarray_free( sa->sa_any );
1982 if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val );
1985 return LDAP_SUCCESS;
1994 struct berval *value,
1995 void *assertedValue )
1997 *matchp = UTF8bvnormcmp( value,
1998 (struct berval *) assertedValue,
1999 LDAP_UTF8_CASEFOLD );
2000 return LDAP_SUCCESS;
2003 /* Remove all spaces and '-' characters */
2005 xtelephoneNumberNormalize(
2008 struct berval *normalized )
2012 /* validator should have refused an empty string */
2013 assert( val->bv_len );
2015 q = normalized->bv_val = ch_malloc( val->bv_len + 1 );
2017 for( p = val->bv_val; *p; p++ ) {
2018 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
2024 normalized->bv_len = q - normalized->bv_val;
2026 if( normalized->bv_len == 0 ) {
2027 free( normalized->bv_val );
2028 return LDAP_INVALID_SYNTAX;
2031 return LDAP_SUCCESS;
2038 struct berval *val )
2042 if( val->bv_len == 0 ) {
2043 /* disallow empty strings */
2044 return LDAP_INVALID_SYNTAX;
2047 if( OID_LEADCHAR(val->bv_val[0]) ) {
2049 for(i=1; i < val->bv_len; i++) {
2050 if( OID_SEPARATOR( val->bv_val[i] ) ) {
2051 if( dot++ ) return 1;
2052 } else if ( OID_CHAR( val->bv_val[i] ) ) {
2055 return LDAP_INVALID_SYNTAX;
2059 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
2061 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
2062 for(i=1; i < val->bv_len; i++) {
2063 if( !DESC_CHAR(val->bv_val[i] ) ) {
2064 return LDAP_INVALID_SYNTAX;
2068 return LDAP_SUCCESS;
2071 return LDAP_INVALID_SYNTAX;
2074 #ifndef SLAP_NVALUES
2082 struct berval *value,
2083 void *assertedValue )
2086 int vsign = 1, avsign = 1; /* default sign = '+' */
2087 struct berval *asserted;
2088 ber_len_t vlen, avlen;
2091 /* Skip leading space/sign/zeroes, and get the sign of the *value number */
2093 vlen = value->bv_len;
2094 if( mr == slap_schema.si_mr_integerFirstComponentMatch ) {
2095 char *tmp = memchr( v, '$', vlen );
2098 while( vlen && ASCII_SPACE( v[vlen-1] ))
2101 for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) /* ANSI 2.2.1 */
2107 /* Do the same with the *assertedValue number */
2108 asserted = (struct berval *) assertedValue;
2109 av = asserted->bv_val;
2110 avlen = asserted->bv_len;
2111 for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- )
2117 match = vsign - avsign;
2119 match = (vlen != avlen
2120 ? ( vlen < avlen ? -1 : 1 )
2121 : memcmp( v, av, vlen ));
2127 return LDAP_SUCCESS;
2134 struct berval *val )
2138 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2140 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2141 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2142 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2143 return LDAP_INVALID_SYNTAX;
2146 for( i=1; i < val->bv_len; i++ ) {
2147 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2150 return LDAP_SUCCESS;
2153 #ifndef SLAP_NVALUES
2158 struct berval *normalized )
2168 /* Ignore leading spaces */
2169 while ( len && ( *p == ' ' )) {
2176 negative = ( *p == '-' );
2177 if(( *p == '-' ) || ( *p == '+' )) {
2183 /* Ignore leading zeros */
2184 while ( len && ( *p == '0' )) {
2189 /* If there are no non-zero digits left, the number is zero, otherwise
2190 allocate space for the number and copy it into the buffer */
2192 normalized->bv_val = ch_strdup("0");
2193 normalized->bv_len = 1;
2196 normalized->bv_len = len+negative;
2197 normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
2199 normalized->bv_val[0] = '-';
2201 AC_MEMCPY( normalized->bv_val + negative, p, len );
2202 normalized->bv_val[len+negative] = '\0';
2205 return LDAP_SUCCESS;
2208 /* Index generation function */
2209 static int integerIndexer(
2214 struct berval *prefix,
2221 HASH_CONTEXT HASHcontext;
2222 unsigned char HASHdigest[HASH_BYTES];
2223 struct berval digest;
2224 digest.bv_val = HASHdigest;
2225 digest.bv_len = sizeof(HASHdigest);
2227 for( i=0; values[i].bv_val != NULL; i++ ) {
2228 /* empty - just count them */
2231 /* we should have at least one value at this point */
2234 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2236 slen = syntax->ssyn_oidlen;
2237 mlen = mr->smr_oidlen;
2239 for( i=0; values[i].bv_val != NULL; i++ ) {
2241 xintegerNormalize( syntax, &values[i], &norm );
2243 HASH_Init( &HASHcontext );
2244 if( prefix != NULL && prefix->bv_len > 0 ) {
2245 HASH_Update( &HASHcontext,
2246 prefix->bv_val, prefix->bv_len );
2248 HASH_Update( &HASHcontext,
2249 syntax->ssyn_oid, slen );
2250 HASH_Update( &HASHcontext,
2251 mr->smr_oid, mlen );
2252 HASH_Update( &HASHcontext,
2253 norm.bv_val, norm.bv_len );
2254 HASH_Final( HASHdigest, &HASHcontext );
2256 ber_dupbv( &keys[i], &digest );
2257 ch_free( norm.bv_val );
2260 keys[i].bv_val = NULL;
2262 return LDAP_SUCCESS;
2265 /* Index generation function */
2266 static int integerFilter(
2271 struct berval *prefix,
2272 void * assertedValue,
2277 HASH_CONTEXT HASHcontext;
2278 unsigned char HASHdigest[HASH_BYTES];
2280 struct berval digest;
2281 digest.bv_val = HASHdigest;
2282 digest.bv_len = sizeof(HASHdigest);
2284 slen = syntax->ssyn_oidlen;
2285 mlen = mr->smr_oidlen;
2287 xintegerNormalize( syntax, assertedValue, &norm );
2289 keys = ch_malloc( sizeof( struct berval ) * 2 );
2291 HASH_Init( &HASHcontext );
2292 if( prefix != NULL && prefix->bv_len > 0 ) {
2293 HASH_Update( &HASHcontext,
2294 prefix->bv_val, prefix->bv_len );
2296 HASH_Update( &HASHcontext,
2297 syntax->ssyn_oid, slen );
2298 HASH_Update( &HASHcontext,
2299 mr->smr_oid, mlen );
2300 HASH_Update( &HASHcontext,
2301 norm.bv_val, norm.bv_len );
2302 HASH_Final( HASHdigest, &HASHcontext );
2304 ber_dupbv( &keys[0], &digest );
2305 keys[1].bv_val = NULL;
2306 ch_free( norm.bv_val );
2309 return LDAP_SUCCESS;
2315 countryStringValidate(
2317 struct berval *val )
2319 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2321 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2322 return LDAP_INVALID_SYNTAX;
2324 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2325 return LDAP_INVALID_SYNTAX;
2328 return LDAP_SUCCESS;
2332 printableStringValidate(
2334 struct berval *val )
2338 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2340 for(i=0; i < val->bv_len; i++) {
2341 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2342 return LDAP_INVALID_SYNTAX;
2346 return LDAP_SUCCESS;
2350 printablesStringValidate(
2352 struct berval *val )
2356 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2358 for(i=0,len=0; i < val->bv_len; i++) {
2359 int c = val->bv_val[i];
2363 return LDAP_INVALID_SYNTAX;
2367 } else if ( SLAP_PRINTABLE(c) ) {
2370 return LDAP_INVALID_SYNTAX;
2375 return LDAP_INVALID_SYNTAX;
2378 return LDAP_SUCCESS;
2384 struct berval *val )
2388 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
2390 for(i=0; i < val->bv_len; i++) {
2391 if( !LDAP_ASCII(val->bv_val[i]) ) {
2392 return LDAP_INVALID_SYNTAX;
2396 return LDAP_SUCCESS;
2406 struct berval *normalized )
2409 xIA5StringNormalize(
2412 struct berval *normalized )
2417 int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
2420 assert( val->bv_len );
2424 /* Ignore initial whitespace */
2425 while ( ASCII_SPACE( *p ) ) {
2429 normalized->bv_val = ch_strdup( p );
2430 p = q = normalized->bv_val;
2433 if ( ASCII_SPACE( *p ) ) {
2436 /* Ignore the extra whitespace */
2437 while ( ASCII_SPACE( *p ) ) {
2442 } else if ( casefold ) {
2443 /* Most IA5 rules require casefolding */
2444 *q++ = TOLOWER(*p++);
2452 assert( normalized->bv_val <= p );
2456 * If the string ended in space, backup the pointer one
2457 * position. One is enough because the above loop collapsed
2458 * all whitespace to a single space.
2461 if ( ASCII_SPACE( q[-1] ) ) {
2465 /* null terminate */
2468 normalized->bv_len = q - normalized->bv_val;
2470 if( normalized->bv_len == 0 ) {
2471 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
2472 normalized->bv_val[0] = ' ';
2473 normalized->bv_val[1] = '\0';
2474 normalized->bv_len = 1;
2477 return LDAP_SUCCESS;
2480 #ifndef SLAP_NVALUES
2488 struct berval *value,
2489 void *assertedValue )
2491 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2494 match = strncmp( value->bv_val,
2495 ((struct berval *) assertedValue)->bv_val,
2500 return LDAP_SUCCESS;
2504 caseExactIA5SubstringsMatch
2507 octetStringSubstringsMatch
2514 struct berval *value,
2515 void *assertedValue )
2518 SubstringsAssertion *sub = assertedValue;
2519 struct berval left = *value;
2523 /* Add up asserted input length */
2524 if( sub->sa_initial.bv_val ) {
2525 inlen += sub->sa_initial.bv_len;
2528 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
2529 inlen += sub->sa_any[i].bv_len;
2532 if( sub->sa_final.bv_val ) {
2533 inlen += sub->sa_final.bv_len;
2536 if( sub->sa_initial.bv_val ) {
2537 if( inlen > left.bv_len ) {
2542 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
2543 sub->sa_initial.bv_len );
2549 left.bv_val += sub->sa_initial.bv_len;
2550 left.bv_len -= sub->sa_initial.bv_len;
2551 inlen -= sub->sa_initial.bv_len;
2554 if( sub->sa_final.bv_val ) {
2555 if( inlen > left.bv_len ) {
2560 match = memcmp( sub->sa_final.bv_val,
2561 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
2562 sub->sa_final.bv_len );
2568 left.bv_len -= sub->sa_final.bv_len;
2569 inlen -= sub->sa_final.bv_len;
2573 for(i=0; sub->sa_any[i].bv_val; i++) {
2578 if( inlen > left.bv_len ) {
2579 /* not enough length */
2584 if( sub->sa_any[i].bv_len == 0 ) {
2588 p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len );
2595 idx = p - left.bv_val;
2597 if( idx >= left.bv_len ) {
2598 /* this shouldn't happen */
2605 if( sub->sa_any[i].bv_len > left.bv_len ) {
2606 /* not enough left */
2611 match = memcmp( left.bv_val,
2612 sub->sa_any[i].bv_val,
2613 sub->sa_any[i].bv_len );
2621 left.bv_val += sub->sa_any[i].bv_len;
2622 left.bv_len -= sub->sa_any[i].bv_len;
2623 inlen -= sub->sa_any[i].bv_len;
2629 return LDAP_SUCCESS;
2632 #ifndef SLAP_NVALUES
2634 /* Index generation function */
2635 static int caseExactIA5Indexer(
2640 struct berval *prefix,
2647 HASH_CONTEXT HASHcontext;
2648 unsigned char HASHdigest[HASH_BYTES];
2649 struct berval digest;
2650 digest.bv_val = HASHdigest;
2651 digest.bv_len = sizeof(HASHdigest);
2653 for( i=0; values[i].bv_val != NULL; i++ ) {
2654 /* empty - just count them */
2657 /* we should have at least one value at this point */
2660 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
2662 slen = syntax->ssyn_oidlen;
2663 mlen = mr->smr_oidlen;
2665 for( i=0; values[i].bv_val != NULL; i++ ) {
2666 struct berval *value = &values[i];
2668 HASH_Init( &HASHcontext );
2669 if( prefix != NULL && prefix->bv_len > 0 ) {
2670 HASH_Update( &HASHcontext,
2671 prefix->bv_val, prefix->bv_len );
2673 HASH_Update( &HASHcontext,
2674 syntax->ssyn_oid, slen );
2675 HASH_Update( &HASHcontext,
2676 mr->smr_oid, mlen );
2677 HASH_Update( &HASHcontext,
2678 value->bv_val, value->bv_len );
2679 HASH_Final( HASHdigest, &HASHcontext );
2681 ber_dupbv( &keys[i], &digest );
2684 keys[i].bv_val = NULL;
2686 return LDAP_SUCCESS;
2689 /* Index generation function */
2690 static int caseExactIA5Filter(
2695 struct berval *prefix,
2696 void * assertedValue,
2701 HASH_CONTEXT HASHcontext;
2702 unsigned char HASHdigest[HASH_BYTES];
2703 struct berval *value;
2704 struct berval digest;
2705 digest.bv_val = HASHdigest;
2706 digest.bv_len = sizeof(HASHdigest);
2708 slen = syntax->ssyn_oidlen;
2709 mlen = mr->smr_oidlen;
2711 value = (struct berval *) assertedValue;
2713 keys = ch_malloc( sizeof( struct berval ) * 2 );
2715 HASH_Init( &HASHcontext );
2716 if( prefix != NULL && prefix->bv_len > 0 ) {
2717 HASH_Update( &HASHcontext,
2718 prefix->bv_val, prefix->bv_len );
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, value->bv_len );
2726 HASH_Final( HASHdigest, &HASHcontext );
2728 ber_dupbv( &keys[0], &digest );
2729 keys[1].bv_val = NULL;
2732 return LDAP_SUCCESS;
2735 /* Substrings Index generation function */
2736 static int caseExactIA5SubstringsIndexer(
2741 struct berval *prefix,
2748 HASH_CONTEXT HASHcontext;
2749 unsigned char HASHdigest[HASH_BYTES];
2750 struct berval digest;
2751 digest.bv_val = HASHdigest;
2752 digest.bv_len = sizeof(HASHdigest);
2754 /* we should have at least one value at this point */
2755 assert( values != NULL && values[0].bv_val != NULL );
2758 for( i=0; values[i].bv_val != NULL; i++ ) {
2759 /* count number of indices to generate */
2760 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2764 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2765 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2766 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2767 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2769 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2773 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2774 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2775 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2779 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2780 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2781 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2782 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2784 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2790 /* no keys to generate */
2792 return LDAP_SUCCESS;
2795 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2797 slen = syntax->ssyn_oidlen;
2798 mlen = mr->smr_oidlen;
2801 for( i=0; values[i].bv_val != NULL; i++ ) {
2803 struct berval *value;
2806 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2808 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2809 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2811 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2812 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2814 for( j=0; j<max; j++ ) {
2815 HASH_Init( &HASHcontext );
2816 if( prefix != NULL && prefix->bv_len > 0 ) {
2817 HASH_Update( &HASHcontext,
2818 prefix->bv_val, prefix->bv_len );
2821 HASH_Update( &HASHcontext,
2822 &pre, sizeof( pre ) );
2823 HASH_Update( &HASHcontext,
2824 syntax->ssyn_oid, slen );
2825 HASH_Update( &HASHcontext,
2826 mr->smr_oid, mlen );
2827 HASH_Update( &HASHcontext,
2829 SLAP_INDEX_SUBSTR_MAXLEN );
2830 HASH_Final( HASHdigest, &HASHcontext );
2832 ber_dupbv( &keys[nkeys++], &digest );
2836 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2837 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2839 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2842 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2843 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2844 HASH_Init( &HASHcontext );
2845 if( prefix != NULL && prefix->bv_len > 0 ) {
2846 HASH_Update( &HASHcontext,
2847 prefix->bv_val, prefix->bv_len );
2849 HASH_Update( &HASHcontext,
2850 &pre, sizeof( pre ) );
2851 HASH_Update( &HASHcontext,
2852 syntax->ssyn_oid, slen );
2853 HASH_Update( &HASHcontext,
2854 mr->smr_oid, mlen );
2855 HASH_Update( &HASHcontext,
2857 HASH_Final( HASHdigest, &HASHcontext );
2859 ber_dupbv( &keys[nkeys++], &digest );
2862 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2863 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2864 HASH_Init( &HASHcontext );
2865 if( prefix != NULL && prefix->bv_len > 0 ) {
2866 HASH_Update( &HASHcontext,
2867 prefix->bv_val, prefix->bv_len );
2869 HASH_Update( &HASHcontext,
2870 &pre, sizeof( pre ) );
2871 HASH_Update( &HASHcontext,
2872 syntax->ssyn_oid, slen );
2873 HASH_Update( &HASHcontext,
2874 mr->smr_oid, mlen );
2875 HASH_Update( &HASHcontext,
2876 &value->bv_val[value->bv_len-j], j );
2877 HASH_Final( HASHdigest, &HASHcontext );
2879 ber_dupbv( &keys[nkeys++], &digest );
2886 keys[nkeys].bv_val = NULL;
2893 return LDAP_SUCCESS;
2896 static int caseExactIA5SubstringsFilter(
2901 struct berval *prefix,
2902 void * assertedValue,
2905 SubstringsAssertion *sa = assertedValue;
2907 ber_len_t nkeys = 0;
2908 size_t slen, mlen, klen;
2910 HASH_CONTEXT HASHcontext;
2911 unsigned char HASHdigest[HASH_BYTES];
2912 struct berval *value;
2913 struct berval digest;
2915 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2916 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2921 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2923 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2924 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2925 /* don't bother accounting for stepping */
2926 nkeys += sa->sa_any[i].bv_len -
2927 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2932 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
2933 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2940 return LDAP_SUCCESS;
2943 digest.bv_val = HASHdigest;
2944 digest.bv_len = sizeof(HASHdigest);
2946 slen = syntax->ssyn_oidlen;
2947 mlen = mr->smr_oidlen;
2949 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
2952 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL &&
2953 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2955 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2956 value = &sa->sa_initial;
2958 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2959 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2961 HASH_Init( &HASHcontext );
2962 if( prefix != NULL && prefix->bv_len > 0 ) {
2963 HASH_Update( &HASHcontext,
2964 prefix->bv_val, prefix->bv_len );
2966 HASH_Update( &HASHcontext,
2967 &pre, sizeof( pre ) );
2968 HASH_Update( &HASHcontext,
2969 syntax->ssyn_oid, slen );
2970 HASH_Update( &HASHcontext,
2971 mr->smr_oid, mlen );
2972 HASH_Update( &HASHcontext,
2973 value->bv_val, klen );
2974 HASH_Final( HASHdigest, &HASHcontext );
2976 ber_dupbv( &keys[nkeys++], &digest );
2979 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2981 pre = SLAP_INDEX_SUBSTR_PREFIX;
2982 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2984 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
2985 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2989 value = &sa->sa_any[i];
2992 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2993 j += SLAP_INDEX_SUBSTR_STEP )
2995 HASH_Init( &HASHcontext );
2996 if( prefix != NULL && prefix->bv_len > 0 ) {
2997 HASH_Update( &HASHcontext,
2998 prefix->bv_val, prefix->bv_len );
3000 HASH_Update( &HASHcontext,
3001 &pre, sizeof( pre ) );
3002 HASH_Update( &HASHcontext,
3003 syntax->ssyn_oid, slen );
3004 HASH_Update( &HASHcontext,
3005 mr->smr_oid, mlen );
3006 HASH_Update( &HASHcontext,
3007 &value->bv_val[j], klen );
3008 HASH_Final( HASHdigest, &HASHcontext );
3010 ber_dupbv( &keys[nkeys++], &digest );
3015 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final.bv_val != NULL &&
3016 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3018 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3019 value = &sa->sa_final;
3021 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3022 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3024 HASH_Init( &HASHcontext );
3025 if( prefix != NULL && prefix->bv_len > 0 ) {
3026 HASH_Update( &HASHcontext,
3027 prefix->bv_val, prefix->bv_len );
3029 HASH_Update( &HASHcontext,
3030 &pre, sizeof( pre ) );
3031 HASH_Update( &HASHcontext,
3032 syntax->ssyn_oid, slen );
3033 HASH_Update( &HASHcontext,
3034 mr->smr_oid, mlen );
3035 HASH_Update( &HASHcontext,
3036 &value->bv_val[value->bv_len-klen], klen );
3037 HASH_Final( HASHdigest, &HASHcontext );
3039 ber_dupbv( &keys[nkeys++], &digest );
3043 keys[nkeys].bv_val = NULL;
3050 return LDAP_SUCCESS;
3059 struct berval *value,
3060 void *assertedValue )
3062 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
3064 if( match == 0 && value->bv_len ) {
3065 match = strncasecmp( value->bv_val,
3066 ((struct berval *) assertedValue)->bv_val,
3071 return LDAP_SUCCESS;
3075 caseIgnoreIA5SubstringsMatch(
3080 struct berval *value,
3081 void *assertedValue )
3084 SubstringsAssertion *sub = assertedValue;
3085 struct berval left = *value;
3089 /* Add up asserted input length */
3090 if( sub->sa_initial.bv_val ) {
3091 inlen += sub->sa_initial.bv_len;
3094 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
3095 inlen += sub->sa_any[i].bv_len;
3098 if( sub->sa_final.bv_val ) {
3099 inlen += sub->sa_final.bv_len;
3102 if( sub->sa_initial.bv_val ) {
3103 if( inlen > left.bv_len ) {
3108 match = strncasecmp( sub->sa_initial.bv_val, left.bv_val,
3109 sub->sa_initial.bv_len );
3115 left.bv_val += sub->sa_initial.bv_len;
3116 left.bv_len -= sub->sa_initial.bv_len;
3117 inlen -= sub->sa_initial.bv_len;
3120 if( sub->sa_final.bv_val ) {
3121 if( inlen > left.bv_len ) {
3126 match = strncasecmp( sub->sa_final.bv_val,
3127 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
3128 sub->sa_final.bv_len );
3134 left.bv_len -= sub->sa_final.bv_len;
3135 inlen -= sub->sa_final.bv_len;
3139 for(i=0; sub->sa_any[i].bv_val; i++) {
3144 if( inlen > left.bv_len ) {
3145 /* not enough length */
3150 if( sub->sa_any[i].bv_len == 0 ) {
3154 p = bvcasechr( &left, *sub->sa_any[i].bv_val, &idx );
3161 assert( idx < left.bv_len );
3162 if( idx >= left.bv_len ) {
3163 /* this shouldn't happen */
3170 if( sub->sa_any[i].bv_len > left.bv_len ) {
3171 /* not enough left */
3176 match = strncasecmp( left.bv_val,
3177 sub->sa_any[i].bv_val,
3178 sub->sa_any[i].bv_len );
3187 left.bv_val += sub->sa_any[i].bv_len;
3188 left.bv_len -= sub->sa_any[i].bv_len;
3189 inlen -= sub->sa_any[i].bv_len;
3195 return LDAP_SUCCESS;
3198 /* Index generation function */
3199 static int caseIgnoreIA5Indexer(
3204 struct berval *prefix,
3209 int rc = LDAP_SUCCESS;
3212 HASH_CONTEXT HASHcontext;
3213 unsigned char HASHdigest[HASH_BYTES];
3214 struct berval digest;
3215 digest.bv_val = HASHdigest;
3216 digest.bv_len = sizeof(HASHdigest);
3218 /* we should have at least one value at this point */
3219 assert( values != NULL && values[0].bv_val != NULL );
3221 for( i=0; values[i].bv_val != NULL; i++ ) {
3222 /* just count them */
3225 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
3227 slen = syntax->ssyn_oidlen;
3228 mlen = mr->smr_oidlen;
3230 for( i=0; values[i].bv_val != NULL; i++ ) {
3231 struct berval value;
3233 if( mr->smr_normalize ) {
3234 rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value );
3235 if( rc != LDAP_SUCCESS ) {
3238 #ifndef SLAP_NVALUES
3239 } else if ( mr->smr_syntax->ssyn_normalize ) {
3240 rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value );
3241 if( rc != LDAP_SUCCESS ) {
3246 ber_dupbv( &value, &values[i] );
3249 ldap_pvt_str2lower( value.bv_val );
3251 HASH_Init( &HASHcontext );
3252 if( prefix != NULL && prefix->bv_len > 0 ) {
3253 HASH_Update( &HASHcontext,
3254 prefix->bv_val, prefix->bv_len );
3256 HASH_Update( &HASHcontext,
3257 syntax->ssyn_oid, slen );
3258 HASH_Update( &HASHcontext,
3259 mr->smr_oid, mlen );
3260 HASH_Update( &HASHcontext,
3261 value.bv_val, value.bv_len );
3262 HASH_Final( HASHdigest, &HASHcontext );
3264 free( value.bv_val );
3266 ber_dupbv( &keys[i], &digest );
3269 keys[i].bv_val = NULL;
3270 if( rc != LDAP_SUCCESS ) {
3271 ber_bvarray_free( keys );
3278 /* Index generation function */
3279 static int caseIgnoreIA5Filter(
3284 struct berval *prefix,
3285 void * assertedValue,
3290 HASH_CONTEXT HASHcontext;
3291 unsigned char HASHdigest[HASH_BYTES];
3292 struct berval value;
3293 struct berval digest;
3294 digest.bv_val = HASHdigest;
3295 digest.bv_len = sizeof(HASHdigest);
3297 slen = syntax->ssyn_oidlen;
3298 mlen = mr->smr_oidlen;
3300 ber_dupbv( &value, (struct berval *) assertedValue );
3301 ldap_pvt_str2lower( value.bv_val );
3303 keys = ch_malloc( sizeof( struct berval ) * 2 );
3305 HASH_Init( &HASHcontext );
3306 if( prefix != NULL && prefix->bv_len > 0 ) {
3307 HASH_Update( &HASHcontext,
3308 prefix->bv_val, prefix->bv_len );
3310 HASH_Update( &HASHcontext,
3311 syntax->ssyn_oid, slen );
3312 HASH_Update( &HASHcontext,
3313 mr->smr_oid, mlen );
3314 HASH_Update( &HASHcontext,
3315 value.bv_val, value.bv_len );
3316 HASH_Final( HASHdigest, &HASHcontext );
3318 ber_dupbv( &keys[0], &digest );
3319 keys[1].bv_val = NULL;
3321 free( value.bv_val );
3325 return LDAP_SUCCESS;
3328 /* Substrings Index generation function */
3329 static int caseIgnoreIA5SubstringsIndexer(
3334 struct berval *prefix,
3341 HASH_CONTEXT HASHcontext;
3342 unsigned char HASHdigest[HASH_BYTES];
3343 struct berval digest;
3344 digest.bv_val = HASHdigest;
3345 digest.bv_len = sizeof(HASHdigest);
3347 /* we should have at least one value at this point */
3348 assert( values != NULL && values[0].bv_val != NULL );
3351 for( i=0; values[i].bv_val != NULL; i++ ) {
3352 /* count number of indices to generate */
3353 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3357 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3358 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3359 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3360 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3362 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3366 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3367 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3368 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3372 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3373 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3374 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3375 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3377 nkeys += values[i].bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3383 /* no keys to generate */
3385 return LDAP_SUCCESS;
3388 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3390 slen = syntax->ssyn_oidlen;
3391 mlen = mr->smr_oidlen;
3394 for( i=0; values[i].bv_val != NULL; i++ ) {
3396 struct berval value;
3398 if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3400 ber_dupbv( &value, &values[i] );
3401 ldap_pvt_str2lower( value.bv_val );
3403 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3404 ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3406 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3407 max = value.bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3409 for( j=0; j<max; j++ ) {
3410 HASH_Init( &HASHcontext );
3411 if( prefix != NULL && prefix->bv_len > 0 ) {
3412 HASH_Update( &HASHcontext,
3413 prefix->bv_val, prefix->bv_len );
3416 HASH_Update( &HASHcontext,
3417 &pre, sizeof( pre ) );
3418 HASH_Update( &HASHcontext,
3419 syntax->ssyn_oid, slen );
3420 HASH_Update( &HASHcontext,
3421 mr->smr_oid, mlen );
3422 HASH_Update( &HASHcontext,
3424 SLAP_INDEX_SUBSTR_MAXLEN );
3425 HASH_Final( HASHdigest, &HASHcontext );
3427 ber_dupbv( &keys[nkeys++], &digest );
3431 max = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3432 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3434 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3437 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3438 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3439 HASH_Init( &HASHcontext );
3440 if( prefix != NULL && prefix->bv_len > 0 ) {
3441 HASH_Update( &HASHcontext,
3442 prefix->bv_val, prefix->bv_len );
3444 HASH_Update( &HASHcontext,
3445 &pre, sizeof( pre ) );
3446 HASH_Update( &HASHcontext,
3447 syntax->ssyn_oid, slen );
3448 HASH_Update( &HASHcontext,
3449 mr->smr_oid, mlen );
3450 HASH_Update( &HASHcontext,
3452 HASH_Final( HASHdigest, &HASHcontext );
3454 ber_dupbv( &keys[nkeys++], &digest );
3457 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3458 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3459 HASH_Init( &HASHcontext );
3460 if( prefix != NULL && prefix->bv_len > 0 ) {
3461 HASH_Update( &HASHcontext,
3462 prefix->bv_val, prefix->bv_len );
3464 HASH_Update( &HASHcontext,
3465 &pre, sizeof( pre ) );
3466 HASH_Update( &HASHcontext,
3467 syntax->ssyn_oid, slen );
3468 HASH_Update( &HASHcontext,
3469 mr->smr_oid, mlen );
3470 HASH_Update( &HASHcontext,
3471 &value.bv_val[value.bv_len-j], j );
3472 HASH_Final( HASHdigest, &HASHcontext );
3474 ber_dupbv( &keys[nkeys++], &digest );
3479 free( value.bv_val );
3483 keys[nkeys].bv_val = NULL;
3490 return LDAP_SUCCESS;
3493 static int caseIgnoreIA5SubstringsFilter(
3498 struct berval *prefix,
3499 void * assertedValue,
3502 SubstringsAssertion *sa = assertedValue;
3504 ber_len_t nkeys = 0;
3505 size_t slen, mlen, klen;
3507 HASH_CONTEXT HASHcontext;
3508 unsigned char HASHdigest[HASH_BYTES];
3509 struct berval value;
3510 struct berval digest;
3512 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3513 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3518 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3520 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3521 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3522 /* don't bother accounting for stepping */
3523 nkeys += sa->sa_any[i].bv_len -
3524 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3529 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3530 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3537 return LDAP_SUCCESS;
3540 digest.bv_val = HASHdigest;
3541 digest.bv_len = sizeof(HASHdigest);
3543 slen = syntax->ssyn_oidlen;
3544 mlen = mr->smr_oidlen;
3546 keys = ch_malloc( sizeof( struct berval ) * (nkeys+1) );
3549 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial.bv_val != NULL &&
3550 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3552 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3553 ber_dupbv( &value, &sa->sa_initial );
3554 ldap_pvt_str2lower( value.bv_val );
3556 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3557 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3559 HASH_Init( &HASHcontext );
3560 if( prefix != NULL && prefix->bv_len > 0 ) {
3561 HASH_Update( &HASHcontext,
3562 prefix->bv_val, prefix->bv_len );
3564 HASH_Update( &HASHcontext,
3565 &pre, sizeof( pre ) );
3566 HASH_Update( &HASHcontext,
3567 syntax->ssyn_oid, slen );
3568 HASH_Update( &HASHcontext,
3569 mr->smr_oid, mlen );
3570 HASH_Update( &HASHcontext,
3571 value.bv_val, klen );
3572 HASH_Final( HASHdigest, &HASHcontext );
3574 free( value.bv_val );
3575 ber_dupbv( &keys[nkeys++], &digest );
3578 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3580 pre = SLAP_INDEX_SUBSTR_PREFIX;
3581 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3583 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
3584 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3588 ber_dupbv( &value, &sa->sa_any[i] );
3589 ldap_pvt_str2lower( value.bv_val );
3592 j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3593 j += SLAP_INDEX_SUBSTR_STEP )
3595 HASH_Init( &HASHcontext );
3596 if( prefix != NULL && prefix->bv_len > 0 ) {
3597 HASH_Update( &HASHcontext,
3598 prefix->bv_val, prefix->bv_len );
3600 HASH_Update( &HASHcontext,
3601 &pre, sizeof( pre ) );
3602 HASH_Update( &HASHcontext,
3603 syntax->ssyn_oid, slen );
3604 HASH_Update( &HASHcontext,
3605 mr->smr_oid, mlen );
3606 HASH_Update( &HASHcontext,
3607 &value.bv_val[j], klen );
3608 HASH_Final( HASHdigest, &HASHcontext );
3610 ber_dupbv( &keys[nkeys++], &digest );
3613 free( value.bv_val );
3617 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final.bv_val != NULL &&
3618 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3620 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3621 ber_dupbv( &value, &sa->sa_final );
3622 ldap_pvt_str2lower( value.bv_val );
3624 klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len
3625 ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len;
3627 HASH_Init( &HASHcontext );
3628 if( prefix != NULL && prefix->bv_len > 0 ) {
3629 HASH_Update( &HASHcontext,
3630 prefix->bv_val, prefix->bv_len );
3632 HASH_Update( &HASHcontext,
3633 &pre, sizeof( pre ) );
3634 HASH_Update( &HASHcontext,
3635 syntax->ssyn_oid, slen );
3636 HASH_Update( &HASHcontext,
3637 mr->smr_oid, mlen );
3638 HASH_Update( &HASHcontext,
3639 &value.bv_val[value.bv_len-klen], klen );
3640 HASH_Final( HASHdigest, &HASHcontext );
3642 free( value.bv_val );
3643 ber_dupbv( &keys[nkeys++], &digest );
3647 keys[nkeys].bv_val = NULL;
3654 return LDAP_SUCCESS;
3660 numericStringValidate(
3666 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
3668 for(i=0; i < in->bv_len; i++) {
3669 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3670 return LDAP_INVALID_SYNTAX;
3674 return LDAP_SUCCESS;
3677 #ifndef SLAP_NVALUES
3680 xnumericStringNormalize(
3683 struct berval *normalized )
3685 /* removal all spaces */
3688 assert( val->bv_len );
3690 normalized->bv_val = ch_malloc( val->bv_len + 1 );
3693 q = normalized->bv_val;
3696 if ( ASCII_SPACE( *p ) ) {
3697 /* Ignore whitespace */
3704 /* we should have copied no more then is in val */
3705 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
3707 /* null terminate */
3710 normalized->bv_len = q - normalized->bv_val;
3712 if( normalized->bv_len == 0 ) {
3713 normalized->bv_val = ch_realloc( normalized->bv_val, 2 );
3714 normalized->bv_val[0] = ' ';
3715 normalized->bv_val[1] = '\0';
3716 normalized->bv_len = 1;
3719 return LDAP_SUCCESS;
3723 objectIdentifierFirstComponentMatch(
3728 struct berval *value,
3729 void *assertedValue )
3731 int rc = LDAP_SUCCESS;
3733 struct berval *asserted = (struct berval *) assertedValue;
3737 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3738 return LDAP_INVALID_SYNTAX;
3741 /* trim leading white space */
3742 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3746 /* grab next word */
3747 oid.bv_val = &value->bv_val[i];
3748 j = value->bv_len - i;
3749 for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) {
3754 /* insert attributeTypes, objectclass check here */
3755 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3756 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3759 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3760 MatchingRule *asserted_mr = mr_bvfind( asserted );
3761 MatchingRule *stored_mr = mr_bvfind( &oid );
3763 if( asserted_mr == NULL ) {
3764 rc = SLAPD_COMPARE_UNDEFINED;
3766 match = asserted_mr != stored_mr;
3769 } else if ( !strcmp( syntax->ssyn_oid,
3770 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3772 AttributeType *asserted_at = at_bvfind( asserted );
3773 AttributeType *stored_at = at_bvfind( &oid );
3775 if( asserted_at == NULL ) {
3776 rc = SLAPD_COMPARE_UNDEFINED;
3778 match = asserted_at != stored_at;
3781 } else if ( !strcmp( syntax->ssyn_oid,
3782 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3784 ObjectClass *asserted_oc = oc_bvfind( asserted );
3785 ObjectClass *stored_oc = oc_bvfind( &oid );
3787 if( asserted_oc == NULL ) {
3788 rc = SLAPD_COMPARE_UNDEFINED;
3790 match = asserted_oc != stored_oc;
3796 LDAP_LOG( CONFIG, ENTRY,
3797 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3798 match, value->bv_val, asserted->bv_val );
3800 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3801 "%d\n\t\"%s\"\n\t\"%s\"\n",
3802 match, value->bv_val, asserted->bv_val );
3805 if( rc == LDAP_SUCCESS ) *matchp = match;
3817 struct berval *value,
3818 void *assertedValue )
3820 long lValue, lAssertedValue;
3822 /* safe to assume integers are NUL terminated? */
3823 lValue = strtol(value->bv_val, NULL, 10);
3824 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3825 return LDAP_CONSTRAINT_VIOLATION;
3828 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3829 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3830 && errno == ERANGE )
3832 return LDAP_CONSTRAINT_VIOLATION;
3835 *matchp = (lValue & lAssertedValue) ? 0 : 1;
3836 return LDAP_SUCCESS;
3845 struct berval *value,
3846 void *assertedValue )
3848 long lValue, lAssertedValue;
3850 /* safe to assume integers are NUL terminated? */
3851 lValue = strtol(value->bv_val, NULL, 10);
3852 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
3853 return LDAP_CONSTRAINT_VIOLATION;
3856 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3857 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX)
3858 && errno == ERANGE )
3860 return LDAP_CONSTRAINT_VIOLATION;
3863 *matchp = (lValue | lAssertedValue) ? 0 : -1;
3864 return LDAP_SUCCESS;
3867 #ifndef SLAP_NVALUES
3870 #include <openssl/x509.h>
3871 #include <openssl/err.h>
3874 * Next function returns a string representation of a ASN1_INTEGER.
3875 * It works for unlimited lengths.
3878 static struct berval *
3879 asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
3883 static char digit[] = "0123456789";
3885 /* We work backwards, make it fill from the end of buf */
3886 p = buf + sizeof(buf) - 1;
3889 if ( a == NULL || a->length == 0 ) {
3897 /* We want to preserve the original */
3898 copy = ch_malloc(n*sizeof(unsigned int));
3899 for (i = 0; i<n; i++) {
3900 copy[i] = a->data[i];
3904 * base indicates the index of the most significant
3905 * byte that might be nonzero. When it goes off the
3906 * end, we now there is nothing left to do.
3912 for (i = base; i<n; i++ ) {
3913 copy[i] += carry*256;
3914 carry = copy[i] % 10;
3919 * Way too large, we need to leave
3920 * room for sign if negative
3925 *--p = digit[carry];
3927 if (copy[base] == 0) base++;
3932 if ( a->type == V_ASN1_NEG_INTEGER ) {
3936 return ber_str2bv( p, 0, 1, bv );
3940 * Given a certificate in DER format, extract the corresponding
3941 * assertion value for certificateExactMatch
3944 certificateExactConvert(
3946 struct berval * out )
3949 unsigned char *p = in->bv_val;
3950 struct berval serial;
3951 struct berval issuer_dn;
3953 xcert = d2i_X509(NULL, &p, in->bv_len);
3956 LDAP_LOG( CONFIG, ENTRY,
3957 "certificateExactConvert: error parsing cert: %s\n",
3958 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
3960 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3961 "error parsing cert: %s\n",
3962 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3964 return LDAP_INVALID_SYNTAX;
3967 if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
3969 return LDAP_INVALID_SYNTAX;
3971 if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn )
3975 ber_memfree(serial.bv_val);
3976 return LDAP_INVALID_SYNTAX;
3981 out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
3982 out->bv_val = ch_malloc(out->bv_len);
3984 AC_MEMCPY(p, serial.bv_val, serial.bv_len);
3986 AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
3988 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
3989 p += issuer_dn.bv_len;
3993 LDAP_LOG( CONFIG, ARGS,
3994 "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 );
3996 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3998 out->bv_val, NULL, NULL );
4001 ber_memfree(serial.bv_val);
4002 ber_memfree(issuer_dn.bv_val);
4004 return LDAP_SUCCESS;
4008 serial_and_issuer_parse(
4009 struct berval *assertion,
4010 struct berval *serial,
4011 struct berval *issuer_dn
4019 begin = assertion->bv_val;
4020 end = assertion->bv_val+assertion->bv_len-1;
4021 for (p=begin; p<=end && *p != '$'; p++) /* empty */ ;
4022 if ( p > end ) return LDAP_INVALID_SYNTAX;
4024 /* p now points at the $ sign, now use
4025 * begin and end to delimit the serial number
4027 while (ASCII_SPACE(*begin)) begin++;
4029 while (ASCII_SPACE(*end)) end--;
4031 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4033 bv.bv_len = end-begin+1;
4035 ber_dupbv(serial, &bv);
4037 /* now extract the issuer, remember p was at the dollar sign */
4039 end = assertion->bv_val+assertion->bv_len-1;
4040 while (ASCII_SPACE(*begin)) begin++;
4041 /* should we trim spaces at the end too? is it safe always? no, no */
4043 if( end <= begin ) return LDAP_INVALID_SYNTAX;
4046 bv.bv_len = end-begin+1;
4049 dnNormalize2( NULL, &bv, issuer_dn );
4052 return LDAP_SUCCESS;
4056 certificateExactMatch(
4061 struct berval *value,
4062 void *assertedValue )
4065 unsigned char *p = value->bv_val;
4066 struct berval serial;
4067 struct berval issuer_dn;
4068 struct berval asserted_serial;
4069 struct berval asserted_issuer_dn;
4072 xcert = d2i_X509(NULL, &p, value->bv_len);
4075 LDAP_LOG( CONFIG, ENTRY,
4076 "certificateExactMatch: error parsing cert: %s\n",
4077 ERR_error_string(ERR_get_error(),NULL), 0, 0 );
4079 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
4080 "error parsing cert: %s\n",
4081 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4083 return LDAP_INVALID_SYNTAX;
4086 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4087 dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn);
4091 serial_and_issuer_parse(assertedValue,
4092 &asserted_serial, &asserted_issuer_dn);
4097 slap_schema.si_syn_integer,
4098 slap_schema.si_mr_integerMatch,
4101 if ( ret == LDAP_SUCCESS ) {
4102 if ( *matchp == 0 ) {
4103 /* We need to normalize everything for dnMatch */
4107 slap_schema.si_syn_distinguishedName,
4108 slap_schema.si_mr_distinguishedNameMatch,
4110 &asserted_issuer_dn);
4115 LDAP_LOG( CONFIG, ARGS, "certificateExactMatch "
4116 "%d\n\t\"%s $ %s\"\n",
4117 *matchp, serial.bv_val, issuer_dn.bv_val );
4118 LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n",
4119 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4122 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
4123 "%d\n\t\"%s $ %s\"\n",
4124 *matchp, serial.bv_val, issuer_dn.bv_val );
4125 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
4126 asserted_serial.bv_val, asserted_issuer_dn.bv_val,
4130 ber_memfree(serial.bv_val);
4131 ber_memfree(issuer_dn.bv_val);
4132 ber_memfree(asserted_serial.bv_val);
4133 ber_memfree(asserted_issuer_dn.bv_val);
4139 * Index generation function
4140 * We just index the serials, in most scenarios the issuer DN is one of
4141 * a very small set of values.
4143 static int certificateExactIndexer(
4148 struct berval *prefix,
4156 struct berval serial;
4158 /* we should have at least one value at this point */
4159 assert( values != NULL && values[0].bv_val != NULL );
4161 for( i=0; values[i].bv_val != NULL; i++ ) {
4162 /* empty -- just count them */
4165 keys = ch_malloc( sizeof( struct berval ) * (i+1) );
4167 for( i=0; values[i].bv_val != NULL; i++ ) {
4168 p = values[i].bv_val;
4169 xcert = d2i_X509(NULL, &p, values[i].bv_len);
4172 LDAP_LOG( CONFIG, ENTRY,
4173 "certificateExactIndexer: error parsing cert: %s\n",
4174 ERR_error_string(ERR_get_error(),NULL), 0, 0);
4176 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4177 "error parsing cert: %s\n",
4178 ERR_error_string(ERR_get_error(),NULL),
4181 /* Do we leak keys on error? */
4182 return LDAP_INVALID_SYNTAX;
4185 asn1_integer2str(xcert->cert_info->serialNumber, &serial);
4187 xintegerNormalize( slap_schema.si_syn_integer,
4188 &serial, &keys[i] );
4189 ber_memfree(serial.bv_val);
4191 LDAP_LOG( CONFIG, ENTRY,
4192 "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0);
4194 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4201 keys[i].bv_val = NULL;
4203 return LDAP_SUCCESS;
4206 /* Index generation function */
4207 /* We think this is always called with a value in matching rule syntax */
4208 static int certificateExactFilter(
4213 struct berval *prefix,
4214 void * assertedValue,
4218 struct berval asserted_serial;
4221 ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL );
4222 if( ret != LDAP_SUCCESS ) return ret;
4224 keys = ch_malloc( sizeof( struct berval ) * 2 );
4225 xintegerNormalize( syntax, &asserted_serial, &keys[0] );
4226 keys[1].bv_val = NULL;
4229 ber_memfree(asserted_serial.bv_val);
4230 return LDAP_SUCCESS;
4236 check_time_syntax (struct berval *val,
4240 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4241 static int mdays[2][12] = {
4242 /* non-leap years */
4243 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4245 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4248 int part, c, tzoffset, leapyear = 0 ;
4250 if( val->bv_len == 0 ) {
4251 return LDAP_INVALID_SYNTAX;
4254 p = (char *)val->bv_val;
4255 e = p + val->bv_len;
4257 /* Ignore initial whitespace */
4258 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4262 if (e - p < 13 - (2 * start)) {
4263 return LDAP_INVALID_SYNTAX;
4266 for (part = 0; part < 9; part++) {
4270 for (part = start; part < 7; part++) {
4272 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4279 return LDAP_INVALID_SYNTAX;
4281 if (c < 0 || c > 9) {
4282 return LDAP_INVALID_SYNTAX;
4288 return LDAP_INVALID_SYNTAX;
4290 if (c < 0 || c > 9) {
4291 return LDAP_INVALID_SYNTAX;
4296 if (part == 2 || part == 3) {
4299 if (parts[part] < 0) {
4300 return LDAP_INVALID_SYNTAX;
4302 if (parts[part] > ceiling[part]) {
4303 return LDAP_INVALID_SYNTAX;
4307 /* leapyear check for the Gregorian calendar (year>1581) */
4308 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4309 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4314 if (parts[3] > mdays[leapyear][parts[2]]) {
4315 return LDAP_INVALID_SYNTAX;
4320 tzoffset = 0; /* UTC */
4321 } else if (c != '+' && c != '-') {
4322 return LDAP_INVALID_SYNTAX;
4326 } else /* c == '+' */ {
4331 return LDAP_INVALID_SYNTAX;
4334 for (part = 7; part < 9; part++) {
4336 if (c < 0 || c > 9) {
4337 return LDAP_INVALID_SYNTAX;
4342 if (c < 0 || c > 9) {
4343 return LDAP_INVALID_SYNTAX;
4347 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4348 return LDAP_INVALID_SYNTAX;
4353 /* Ignore trailing whitespace */
4354 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4358 return LDAP_INVALID_SYNTAX;
4361 switch ( tzoffset ) {
4362 case -1: /* negativ offset to UTC, ie west of Greenwich */
4363 parts[4] += parts[7];
4364 parts[5] += parts[8];
4365 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4369 c = mdays[leapyear][parts[2]];
4371 if (parts[part] > c) {
4372 parts[part] -= c + 1;
4377 case 1: /* positive offset to UTC, ie east of Greenwich */
4378 parts[4] -= parts[7];
4379 parts[5] -= parts[8];
4380 for (part = 6; --part > 0; ) {
4384 /* first arg to % needs to be non negativ */
4385 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4387 if (parts[part] < 0) {
4388 parts[part] += c + 1;
4393 case 0: /* already UTC */
4397 return LDAP_SUCCESS;
4400 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4405 struct berval *normalized )
4409 rc = check_time_syntax(val, 1, parts);
4410 if (rc != LDAP_SUCCESS) {
4414 normalized->bv_val = ch_malloc( 14 );
4415 if ( normalized->bv_val == NULL ) {
4416 return LBER_ERROR_MEMORY;
4419 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4420 parts[1], parts[2] + 1, parts[3] + 1,
4421 parts[4], parts[5], parts[6] );
4422 normalized->bv_len = 13;
4424 return LDAP_SUCCESS;
4428 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4436 return check_time_syntax(in, 1, parts);
4441 generalizedTimeValidate(
4447 return check_time_syntax(in, 0, parts);
4450 #ifndef SLAP_NVALUES
4453 xgeneralizedTimeNormalize(
4456 struct berval *normalized )
4460 rc = check_time_syntax(val, 0, parts);
4461 if (rc != LDAP_SUCCESS) {
4465 normalized->bv_val = ch_malloc( 16 );
4466 if ( normalized->bv_val == NULL ) {
4467 return LBER_ERROR_MEMORY;
4470 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4471 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4472 parts[4], parts[5], parts[6] );
4473 normalized->bv_len = 15;
4475 return LDAP_SUCCESS;
4480 nisNetgroupTripleValidate(
4482 struct berval *val )
4487 if ( val->bv_len == 0 ) {
4488 return LDAP_INVALID_SYNTAX;
4491 p = (char *)val->bv_val;
4492 e = p + val->bv_len;
4494 if ( *p != '(' /*')'*/ ) {
4495 return LDAP_INVALID_SYNTAX;
4498 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
4502 return LDAP_INVALID_SYNTAX;
4505 } else if ( !AD_CHAR( *p ) ) {
4506 return LDAP_INVALID_SYNTAX;
4510 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4511 return LDAP_INVALID_SYNTAX;
4517 return LDAP_INVALID_SYNTAX;
4520 return LDAP_SUCCESS;
4524 bootParameterValidate(
4526 struct berval *val )
4530 if ( val->bv_len == 0 ) {
4531 return LDAP_INVALID_SYNTAX;
4534 p = (char *)val->bv_val;
4535 e = p + val->bv_len;
4538 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4539 if ( !AD_CHAR( *p ) ) {
4540 return LDAP_INVALID_SYNTAX;
4545 return LDAP_INVALID_SYNTAX;
4549 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4550 if ( !AD_CHAR( *p ) ) {
4551 return LDAP_INVALID_SYNTAX;
4556 return LDAP_INVALID_SYNTAX;
4560 for ( p++; p < e; p++ ) {
4561 if ( !SLAP_PRINTABLE( *p ) ) {
4562 return LDAP_INVALID_SYNTAX;
4566 return LDAP_SUCCESS;
4569 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4570 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4572 static slap_syntax_defs_rec syntax_defs[] = {
4573 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
4574 X_BINARY X_NOT_H_R ")",
4575 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4576 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4577 0, NULL, NULL, NULL},
4578 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4579 0, NULL, NULL, NULL},
4580 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
4582 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4583 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
4585 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4586 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4587 0, bitStringValidate, NULL, NULL },
4588 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4589 0, booleanValidate, NULL, NULL},
4590 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4591 X_BINARY X_NOT_H_R ")",
4592 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4593 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4594 X_BINARY X_NOT_H_R ")",
4595 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4596 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4597 X_BINARY X_NOT_H_R ")",
4598 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4599 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4600 0, countryStringValidate, xIA5StringNormalize, NULL},
4601 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4602 0, dnValidate, xdnNormalize, dnPretty2},
4603 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4604 0, NULL, NULL, NULL},
4605 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4606 0, NULL, NULL, NULL},
4607 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4608 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4609 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4610 0, NULL, NULL, NULL},
4611 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4612 0, NULL, NULL, NULL},
4613 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4614 0, NULL, NULL, NULL},
4615 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4616 0, NULL, NULL, NULL},
4617 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4618 0, NULL, NULL, NULL},
4619 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4620 0, printablesStringValidate, xtelephoneNumberNormalize, NULL},
4621 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4622 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4623 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4624 0, generalizedTimeValidate, xgeneralizedTimeNormalize, NULL},
4625 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4626 0, NULL, NULL, NULL},
4627 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4628 0, IA5StringValidate, xIA5StringNormalize, NULL},
4629 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4630 0, integerValidate, xintegerNormalize, NULL},
4631 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4632 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4633 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4634 0, NULL, NULL, NULL},
4635 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4636 0, NULL, NULL, NULL},
4637 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4638 0, NULL, NULL, NULL},
4639 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4640 0, NULL, NULL, NULL},
4641 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4642 0, NULL, NULL, NULL},
4643 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4644 0, nameUIDValidate, xnameUIDNormalize, NULL},
4645 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4646 0, NULL, NULL, NULL},
4647 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4648 0, numericStringValidate, xnumericStringNormalize, NULL},
4649 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4650 0, NULL, NULL, NULL},
4651 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4652 0, oidValidate, NULL, NULL},
4653 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4654 0, IA5StringValidate, xIA5StringNormalize, NULL},
4655 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4656 0, blobValidate, NULL, NULL},
4657 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4658 0, UTF8StringValidate, xUTF8StringNormalize, NULL},
4659 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4660 0, NULL, NULL, NULL},
4661 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4662 0, NULL, NULL, NULL},
4663 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4664 0, printableStringValidate, xIA5StringNormalize, NULL},
4665 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' "
4666 X_BINARY X_NOT_H_R ")",
4667 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4668 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4669 X_BINARY X_NOT_H_R ")",
4670 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4671 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4672 0, printableStringValidate, xtelephoneNumberNormalize, NULL},
4673 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4674 0, NULL, NULL, NULL},
4675 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4676 0, printablesStringValidate, xIA5StringNormalize, NULL},
4677 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
4678 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4679 0, utcTimeValidate, xutcTimeNormalize, NULL},
4681 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4682 0, NULL, NULL, NULL},
4683 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4684 0, NULL, NULL, NULL},
4685 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4686 0, NULL, NULL, NULL},
4687 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4688 0, NULL, NULL, NULL},
4689 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4690 0, NULL, NULL, NULL},
4692 /* RFC 2307 NIS Syntaxes */
4693 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4694 0, nisNetgroupTripleValidate, NULL, NULL},
4695 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4696 0, bootParameterValidate, NULL, NULL},
4700 /* These OIDs are not published yet, but will be in the next
4701 * I-D for PKIX LDAPv3 schema as have been advanced by David
4702 * Chadwick in private mail.
4704 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4705 0, UTF8StringValidate, NULL, NULL},
4708 /* OpenLDAP Experimental Syntaxes */
4709 #ifdef SLAPD_ACI_ENABLED
4710 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4712 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4716 #ifdef SLAPD_AUTHPASSWD
4717 /* needs updating */
4718 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4719 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4722 /* OpenLDAP Void Syntax */
4723 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4724 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4725 {NULL, 0, NULL, NULL, NULL}
4729 char *certificateExactMatchSyntaxes[] = {
4730 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
4734 char *directoryStringSyntaxes[] = {
4735 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
4738 char *integerFirstComponentMatchSyntaxes[] = {
4739 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
4740 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
4743 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
4744 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
4745 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
4746 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
4747 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
4748 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
4749 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
4750 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
4751 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
4756 * Other matching rules in X.520 that we do not use (yet):
4758 * 2.5.13.9 numericStringOrderingMatch
4759 * 2.5.13.25 uTCTimeMatch
4760 * 2.5.13.26 uTCTimeOrderingMatch
4761 * 2.5.13.31 directoryStringFirstComponentMatch
4762 * 2.5.13.32 wordMatch
4763 * 2.5.13.33 keywordMatch
4764 * 2.5.13.35 certificateMatch
4765 * 2.5.13.36 certificatePairExactMatch
4766 * 2.5.13.37 certificatePairMatch
4767 * 2.5.13.38 certificateListExactMatch
4768 * 2.5.13.39 certificateListMatch
4769 * 2.5.13.40 algorithmIdentifierMatch
4770 * 2.5.13.41 storedPrefixMatch
4771 * 2.5.13.42 attributeCertificateMatch
4772 * 2.5.13.43 readerAndKeyIDMatch
4773 * 2.5.13.44 attributeIntegrityMatch
4775 static slap_mrule_defs_rec mrule_defs[] = {
4777 * EQUALITY matching rules must be listed after associated APPROX
4778 * matching rules. So, we list all APPROX matching rules first.
4780 #ifndef SLAP_NVALUES
4781 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4782 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4783 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4784 NULL, NULL, directoryStringApproxMatch,
4785 directoryStringApproxIndexer, directoryStringApproxFilter,
4788 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4789 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4790 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
4791 NULL, NULL, IA5StringApproxMatch,
4792 IA5StringApproxIndexer, IA5StringApproxFilter,
4797 * Other matching rules
4800 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4801 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4802 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4804 objectIdentifierNormalize, objectIdentifierMatch,
4805 objectIdentifierIndexer, objectIdentifierFilter,
4808 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4809 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4810 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4812 distinguishedNameNormalize, distinguishedNameMatch,
4813 distinguishedNameIndexer, distinguishedNameFilter,
4816 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4817 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4818 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4819 directoryStringSyntaxes,
4821 caseIgnoreNormalize, caseIgnoreMatch,
4822 caseIgnoreIndexer, caseIgnoreFilter,
4823 directoryStringApproxMatchOID },
4825 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4826 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4827 SLAP_MR_ORDERING, directoryStringSyntaxes,
4828 NULL, caseIgnoreNormalize, caseIgnoreOrderingMatch,
4831 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4832 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4833 SLAP_MR_SUBSTR, NULL,
4835 caseIgnoreSubstringsMatch,
4836 caseIgnoreSubstringsIndexer, caseIgnoreSubstringsFilter,
4839 {"( 2.5.13.5 NAME 'caseExactMatch' "
4840 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4841 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
4843 caseExactNormalize, caseExactMatch,
4844 caseExactIndexer, caseExactFilter,
4845 directoryStringApproxMatchOID },
4847 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4848 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4849 SLAP_MR_ORDERING, directoryStringSyntaxes,
4850 NULL, caseExactNormalize, caseExactOrderingMatch,
4853 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4854 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4855 SLAP_MR_SUBSTR, directoryStringSyntaxes,
4857 NULL, caseExactSubstringsMatch,
4858 caseExactSubstringsIndexer, caseExactSubstringsFilter,
4861 {"( 2.5.13.8 NAME 'numericStringMatch' "
4862 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4863 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4865 numericStringNormalize, numericStringMatch,
4866 numericStringIndexer, numericStringFilter,
4869 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4870 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4871 SLAP_MR_SUBSTR, NULL,
4873 NULL, numericStringSubstringsMatch,
4874 numericStringSubstringsIndexer, numericStringSubstringsFilter,
4877 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4878 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4879 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4880 NULL, NULL, NULL, NULL, NULL, NULL},
4882 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4883 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4884 SLAP_MR_SUBSTR, NULL,
4885 NULL, NULL, NULL, NULL, NULL, NULL},
4887 {"( 2.5.13.13 NAME 'booleanMatch' "
4888 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4889 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4890 NULL, NULL, booleanMatch, NULL, NULL, NULL},
4892 {"( 2.5.13.14 NAME 'integerMatch' "
4893 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4894 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4896 integerNormalize, integerMatch,
4897 integerIndexer, integerFilter,
4900 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
4901 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4902 SLAP_MR_ORDERING, NULL, NULL,
4903 integerNormalize, integerOrderingMatch,
4904 integerIndexer, integerFilter,
4907 {"( 2.5.13.16 NAME 'bitStringMatch' "
4908 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4909 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4911 bitStringNormalize, bitStringMatch,
4912 bitStringIndexer, bitStringFilter,
4915 {"( 2.5.13.17 NAME 'octetStringMatch' "
4916 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4917 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4919 octetStringMatch, octetStringIndexer, octetStringFilter,
4922 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
4923 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4924 SLAP_MR_ORDERING, NULL,
4926 octetStringOrderingMatch, NULL, NULL,
4929 {"( 2.5.13.19 NAME 'octetStringSubstringsMatch' "
4930 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4931 SLAP_MR_SUBSTR, NULL,
4933 octetStringSubstringsMatch, NULL, NULL,
4936 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4937 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4938 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
4940 telephoneNumberNormalize, telephoneNumberMatch,
4941 telephoneNumberIndexer, telephoneNumberFilter,
4944 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4945 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4946 SLAP_MR_SUBSTR, NULL,
4947 NULL, NULL, telephoneNumberSubstringsMatch,
4948 telephoneNumberSubstringsIndexer, telephoneNumberSubstringsFilter,
4951 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4952 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4953 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4958 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4959 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4960 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4962 uniqueMemberNormalize, uniqueMemberMatch,
4966 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4967 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4968 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4969 NULL, NULL, NULL, NULL, NULL, NULL},
4971 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4972 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4973 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
4975 generalizedTimeNormalize, generalizedTimeMatch,
4979 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4980 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4981 SLAP_MR_ORDERING, NULL,
4983 generalizedTimeNormalize, generalizedTimeOrderingMatch,
4987 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4988 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4989 SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes,
4991 integerFirstComponentNormalize, integerMatch,
4995 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4996 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4997 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4998 objectIdentifierFirstComponentMatchSyntaxes,
5000 objectIdentifierFirstComponentNormalize, objectIdentifierMatch,
5004 #ifndef SLAP_NVALUES
5006 {"( 2.5.13.34 NAME 'certificateExactMatch' "
5007 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
5008 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
5009 certificateExactConvert, NULL,
5010 certificateExactMatch,
5011 certificateExactIndexer, certificateExactFilter,
5016 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
5017 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5018 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
5020 caseExactIA5Normalize, caseExactIA5Match,
5021 caseExactIA5Indexer, caseExactIA5Filter,
5022 IA5StringApproxMatchOID },
5024 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
5025 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5026 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL,
5028 NULL, caseIgnoreIA5Match,
5029 caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
5030 IA5StringApproxMatchOID },
5032 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
5033 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5034 SLAP_MR_SUBSTR, NULL,
5036 NULL, caseIgnoreIA5SubstringsMatch,
5037 caseIgnoreIA5SubstringsIndexer, caseIgnoreIA5SubstringsFilter,
5040 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
5041 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5042 SLAP_MR_SUBSTR, NULL,
5044 NULL, caseExactIA5SubstringsMatch,
5045 caseExactIA5SubstringsIndexer, caseExactIA5SubstringsFilter,
5048 #ifdef SLAPD_AUTHPASSWD
5049 /* needs updating */
5050 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
5051 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
5052 SLAP_MR_EQUALITY, NULL,
5054 authPasswordMatch, NULL, NULL,
5058 #ifdef SLAPD_ACI_ENABLED
5059 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
5060 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
5061 SLAP_MR_EQUALITY, NULL,
5063 OpenLDAPaciMatch, NULL, NULL,
5067 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
5068 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5071 NULL, integerBitAndMatch, NULL, NULL,
5074 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
5075 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5078 NULL, integerBitOrMatch, NULL, NULL,
5081 {NULL, SLAP_MR_NONE, NULL,
5082 NULL, NULL, NULL, NULL, NULL,
5087 slap_schema_init( void )
5092 /* we should only be called once (from main) */
5093 assert( schema_init_done == 0 );
5095 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
5096 res = register_syntax( &syntax_defs[i] );
5099 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
5100 syntax_defs[i].sd_desc );
5105 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
5106 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
5107 mrule_defs[i].mrd_compat_syntaxes == NULL )
5110 "slap_schema_init: Ignoring unusable matching rule %s\n",
5111 mrule_defs[i].mrd_desc );
5115 res = register_matching_rule( &mrule_defs[i] );
5119 "slap_schema_init: Error registering matching rule %s\n",
5120 mrule_defs[i].mrd_desc );
5125 res = slap_schema_load();
5126 schema_init_done = 1;
5131 schema_destroy( void )