1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
13 #include <ac/string.h>
14 #include <ac/socket.h>
18 #include "lutil_md5.h"
20 /* recycled validatation routines */
21 #define berValidate blobValidate
23 /* unimplemented pretters */
25 #define integerPretty NULL
27 /* recycled matching routines */
28 #define bitStringMatch octetStringMatch
29 #define integerMatch caseIgnoreIA5Match
30 #define numericStringMatch caseIgnoreIA5Match
31 #define objectIdentifierMatch caseIgnoreIA5Match
32 #define telephoneNumberMatch caseIgnoreIA5Match
33 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
34 #define generalizedTimeMatch caseIgnoreIA5Match
35 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
36 #define uniqueMemberMatch dnMatch
38 /* approx matching rules */
39 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
40 #define directoryStringApproxMatch NULL
41 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
42 #define IA5StringApproxMatch NULL
44 /* orderring matching rules */
45 #define caseIgnoreOrderingMatch caseIgnoreMatch
46 #define caseExactOrderingMatch caseExactMatch
48 /* unimplemented matching routines */
49 #define caseIgnoreListMatch NULL
50 #define caseIgnoreListSubstringsMatch NULL
51 #define protocolInformationMatch NULL
52 #define integerFirstComponentMatch NULL
54 #define OpenLDAPaciMatch NULL
55 #define authPasswordMatch NULL
57 /* recycled indexing/filtering routines */
58 #define dnIndexer caseIgnoreIndexer
59 #define dnFilter caseIgnoreFilter
60 #define integerIndexer caseIgnoreIA5Indexer
61 #define integerFilter caseIgnoreIA5Filter
63 #define telephoneNumberIndexer caseIgnoreIA5Indexer
64 #define telephoneNumberFilter caseIgnoreIA5Filter
65 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
66 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
68 static char *strcasechr( const char *str, int c )
70 char *lower = strchr( str, TOLOWER(c) );
71 char *upper = strchr( str, TOUPPER(c) );
73 if( lower && upper ) {
74 return lower < upper ? lower : upper;
91 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
94 match = memcmp( value->bv_val,
95 ((struct berval *) assertedValue)->bv_val,
103 /* Index generation function */
104 int octetStringIndexer(
109 struct berval *prefix,
110 struct berval **values,
111 struct berval ***keysp )
115 struct berval **keys;
116 lutil_MD5_CTX MD5context;
117 unsigned char MD5digest[16];
118 struct berval digest;
119 digest.bv_val = MD5digest;
120 digest.bv_len = sizeof(MD5digest);
122 /* we should have at least one value at this point */
123 assert( values != NULL && values[0] != NULL );
125 for( i=0; values[i] != NULL; i++ ) {
126 /* just count them */
129 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
131 slen = strlen( syntax->ssyn_oid );
132 mlen = strlen( mr->smr_oid );
134 for( i=0; values[i] != NULL; i++ ) {
135 lutil_MD5Init( &MD5context );
136 if( prefix != NULL && prefix->bv_len > 0 ) {
137 lutil_MD5Update( &MD5context,
138 prefix->bv_val, prefix->bv_len );
140 lutil_MD5Update( &MD5context,
141 syntax->ssyn_oid, slen );
142 lutil_MD5Update( &MD5context,
144 lutil_MD5Update( &MD5context,
145 values[i]->bv_val, values[i]->bv_len );
146 lutil_MD5Final( MD5digest, &MD5context );
148 keys[i] = ber_bvdup( &digest );
158 /* Index generation function */
159 int octetStringFilter(
164 struct berval *prefix,
166 struct berval ***keysp )
169 struct berval **keys;
170 lutil_MD5_CTX MD5context;
171 unsigned char MD5digest[LUTIL_MD5_BYTES];
172 struct berval *value = (struct berval *) assertValue;
173 struct berval digest;
174 digest.bv_val = MD5digest;
175 digest.bv_len = sizeof(MD5digest);
177 slen = strlen( syntax->ssyn_oid );
178 mlen = strlen( mr->smr_oid );
180 keys = ch_malloc( sizeof( struct berval * ) * 2 );
182 lutil_MD5Init( &MD5context );
183 if( prefix != NULL && prefix->bv_len > 0 ) {
184 lutil_MD5Update( &MD5context,
185 prefix->bv_val, prefix->bv_len );
187 lutil_MD5Update( &MD5context,
188 syntax->ssyn_oid, slen );
189 lutil_MD5Update( &MD5context,
191 lutil_MD5Update( &MD5context,
192 value->bv_val, value->bv_len );
193 lutil_MD5Final( MD5digest, &MD5context );
195 keys[0] = ber_bvdup( &digest );
211 if( in->bv_len == 0 ) return LDAP_SUCCESS;
213 dn = ch_strdup( in->bv_val );
215 rc = dn_validate( dn ) == NULL
216 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
226 struct berval **normalized )
228 struct berval *out = ber_bvdup( val );
230 if( out->bv_len != 0 ) {
232 #ifdef USE_DN_NORMALIZE
233 dn = dn_normalize( out->bv_val );
235 dn = dn_validate( out->bv_val );
240 return LDAP_INVALID_SYNTAX;
244 out->bv_len = strlen( dn );
257 struct berval *value,
258 void *assertedValue )
261 struct berval *asserted = (struct berval *) assertedValue;
263 match = value->bv_len - asserted->bv_len;
266 #ifdef USE_DN_NORMALIZE
267 match = strcmp( value->bv_val, asserted->bv_val );
269 match = strcasecmp( value->bv_val, asserted->bv_val );
273 Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
274 match, value->bv_val, asserted->bv_val );
288 if( in->bv_len == 0 ) return LDAP_SUCCESS;
290 dn = ber_bvdup( in );
292 if( dn->bv_val[dn->bv_len-1] == '\'' ) {
293 /* assume presence of optional UID */
296 for(i=dn->bv_len-2; i>2; i--) {
297 if( dn->bv_val[i] != '0' && dn->bv_val[i] != '1' ) {
301 if( dn->bv_val[i] != '\'' ) {
302 return LDAP_INVALID_SYNTAX;
304 if( dn->bv_val[i-1] != 'B' ) {
305 return LDAP_INVALID_SYNTAX;
307 if( dn->bv_val[i-2] != '#' ) {
308 return LDAP_INVALID_SYNTAX;
311 /* trim the UID to allow use of dn_validate */
312 dn->bv_val[i-2] = '\0';
315 rc = dn_validate( dn->bv_val ) == NULL
316 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
326 struct berval **normalized )
328 struct berval *out = ber_bvdup( val );
330 if( out->bv_len != 0 ) {
334 ber_len_t uidlen = 0;
336 if( out->bv_val[out->bv_len-1] == '\'' ) {
337 /* assume presence of optional UID */
338 uid = strrchr( out->bv_val, '#' );
342 return LDAP_INVALID_SYNTAX;
345 uidlen = out->bv_len - (out->bv_val - uid);
346 /* temporarily trim the UID */
350 #ifdef USE_DN_NORMALIZE
351 dn = dn_normalize( out->bv_val );
353 dn = dn_validate( out->bv_val );
358 return LDAP_INVALID_SYNTAX;
364 /* restore the separator */
367 SAFEMEMCPY( &dn[dnlen], uid, uidlen );
371 out->bv_len = dnlen + uidlen;
373 out->bv_val[out->bv_len] = '\0';
385 /* any value allowed */
394 /* any value allowed */
405 /* very unforgiving validation, requires no normalization
406 * before simplistic matching
408 if( in->bv_len < 3 ) {
409 return LDAP_INVALID_SYNTAX;
412 if( in->bv_val[0] != 'B' ||
413 in->bv_val[1] != '\'' ||
414 in->bv_val[in->bv_len-1] != '\'' )
416 return LDAP_INVALID_SYNTAX;
419 for( i=in->bv_len-2; i>1; i-- ) {
420 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
421 return LDAP_INVALID_SYNTAX;
429 * Handling boolean syntax and matching is quite rigid.
430 * A more flexible approach would be to allow a variety
431 * of strings to be normalized and prettied into TRUE
439 /* very unforgiving validation, requires no normalization
440 * before simplistic matching
443 if( in->bv_len == 4 ) {
444 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
447 } else if( in->bv_len == 5 ) {
448 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
453 return LDAP_INVALID_SYNTAX;
462 struct berval *value,
463 void *assertedValue )
465 /* simplistic matching allowed by rigid validation */
466 struct berval *asserted = (struct berval *) assertedValue;
467 *matchp = value->bv_len != asserted->bv_len;
474 struct berval *right,
475 struct berval *left )
478 ber_len_t rlen, llen;
479 ber_len_t rslen, lslen;
480 ldap_unicode_t ru, lu;
481 ldap_unicode_t ruu, luu;
484 r < right->bv_len && l < left->bv_len;
488 * XXYYZ: we convert to ucs4 even though -llunicode
489 * expects ucs2 in an unsigned long
491 ru = ldap_utf8_to_ucs4( &right->bv_val[r] );
492 if( ru == LDAP_UCS4_INVALID ) {
496 lu = ldap_utf8_to_ucs4( &left->bv_val[l] );
497 if( lu == LDAP_UCS4_INVALID ) {
501 ruu = uctoupper( ru );
502 luu = uctoupper( lu );
506 } else if( luu > ruu ) {
510 rlen = LDAP_UTF8_CHARLEN( &right->bv_val[r] );
511 llen = LDAP_UTF8_CHARLEN( &left->bv_val[l] );
514 if( r < right->bv_len ) {
519 if( l < left->bv_len ) {
535 unsigned char *u = in->bv_val;
537 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
539 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
540 /* get the length indicated by the first byte */
541 len = LDAP_UTF8_CHARLEN( u );
543 /* should not be zero */
544 if( len == 0 ) return LDAP_INVALID_SYNTAX;
546 /* make sure len corresponds with the offset
547 to the next character */
548 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
551 if( count != 0 ) return LDAP_INVALID_SYNTAX;
560 struct berval **normalized )
562 struct berval *newval;
565 newval = ch_malloc( sizeof( struct berval ) );
569 /* Ignore initial whitespace */
570 while ( ldap_utf8_isspace( p ) ) {
576 return LDAP_INVALID_SYNTAX;
579 newval->bv_val = ch_strdup( p );
580 p = q = newval->bv_val;
586 if ( ldap_utf8_isspace( p ) ) {
587 len = LDAP_UTF8_COPY(q,p);
592 /* Ignore the extra whitespace */
593 while ( ldap_utf8_isspace( p ) ) {
597 len = LDAP_UTF8_COPY(q,p);
604 assert( *newval->bv_val );
605 assert( newval->bv_val < p );
608 /* cannot start with a space */
609 assert( !ldap_utf8_isspace(newval->bv_val) );
612 * If the string ended in space, backup the pointer one
613 * position. One is enough because the above loop collapsed
614 * all whitespace to a single space.
621 /* cannot end with a space */
622 assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
627 newval->bv_len = q - newval->bv_val;
628 *normalized = newval;
639 struct berval *value,
640 void *assertedValue )
642 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
645 match = strncmp( value->bv_val,
646 ((struct berval *) assertedValue)->bv_val,
655 caseExactSubstringsMatch(
660 struct berval *value,
661 void *assertedValue )
664 SubstringsAssertion *sub = assertedValue;
665 struct berval left = *value;
669 /* Add up asserted input length */
670 if( sub->sa_initial ) {
671 inlen += sub->sa_initial->bv_len;
674 for(i=0; sub->sa_any[i] != NULL; i++) {
675 inlen += sub->sa_any[i]->bv_len;
678 if( sub->sa_final ) {
679 inlen += sub->sa_final->bv_len;
682 if( sub->sa_initial ) {
683 if( inlen > left.bv_len ) {
688 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
689 sub->sa_initial->bv_len );
695 left.bv_val += sub->sa_initial->bv_len;
696 left.bv_len -= sub->sa_initial->bv_len;
697 inlen -= sub->sa_initial->bv_len;
700 if( sub->sa_final ) {
701 if( inlen > left.bv_len ) {
706 match = strncmp( sub->sa_final->bv_val,
707 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
708 sub->sa_final->bv_len );
714 left.bv_len -= sub->sa_final->bv_len;
715 inlen -= sub->sa_final->bv_len;
719 for(i=0; sub->sa_any[i]; i++) {
724 if( inlen > left.bv_len ) {
725 /* not enough length */
730 if( sub->sa_any[i]->bv_len == 0 ) {
734 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
741 idx = p - left.bv_val;
742 assert( idx < left.bv_len );
744 if( idx >= left.bv_len ) {
745 /* this shouldn't happen */
752 if( sub->sa_any[i]->bv_len > left.bv_len ) {
753 /* not enough left */
758 match = strncmp( left.bv_val,
759 sub->sa_any[i]->bv_val,
760 sub->sa_any[i]->bv_len );
768 left.bv_val += sub->sa_any[i]->bv_len;
769 left.bv_len -= sub->sa_any[i]->bv_len;
770 inlen -= sub->sa_any[i]->bv_len;
779 /* Index generation function */
780 int caseExactIndexer(
785 struct berval *prefix,
786 struct berval **values,
787 struct berval ***keysp )
791 struct berval **keys;
792 lutil_MD5_CTX MD5context;
793 unsigned char MD5digest[16];
794 struct berval digest;
795 digest.bv_val = MD5digest;
796 digest.bv_len = sizeof(MD5digest);
798 /* we should have at least one value at this point */
799 assert( values != NULL && values[0] != NULL );
801 for( i=0; values[i] != NULL; i++ ) {
802 /* just count them */
805 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
807 slen = strlen( syntax->ssyn_oid );
808 mlen = strlen( mr->smr_oid );
810 for( i=0; values[i] != NULL; i++ ) {
811 struct berval *value = values[i];
813 lutil_MD5Init( &MD5context );
814 if( prefix != NULL && prefix->bv_len > 0 ) {
815 lutil_MD5Update( &MD5context,
816 prefix->bv_val, prefix->bv_len );
818 lutil_MD5Update( &MD5context,
819 syntax->ssyn_oid, slen );
820 lutil_MD5Update( &MD5context,
822 lutil_MD5Update( &MD5context,
823 value->bv_val, value->bv_len );
824 lutil_MD5Final( MD5digest, &MD5context );
826 keys[i] = ber_bvdup( &digest );
834 /* Index generation function */
840 struct berval *prefix,
842 struct berval ***keysp )
845 struct berval **keys;
846 lutil_MD5_CTX MD5context;
847 unsigned char MD5digest[LUTIL_MD5_BYTES];
848 struct berval *value;
849 struct berval digest;
850 digest.bv_val = MD5digest;
851 digest.bv_len = sizeof(MD5digest);
853 slen = strlen( syntax->ssyn_oid );
854 mlen = strlen( mr->smr_oid );
856 value = (struct berval *) assertValue;
858 keys = ch_malloc( sizeof( struct berval * ) * 2 );
860 lutil_MD5Init( &MD5context );
861 if( prefix != NULL && prefix->bv_len > 0 ) {
862 lutil_MD5Update( &MD5context,
863 prefix->bv_val, prefix->bv_len );
865 lutil_MD5Update( &MD5context,
866 syntax->ssyn_oid, slen );
867 lutil_MD5Update( &MD5context,
869 lutil_MD5Update( &MD5context,
870 value->bv_val, value->bv_len );
871 lutil_MD5Final( MD5digest, &MD5context );
873 keys[0] = ber_bvdup( &digest );
880 /* Substrings Index generation function */
881 int caseExactSubstringsIndexer(
886 struct berval *prefix,
887 struct berval **values,
888 struct berval ***keysp )
892 struct berval **keys;
893 lutil_MD5_CTX MD5context;
894 unsigned char MD5digest[16];
895 struct berval digest;
896 digest.bv_val = MD5digest;
897 digest.bv_len = sizeof(MD5digest);
899 /* we should have at least one value at this point */
900 assert( values != NULL && values[0] != NULL );
903 for( i=0; values[i] != NULL; i++ ) {
904 /* count number of indices to generate */
905 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
909 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
910 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
911 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
912 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
914 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
918 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
919 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
920 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
924 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
925 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
926 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
927 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
929 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
935 /* no keys to generate */
940 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
942 slen = strlen( syntax->ssyn_oid );
943 mlen = strlen( mr->smr_oid );
946 for( i=0; values[i] != NULL; i++ ) {
948 struct berval *value;
951 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
953 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
954 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
956 char pre = SLAP_INDEX_SUBSTR_PREFIX;
957 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
959 for( j=0; j<max; j++ ) {
960 lutil_MD5Init( &MD5context );
961 if( prefix != NULL && prefix->bv_len > 0 ) {
962 lutil_MD5Update( &MD5context,
963 prefix->bv_val, prefix->bv_len );
966 lutil_MD5Update( &MD5context,
967 &pre, sizeof( pre ) );
968 lutil_MD5Update( &MD5context,
969 syntax->ssyn_oid, slen );
970 lutil_MD5Update( &MD5context,
972 lutil_MD5Update( &MD5context,
974 SLAP_INDEX_SUBSTR_MAXLEN );
975 lutil_MD5Final( MD5digest, &MD5context );
977 keys[nkeys++] = ber_bvdup( &digest );
981 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
982 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
984 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
987 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
988 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
989 lutil_MD5Init( &MD5context );
990 if( prefix != NULL && prefix->bv_len > 0 ) {
991 lutil_MD5Update( &MD5context,
992 prefix->bv_val, prefix->bv_len );
994 lutil_MD5Update( &MD5context,
995 &pre, sizeof( pre ) );
996 lutil_MD5Update( &MD5context,
997 syntax->ssyn_oid, slen );
998 lutil_MD5Update( &MD5context,
1000 lutil_MD5Update( &MD5context,
1002 lutil_MD5Final( MD5digest, &MD5context );
1004 keys[nkeys++] = ber_bvdup( &digest );
1007 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1008 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1009 lutil_MD5Init( &MD5context );
1010 if( prefix != NULL && prefix->bv_len > 0 ) {
1011 lutil_MD5Update( &MD5context,
1012 prefix->bv_val, prefix->bv_len );
1014 lutil_MD5Update( &MD5context,
1015 &pre, sizeof( pre ) );
1016 lutil_MD5Update( &MD5context,
1017 syntax->ssyn_oid, slen );
1018 lutil_MD5Update( &MD5context,
1019 mr->smr_oid, mlen );
1020 lutil_MD5Update( &MD5context,
1021 &value->bv_val[value->bv_len-j], j );
1022 lutil_MD5Final( MD5digest, &MD5context );
1024 keys[nkeys++] = ber_bvdup( &digest );
1038 return LDAP_SUCCESS;
1041 int caseExactSubstringsFilter(
1046 struct berval *prefix,
1048 struct berval ***keysp )
1050 SubstringsAssertion *sa = assertValue;
1052 ber_len_t nkeys = 0;
1053 size_t slen, mlen, klen;
1054 struct berval **keys;
1055 lutil_MD5_CTX MD5context;
1056 unsigned char MD5digest[LUTIL_MD5_BYTES];
1057 struct berval *value;
1058 struct berval digest;
1060 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1061 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1066 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1068 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1069 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1070 /* don't bother accounting for stepping */
1071 nkeys += sa->sa_any[i]->bv_len -
1072 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1077 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1078 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1085 return LDAP_SUCCESS;
1088 digest.bv_val = MD5digest;
1089 digest.bv_len = sizeof(MD5digest);
1091 slen = strlen( syntax->ssyn_oid );
1092 mlen = strlen( mr->smr_oid );
1094 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1097 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1098 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1100 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1101 value = sa->sa_initial;
1103 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1104 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1106 lutil_MD5Init( &MD5context );
1107 if( prefix != NULL && prefix->bv_len > 0 ) {
1108 lutil_MD5Update( &MD5context,
1109 prefix->bv_val, prefix->bv_len );
1111 lutil_MD5Update( &MD5context,
1112 &pre, sizeof( pre ) );
1113 lutil_MD5Update( &MD5context,
1114 syntax->ssyn_oid, slen );
1115 lutil_MD5Update( &MD5context,
1116 mr->smr_oid, mlen );
1117 lutil_MD5Update( &MD5context,
1118 value->bv_val, klen );
1119 lutil_MD5Final( MD5digest, &MD5context );
1121 keys[nkeys++] = ber_bvdup( &digest );
1124 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1126 pre = SLAP_INDEX_SUBSTR_PREFIX;
1127 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1129 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1130 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1134 value = sa->sa_any[i];
1137 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1138 j += SLAP_INDEX_SUBSTR_STEP )
1140 lutil_MD5Init( &MD5context );
1141 if( prefix != NULL && prefix->bv_len > 0 ) {
1142 lutil_MD5Update( &MD5context,
1143 prefix->bv_val, prefix->bv_len );
1145 lutil_MD5Update( &MD5context,
1146 &pre, sizeof( pre ) );
1147 lutil_MD5Update( &MD5context,
1148 syntax->ssyn_oid, slen );
1149 lutil_MD5Update( &MD5context,
1150 mr->smr_oid, mlen );
1151 lutil_MD5Update( &MD5context,
1152 &value->bv_val[j], klen );
1153 lutil_MD5Final( MD5digest, &MD5context );
1155 keys[nkeys++] = ber_bvdup( &digest );
1160 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1161 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1163 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1164 value = sa->sa_final;
1166 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1167 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1169 lutil_MD5Init( &MD5context );
1170 if( prefix != NULL && prefix->bv_len > 0 ) {
1171 lutil_MD5Update( &MD5context,
1172 prefix->bv_val, prefix->bv_len );
1174 lutil_MD5Update( &MD5context,
1175 &pre, sizeof( pre ) );
1176 lutil_MD5Update( &MD5context,
1177 syntax->ssyn_oid, slen );
1178 lutil_MD5Update( &MD5context,
1179 mr->smr_oid, mlen );
1180 lutil_MD5Update( &MD5context,
1181 &value->bv_val[value->bv_len-klen], klen );
1182 lutil_MD5Final( MD5digest, &MD5context );
1184 keys[nkeys++] = ber_bvdup( &digest );
1195 return LDAP_SUCCESS;
1204 struct berval *value,
1205 void *assertedValue )
1208 *matchp = UTF8casecmp( value, (struct berval *) assertedValue );
1210 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
1213 match = strncasecmp( value->bv_val,
1214 ((struct berval *) assertedValue)->bv_val,
1220 return LDAP_SUCCESS;
1224 caseIgnoreSubstringsMatch(
1229 struct berval *value,
1230 void *assertedValue )
1233 SubstringsAssertion *sub = assertedValue;
1234 struct berval left = *value;
1238 /* Add up asserted input length */
1239 if( sub->sa_initial ) {
1240 inlen += sub->sa_initial->bv_len;
1243 for(i=0; sub->sa_any[i] != NULL; i++) {
1244 inlen += sub->sa_any[i]->bv_len;
1247 if( sub->sa_final ) {
1248 inlen += sub->sa_final->bv_len;
1251 if( sub->sa_initial ) {
1252 if( inlen > left.bv_len ) {
1257 match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
1258 sub->sa_initial->bv_len );
1264 left.bv_val += sub->sa_initial->bv_len;
1265 left.bv_len -= sub->sa_initial->bv_len;
1266 inlen -= sub->sa_initial->bv_len;
1269 if( sub->sa_final ) {
1270 if( inlen > left.bv_len ) {
1275 match = strncasecmp( sub->sa_final->bv_val,
1276 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
1277 sub->sa_final->bv_len );
1283 left.bv_len -= sub->sa_final->bv_len;
1284 inlen -= sub->sa_final->bv_len;
1288 for(i=0; sub->sa_any[i]; i++) {
1293 if( inlen > left.bv_len ) {
1294 /* not enough length */
1299 if( sub->sa_any[i]->bv_len == 0 ) {
1303 p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
1310 idx = p - left.bv_val;
1311 assert( idx < left.bv_len );
1313 if( idx >= left.bv_len ) {
1314 /* this shouldn't happen */
1321 if( sub->sa_any[i]->bv_len > left.bv_len ) {
1322 /* not enough left */
1327 match = strncasecmp( left.bv_val,
1328 sub->sa_any[i]->bv_val,
1329 sub->sa_any[i]->bv_len );
1338 left.bv_val += sub->sa_any[i]->bv_len;
1339 left.bv_len -= sub->sa_any[i]->bv_len;
1340 inlen -= sub->sa_any[i]->bv_len;
1346 return LDAP_SUCCESS;
1349 /* Index generation function */
1350 int caseIgnoreIndexer(
1355 struct berval *prefix,
1356 struct berval **values,
1357 struct berval ***keysp )
1361 struct berval **keys;
1362 lutil_MD5_CTX MD5context;
1363 unsigned char MD5digest[16];
1364 struct berval digest;
1365 digest.bv_val = MD5digest;
1366 digest.bv_len = sizeof(MD5digest);
1368 /* we should have at least one value at this point */
1369 assert( values != NULL && values[0] != NULL );
1371 for( i=0; values[i] != NULL; i++ ) {
1372 /* just count them */
1375 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
1377 slen = strlen( syntax->ssyn_oid );
1378 mlen = strlen( mr->smr_oid );
1380 for( i=0; values[i] != NULL; i++ ) {
1381 struct berval *value = ber_bvdup( values[i] );
1382 ldap_pvt_str2upper( value->bv_val );
1384 lutil_MD5Init( &MD5context );
1385 if( prefix != NULL && prefix->bv_len > 0 ) {
1386 lutil_MD5Update( &MD5context,
1387 prefix->bv_val, prefix->bv_len );
1389 lutil_MD5Update( &MD5context,
1390 syntax->ssyn_oid, slen );
1391 lutil_MD5Update( &MD5context,
1392 mr->smr_oid, mlen );
1393 lutil_MD5Update( &MD5context,
1394 value->bv_val, value->bv_len );
1395 lutil_MD5Final( MD5digest, &MD5context );
1397 ber_bvfree( value );
1399 keys[i] = ber_bvdup( &digest );
1404 return LDAP_SUCCESS;
1407 /* Index generation function */
1408 int caseIgnoreFilter(
1413 struct berval *prefix,
1415 struct berval ***keysp )
1418 struct berval **keys;
1419 lutil_MD5_CTX MD5context;
1420 unsigned char MD5digest[LUTIL_MD5_BYTES];
1421 struct berval *value;
1422 struct berval digest;
1423 digest.bv_val = MD5digest;
1424 digest.bv_len = sizeof(MD5digest);
1426 slen = strlen( syntax->ssyn_oid );
1427 mlen = strlen( mr->smr_oid );
1429 value = ber_bvdup( (struct berval *) assertValue );
1430 ldap_pvt_str2upper( value->bv_val );
1432 keys = ch_malloc( sizeof( struct berval * ) * 2 );
1434 lutil_MD5Init( &MD5context );
1435 if( prefix != NULL && prefix->bv_len > 0 ) {
1436 lutil_MD5Update( &MD5context,
1437 prefix->bv_val, prefix->bv_len );
1439 lutil_MD5Update( &MD5context,
1440 syntax->ssyn_oid, slen );
1441 lutil_MD5Update( &MD5context,
1442 mr->smr_oid, mlen );
1443 lutil_MD5Update( &MD5context,
1444 value->bv_val, value->bv_len );
1445 lutil_MD5Final( MD5digest, &MD5context );
1447 keys[0] = ber_bvdup( &digest );
1450 ber_bvfree( value );
1454 return LDAP_SUCCESS;
1457 /* Substrings Index generation function */
1458 int caseIgnoreSubstringsIndexer(
1463 struct berval *prefix,
1464 struct berval **values,
1465 struct berval ***keysp )
1469 struct berval **keys;
1470 lutil_MD5_CTX MD5context;
1471 unsigned char MD5digest[16];
1472 struct berval digest;
1473 digest.bv_val = MD5digest;
1474 digest.bv_len = sizeof(MD5digest);
1476 /* we should have at least one value at this point */
1477 assert( values != NULL && values[0] != NULL );
1480 for( i=0; values[i] != NULL; i++ ) {
1481 /* count number of indices to generate */
1482 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1486 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1487 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1488 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1489 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1491 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1495 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1496 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1497 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1501 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1502 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1503 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1504 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1506 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1512 /* no keys to generate */
1514 return LDAP_SUCCESS;
1517 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1519 slen = strlen( syntax->ssyn_oid );
1520 mlen = strlen( mr->smr_oid );
1523 for( i=0; values[i] != NULL; i++ ) {
1525 struct berval *value;
1527 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1529 value = ber_bvdup( values[i] );
1530 ldap_pvt_str2upper( value->bv_val );
1532 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1533 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1535 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1536 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1538 for( j=0; j<max; j++ ) {
1539 lutil_MD5Init( &MD5context );
1540 if( prefix != NULL && prefix->bv_len > 0 ) {
1541 lutil_MD5Update( &MD5context,
1542 prefix->bv_val, prefix->bv_len );
1545 lutil_MD5Update( &MD5context,
1546 &pre, sizeof( pre ) );
1547 lutil_MD5Update( &MD5context,
1548 syntax->ssyn_oid, slen );
1549 lutil_MD5Update( &MD5context,
1550 mr->smr_oid, mlen );
1551 lutil_MD5Update( &MD5context,
1553 SLAP_INDEX_SUBSTR_MAXLEN );
1554 lutil_MD5Final( MD5digest, &MD5context );
1556 keys[nkeys++] = ber_bvdup( &digest );
1560 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1561 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1563 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1566 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1567 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1568 lutil_MD5Init( &MD5context );
1569 if( prefix != NULL && prefix->bv_len > 0 ) {
1570 lutil_MD5Update( &MD5context,
1571 prefix->bv_val, prefix->bv_len );
1573 lutil_MD5Update( &MD5context,
1574 &pre, sizeof( pre ) );
1575 lutil_MD5Update( &MD5context,
1576 syntax->ssyn_oid, slen );
1577 lutil_MD5Update( &MD5context,
1578 mr->smr_oid, mlen );
1579 lutil_MD5Update( &MD5context,
1581 lutil_MD5Final( MD5digest, &MD5context );
1583 keys[nkeys++] = ber_bvdup( &digest );
1586 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1587 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1588 lutil_MD5Init( &MD5context );
1589 if( prefix != NULL && prefix->bv_len > 0 ) {
1590 lutil_MD5Update( &MD5context,
1591 prefix->bv_val, prefix->bv_len );
1593 lutil_MD5Update( &MD5context,
1594 &pre, sizeof( pre ) );
1595 lutil_MD5Update( &MD5context,
1596 syntax->ssyn_oid, slen );
1597 lutil_MD5Update( &MD5context,
1598 mr->smr_oid, mlen );
1599 lutil_MD5Update( &MD5context,
1600 &value->bv_val[value->bv_len-j], j );
1601 lutil_MD5Final( MD5digest, &MD5context );
1603 keys[nkeys++] = ber_bvdup( &digest );
1608 ber_bvfree( value );
1619 return LDAP_SUCCESS;
1622 int caseIgnoreSubstringsFilter(
1627 struct berval *prefix,
1629 struct berval ***keysp )
1631 SubstringsAssertion *sa = assertValue;
1633 ber_len_t nkeys = 0;
1634 size_t slen, mlen, klen;
1635 struct berval **keys;
1636 lutil_MD5_CTX MD5context;
1637 unsigned char MD5digest[LUTIL_MD5_BYTES];
1638 struct berval *value;
1639 struct berval digest;
1641 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
1642 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1647 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
1649 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1650 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1651 /* don't bother accounting for stepping */
1652 nkeys += sa->sa_any[i]->bv_len -
1653 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1658 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
1659 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1666 return LDAP_SUCCESS;
1669 digest.bv_val = MD5digest;
1670 digest.bv_len = sizeof(MD5digest);
1672 slen = strlen( syntax->ssyn_oid );
1673 mlen = strlen( mr->smr_oid );
1675 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1678 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
1679 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1681 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1682 value = ber_bvdup( sa->sa_initial );
1683 ldap_pvt_str2upper( value->bv_val );
1685 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1686 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1688 lutil_MD5Init( &MD5context );
1689 if( prefix != NULL && prefix->bv_len > 0 ) {
1690 lutil_MD5Update( &MD5context,
1691 prefix->bv_val, prefix->bv_len );
1693 lutil_MD5Update( &MD5context,
1694 &pre, sizeof( pre ) );
1695 lutil_MD5Update( &MD5context,
1696 syntax->ssyn_oid, slen );
1697 lutil_MD5Update( &MD5context,
1698 mr->smr_oid, mlen );
1699 lutil_MD5Update( &MD5context,
1700 value->bv_val, klen );
1701 lutil_MD5Final( MD5digest, &MD5context );
1703 ber_bvfree( value );
1704 keys[nkeys++] = ber_bvdup( &digest );
1707 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
1709 pre = SLAP_INDEX_SUBSTR_PREFIX;
1710 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1712 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1713 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1717 value = ber_bvdup( sa->sa_any[i] );
1718 ldap_pvt_str2upper( value->bv_val );
1721 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1722 j += SLAP_INDEX_SUBSTR_STEP )
1724 lutil_MD5Init( &MD5context );
1725 if( prefix != NULL && prefix->bv_len > 0 ) {
1726 lutil_MD5Update( &MD5context,
1727 prefix->bv_val, prefix->bv_len );
1729 lutil_MD5Update( &MD5context,
1730 &pre, sizeof( pre ) );
1731 lutil_MD5Update( &MD5context,
1732 syntax->ssyn_oid, slen );
1733 lutil_MD5Update( &MD5context,
1734 mr->smr_oid, mlen );
1735 lutil_MD5Update( &MD5context,
1736 &value->bv_val[j], klen );
1737 lutil_MD5Final( MD5digest, &MD5context );
1739 keys[nkeys++] = ber_bvdup( &digest );
1742 ber_bvfree( value );
1746 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
1747 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1749 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1750 value = ber_bvdup( sa->sa_final );
1751 ldap_pvt_str2upper( value->bv_val );
1753 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1754 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1756 lutil_MD5Init( &MD5context );
1757 if( prefix != NULL && prefix->bv_len > 0 ) {
1758 lutil_MD5Update( &MD5context,
1759 prefix->bv_val, prefix->bv_len );
1761 lutil_MD5Update( &MD5context,
1762 &pre, sizeof( pre ) );
1763 lutil_MD5Update( &MD5context,
1764 syntax->ssyn_oid, slen );
1765 lutil_MD5Update( &MD5context,
1766 mr->smr_oid, mlen );
1767 lutil_MD5Update( &MD5context,
1768 &value->bv_val[value->bv_len-klen], klen );
1769 lutil_MD5Final( MD5digest, &MD5context );
1771 ber_bvfree( value );
1772 keys[nkeys++] = ber_bvdup( &digest );
1783 return LDAP_SUCCESS;
1789 struct berval *val )
1793 if( val->bv_len == 0 ) {
1794 /* disallow empty strings */
1795 return LDAP_INVALID_SYNTAX;
1798 if( OID_LEADCHAR(val->bv_val[0]) ) {
1800 for(i=1; i < val->bv_len; i++) {
1801 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1802 if( dot++ ) return 1;
1803 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1806 return LDAP_INVALID_SYNTAX;
1810 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1812 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1813 for(i=1; i < val->bv_len; i++) {
1814 if( !DESC_CHAR(val->bv_val[i] ) ) {
1815 return LDAP_INVALID_SYNTAX;
1819 return LDAP_SUCCESS;
1822 return LDAP_INVALID_SYNTAX;
1828 struct berval *val )
1832 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1834 if( val->bv_val[0] == '+' || val->bv_val[0] == '-' ) {
1835 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
1836 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
1837 return LDAP_INVALID_SYNTAX;
1840 for(i=1; i < val->bv_len; i++) {
1841 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1844 return LDAP_SUCCESS;
1851 struct berval **normalized )
1854 struct berval *newval;
1860 negative = ( *p == '-' );
1861 if( *p == '-' || *p == '+' ) p++;
1863 /* Ignore leading zeros */
1864 while ( *p == '0' ) p++;
1866 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
1869 newval->bv_val = ch_strdup("0");
1874 newval->bv_val = ch_malloc( val->bv_len + 1 );
1878 newval->bv_val[newval->bv_len++] = '-';
1881 for( ; *p != '\0'; p++ ) {
1882 newval->bv_val[newval->bv_len++] = *p;
1885 newval->bv_val[newval->bv_len] = '\0';
1888 *normalized = newval;
1889 return LDAP_SUCCESS;
1893 countryStringValidate(
1895 struct berval *val )
1897 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
1899 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
1900 return LDAP_INVALID_SYNTAX;
1902 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
1903 return LDAP_INVALID_SYNTAX;
1906 return LDAP_SUCCESS;
1910 printableStringValidate(
1912 struct berval *val )
1916 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1918 for(i=0; i < val->bv_len; i++) {
1919 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
1920 return LDAP_INVALID_SYNTAX;
1924 return LDAP_SUCCESS;
1928 printablesStringValidate(
1930 struct berval *val )
1934 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1936 for(i=0; i < val->bv_len; i++) {
1937 if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
1938 return LDAP_INVALID_SYNTAX;
1942 return LDAP_SUCCESS;
1948 struct berval *val )
1952 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
1954 for(i=0; i < val->bv_len; i++) {
1955 if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
1958 return LDAP_SUCCESS;
1965 struct berval **normalized )
1967 struct berval *newval;
1970 newval = ch_malloc( sizeof( struct berval ) );
1974 /* Ignore initial whitespace */
1975 while ( ASCII_SPACE( *p ) ) {
1981 return LDAP_INVALID_SYNTAX;
1984 newval->bv_val = ch_strdup( p );
1985 p = q = newval->bv_val;
1988 if ( ASCII_SPACE( *p ) ) {
1991 /* Ignore the extra whitespace */
1992 while ( ASCII_SPACE( *p ) ) {
2000 assert( *newval->bv_val );
2001 assert( newval->bv_val < p );
2004 /* cannot start with a space */
2005 assert( !ASCII_SPACE(*newval->bv_val) );
2008 * If the string ended in space, backup the pointer one
2009 * position. One is enough because the above loop collapsed
2010 * all whitespace to a single space.
2013 if ( ASCII_SPACE( q[-1] ) ) {
2017 /* cannot end with a space */
2018 assert( !ASCII_SPACE( q[-1] ) );
2020 /* null terminate */
2023 newval->bv_len = q - newval->bv_val;
2024 *normalized = newval;
2026 return LDAP_SUCCESS;
2035 struct berval *value,
2036 void *assertedValue )
2038 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2041 match = strncmp( value->bv_val,
2042 ((struct berval *) assertedValue)->bv_val,
2047 return LDAP_SUCCESS;
2051 caseExactIA5SubstringsMatch(
2056 struct berval *value,
2057 void *assertedValue )
2060 SubstringsAssertion *sub = assertedValue;
2061 struct berval left = *value;
2065 /* Add up asserted input length */
2066 if( sub->sa_initial ) {
2067 inlen += sub->sa_initial->bv_len;
2070 for(i=0; sub->sa_any[i] != NULL; i++) {
2071 inlen += sub->sa_any[i]->bv_len;
2074 if( sub->sa_final ) {
2075 inlen += sub->sa_final->bv_len;
2078 if( sub->sa_initial ) {
2079 if( inlen > left.bv_len ) {
2084 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
2085 sub->sa_initial->bv_len );
2091 left.bv_val += sub->sa_initial->bv_len;
2092 left.bv_len -= sub->sa_initial->bv_len;
2093 inlen -= sub->sa_initial->bv_len;
2096 if( sub->sa_final ) {
2097 if( inlen > left.bv_len ) {
2102 match = strncmp( sub->sa_final->bv_val,
2103 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2104 sub->sa_final->bv_len );
2110 left.bv_len -= sub->sa_final->bv_len;
2111 inlen -= sub->sa_final->bv_len;
2115 for(i=0; sub->sa_any[i]; i++) {
2120 if( inlen > left.bv_len ) {
2121 /* not enough length */
2126 if( sub->sa_any[i]->bv_len == 0 ) {
2130 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
2137 idx = p - left.bv_val;
2138 assert( idx < left.bv_len );
2140 if( idx >= left.bv_len ) {
2141 /* this shouldn't happen */
2148 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2149 /* not enough left */
2154 match = strncmp( left.bv_val,
2155 sub->sa_any[i]->bv_val,
2156 sub->sa_any[i]->bv_len );
2164 left.bv_val += sub->sa_any[i]->bv_len;
2165 left.bv_len -= sub->sa_any[i]->bv_len;
2166 inlen -= sub->sa_any[i]->bv_len;
2172 return LDAP_SUCCESS;
2175 /* Index generation function */
2176 int caseExactIA5Indexer(
2181 struct berval *prefix,
2182 struct berval **values,
2183 struct berval ***keysp )
2187 struct berval **keys;
2188 lutil_MD5_CTX MD5context;
2189 unsigned char MD5digest[16];
2190 struct berval digest;
2191 digest.bv_val = MD5digest;
2192 digest.bv_len = sizeof(MD5digest);
2194 /* we should have at least one value at this point */
2195 assert( values != NULL && values[0] != NULL );
2197 for( i=0; values[i] != NULL; i++ ) {
2198 /* just count them */
2201 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2203 slen = strlen( syntax->ssyn_oid );
2204 mlen = strlen( mr->smr_oid );
2206 for( i=0; values[i] != NULL; i++ ) {
2207 struct berval *value = values[i];
2209 lutil_MD5Init( &MD5context );
2210 if( prefix != NULL && prefix->bv_len > 0 ) {
2211 lutil_MD5Update( &MD5context,
2212 prefix->bv_val, prefix->bv_len );
2214 lutil_MD5Update( &MD5context,
2215 syntax->ssyn_oid, slen );
2216 lutil_MD5Update( &MD5context,
2217 mr->smr_oid, mlen );
2218 lutil_MD5Update( &MD5context,
2219 value->bv_val, value->bv_len );
2220 lutil_MD5Final( MD5digest, &MD5context );
2222 keys[i] = ber_bvdup( &digest );
2227 return LDAP_SUCCESS;
2230 /* Index generation function */
2231 int caseExactIA5Filter(
2236 struct berval *prefix,
2238 struct berval ***keysp )
2241 struct berval **keys;
2242 lutil_MD5_CTX MD5context;
2243 unsigned char MD5digest[LUTIL_MD5_BYTES];
2244 struct berval *value;
2245 struct berval digest;
2246 digest.bv_val = MD5digest;
2247 digest.bv_len = sizeof(MD5digest);
2249 slen = strlen( syntax->ssyn_oid );
2250 mlen = strlen( mr->smr_oid );
2252 value = (struct berval *) assertValue;
2254 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2256 lutil_MD5Init( &MD5context );
2257 if( prefix != NULL && prefix->bv_len > 0 ) {
2258 lutil_MD5Update( &MD5context,
2259 prefix->bv_val, prefix->bv_len );
2261 lutil_MD5Update( &MD5context,
2262 syntax->ssyn_oid, slen );
2263 lutil_MD5Update( &MD5context,
2264 mr->smr_oid, mlen );
2265 lutil_MD5Update( &MD5context,
2266 value->bv_val, value->bv_len );
2267 lutil_MD5Final( MD5digest, &MD5context );
2269 keys[0] = ber_bvdup( &digest );
2273 return LDAP_SUCCESS;
2276 /* Substrings Index generation function */
2277 int caseExactIA5SubstringsIndexer(
2282 struct berval *prefix,
2283 struct berval **values,
2284 struct berval ***keysp )
2288 struct berval **keys;
2289 lutil_MD5_CTX MD5context;
2290 unsigned char MD5digest[16];
2291 struct berval digest;
2292 digest.bv_val = MD5digest;
2293 digest.bv_len = sizeof(MD5digest);
2295 /* we should have at least one value at this point */
2296 assert( values != NULL && values[0] != NULL );
2299 for( i=0; values[i] != NULL; i++ ) {
2300 /* count number of indices to generate */
2301 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2305 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2306 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2307 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2308 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2310 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2314 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2315 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2316 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2320 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2321 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2322 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2323 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2325 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2331 /* no keys to generate */
2333 return LDAP_SUCCESS;
2336 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2338 slen = strlen( syntax->ssyn_oid );
2339 mlen = strlen( mr->smr_oid );
2342 for( i=0; values[i] != NULL; i++ ) {
2344 struct berval *value;
2347 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2349 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2350 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2352 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2353 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2355 for( j=0; j<max; j++ ) {
2356 lutil_MD5Init( &MD5context );
2357 if( prefix != NULL && prefix->bv_len > 0 ) {
2358 lutil_MD5Update( &MD5context,
2359 prefix->bv_val, prefix->bv_len );
2362 lutil_MD5Update( &MD5context,
2363 &pre, sizeof( pre ) );
2364 lutil_MD5Update( &MD5context,
2365 syntax->ssyn_oid, slen );
2366 lutil_MD5Update( &MD5context,
2367 mr->smr_oid, mlen );
2368 lutil_MD5Update( &MD5context,
2370 SLAP_INDEX_SUBSTR_MAXLEN );
2371 lutil_MD5Final( MD5digest, &MD5context );
2373 keys[nkeys++] = ber_bvdup( &digest );
2377 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2378 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2380 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2383 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2384 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2385 lutil_MD5Init( &MD5context );
2386 if( prefix != NULL && prefix->bv_len > 0 ) {
2387 lutil_MD5Update( &MD5context,
2388 prefix->bv_val, prefix->bv_len );
2390 lutil_MD5Update( &MD5context,
2391 &pre, sizeof( pre ) );
2392 lutil_MD5Update( &MD5context,
2393 syntax->ssyn_oid, slen );
2394 lutil_MD5Update( &MD5context,
2395 mr->smr_oid, mlen );
2396 lutil_MD5Update( &MD5context,
2398 lutil_MD5Final( MD5digest, &MD5context );
2400 keys[nkeys++] = ber_bvdup( &digest );
2403 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2404 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2405 lutil_MD5Init( &MD5context );
2406 if( prefix != NULL && prefix->bv_len > 0 ) {
2407 lutil_MD5Update( &MD5context,
2408 prefix->bv_val, prefix->bv_len );
2410 lutil_MD5Update( &MD5context,
2411 &pre, sizeof( pre ) );
2412 lutil_MD5Update( &MD5context,
2413 syntax->ssyn_oid, slen );
2414 lutil_MD5Update( &MD5context,
2415 mr->smr_oid, mlen );
2416 lutil_MD5Update( &MD5context,
2417 &value->bv_val[value->bv_len-j], j );
2418 lutil_MD5Final( MD5digest, &MD5context );
2420 keys[nkeys++] = ber_bvdup( &digest );
2434 return LDAP_SUCCESS;
2437 int caseExactIA5SubstringsFilter(
2442 struct berval *prefix,
2444 struct berval ***keysp )
2446 SubstringsAssertion *sa = assertValue;
2448 ber_len_t nkeys = 0;
2449 size_t slen, mlen, klen;
2450 struct berval **keys;
2451 lutil_MD5_CTX MD5context;
2452 unsigned char MD5digest[LUTIL_MD5_BYTES];
2453 struct berval *value;
2454 struct berval digest;
2456 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2457 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2462 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2464 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2465 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2466 /* don't bother accounting for stepping */
2467 nkeys += sa->sa_any[i]->bv_len -
2468 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2473 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2474 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2481 return LDAP_SUCCESS;
2484 digest.bv_val = MD5digest;
2485 digest.bv_len = sizeof(MD5digest);
2487 slen = strlen( syntax->ssyn_oid );
2488 mlen = strlen( mr->smr_oid );
2490 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2493 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2494 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2496 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2497 value = sa->sa_initial;
2499 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2500 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2502 lutil_MD5Init( &MD5context );
2503 if( prefix != NULL && prefix->bv_len > 0 ) {
2504 lutil_MD5Update( &MD5context,
2505 prefix->bv_val, prefix->bv_len );
2507 lutil_MD5Update( &MD5context,
2508 &pre, sizeof( pre ) );
2509 lutil_MD5Update( &MD5context,
2510 syntax->ssyn_oid, slen );
2511 lutil_MD5Update( &MD5context,
2512 mr->smr_oid, mlen );
2513 lutil_MD5Update( &MD5context,
2514 value->bv_val, klen );
2515 lutil_MD5Final( MD5digest, &MD5context );
2517 keys[nkeys++] = ber_bvdup( &digest );
2520 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2522 pre = SLAP_INDEX_SUBSTR_PREFIX;
2523 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2525 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2526 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2530 value = sa->sa_any[i];
2533 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2534 j += SLAP_INDEX_SUBSTR_STEP )
2536 lutil_MD5Init( &MD5context );
2537 if( prefix != NULL && prefix->bv_len > 0 ) {
2538 lutil_MD5Update( &MD5context,
2539 prefix->bv_val, prefix->bv_len );
2541 lutil_MD5Update( &MD5context,
2542 &pre, sizeof( pre ) );
2543 lutil_MD5Update( &MD5context,
2544 syntax->ssyn_oid, slen );
2545 lutil_MD5Update( &MD5context,
2546 mr->smr_oid, mlen );
2547 lutil_MD5Update( &MD5context,
2548 &value->bv_val[j], klen );
2549 lutil_MD5Final( MD5digest, &MD5context );
2551 keys[nkeys++] = ber_bvdup( &digest );
2556 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2557 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2559 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2560 value = sa->sa_final;
2562 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2563 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2565 lutil_MD5Init( &MD5context );
2566 if( prefix != NULL && prefix->bv_len > 0 ) {
2567 lutil_MD5Update( &MD5context,
2568 prefix->bv_val, prefix->bv_len );
2570 lutil_MD5Update( &MD5context,
2571 &pre, sizeof( pre ) );
2572 lutil_MD5Update( &MD5context,
2573 syntax->ssyn_oid, slen );
2574 lutil_MD5Update( &MD5context,
2575 mr->smr_oid, mlen );
2576 lutil_MD5Update( &MD5context,
2577 &value->bv_val[value->bv_len-klen], klen );
2578 lutil_MD5Final( MD5digest, &MD5context );
2580 keys[nkeys++] = ber_bvdup( &digest );
2591 return LDAP_SUCCESS;
2600 struct berval *value,
2601 void *assertedValue )
2603 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2605 if( match == 0 && value->bv_len ) {
2606 match = strncasecmp( value->bv_val,
2607 ((struct berval *) assertedValue)->bv_val,
2612 return LDAP_SUCCESS;
2616 caseIgnoreIA5SubstringsMatch(
2621 struct berval *value,
2622 void *assertedValue )
2625 SubstringsAssertion *sub = assertedValue;
2626 struct berval left = *value;
2630 /* Add up asserted input length */
2631 if( sub->sa_initial ) {
2632 inlen += sub->sa_initial->bv_len;
2635 for(i=0; sub->sa_any[i] != NULL; i++) {
2636 inlen += sub->sa_any[i]->bv_len;
2639 if( sub->sa_final ) {
2640 inlen += sub->sa_final->bv_len;
2643 if( sub->sa_initial ) {
2644 if( inlen > left.bv_len ) {
2649 match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
2650 sub->sa_initial->bv_len );
2656 left.bv_val += sub->sa_initial->bv_len;
2657 left.bv_len -= sub->sa_initial->bv_len;
2658 inlen -= sub->sa_initial->bv_len;
2661 if( sub->sa_final ) {
2662 if( inlen > left.bv_len ) {
2667 match = strncasecmp( sub->sa_final->bv_val,
2668 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2669 sub->sa_final->bv_len );
2675 left.bv_len -= sub->sa_final->bv_len;
2676 inlen -= sub->sa_final->bv_len;
2680 for(i=0; sub->sa_any[i]; i++) {
2685 if( inlen > left.bv_len ) {
2686 /* not enough length */
2691 if( sub->sa_any[i]->bv_len == 0 ) {
2695 p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
2702 idx = p - left.bv_val;
2703 assert( idx < left.bv_len );
2705 if( idx >= left.bv_len ) {
2706 /* this shouldn't happen */
2713 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2714 /* not enough left */
2719 match = strncasecmp( left.bv_val,
2720 sub->sa_any[i]->bv_val,
2721 sub->sa_any[i]->bv_len );
2730 left.bv_val += sub->sa_any[i]->bv_len;
2731 left.bv_len -= sub->sa_any[i]->bv_len;
2732 inlen -= sub->sa_any[i]->bv_len;
2738 return LDAP_SUCCESS;
2741 /* Index generation function */
2742 int caseIgnoreIA5Indexer(
2747 struct berval *prefix,
2748 struct berval **values,
2749 struct berval ***keysp )
2753 struct berval **keys;
2754 lutil_MD5_CTX MD5context;
2755 unsigned char MD5digest[16];
2756 struct berval digest;
2757 digest.bv_val = MD5digest;
2758 digest.bv_len = sizeof(MD5digest);
2760 /* we should have at least one value at this point */
2761 assert( values != NULL && values[0] != NULL );
2763 for( i=0; values[i] != NULL; i++ ) {
2764 /* just count them */
2767 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2769 slen = strlen( syntax->ssyn_oid );
2770 mlen = strlen( mr->smr_oid );
2772 for( i=0; values[i] != NULL; i++ ) {
2773 struct berval *value = ber_bvdup( values[i] );
2774 ldap_pvt_str2upper( value->bv_val );
2776 lutil_MD5Init( &MD5context );
2777 if( prefix != NULL && prefix->bv_len > 0 ) {
2778 lutil_MD5Update( &MD5context,
2779 prefix->bv_val, prefix->bv_len );
2781 lutil_MD5Update( &MD5context,
2782 syntax->ssyn_oid, slen );
2783 lutil_MD5Update( &MD5context,
2784 mr->smr_oid, mlen );
2785 lutil_MD5Update( &MD5context,
2786 value->bv_val, value->bv_len );
2787 lutil_MD5Final( MD5digest, &MD5context );
2789 ber_bvfree( value );
2791 keys[i] = ber_bvdup( &digest );
2796 return LDAP_SUCCESS;
2799 /* Index generation function */
2800 int caseIgnoreIA5Filter(
2805 struct berval *prefix,
2807 struct berval ***keysp )
2810 struct berval **keys;
2811 lutil_MD5_CTX MD5context;
2812 unsigned char MD5digest[LUTIL_MD5_BYTES];
2813 struct berval *value;
2814 struct berval digest;
2815 digest.bv_val = MD5digest;
2816 digest.bv_len = sizeof(MD5digest);
2818 slen = strlen( syntax->ssyn_oid );
2819 mlen = strlen( mr->smr_oid );
2821 value = ber_bvdup( (struct berval *) assertValue );
2822 ldap_pvt_str2upper( value->bv_val );
2824 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2826 lutil_MD5Init( &MD5context );
2827 if( prefix != NULL && prefix->bv_len > 0 ) {
2828 lutil_MD5Update( &MD5context,
2829 prefix->bv_val, prefix->bv_len );
2831 lutil_MD5Update( &MD5context,
2832 syntax->ssyn_oid, slen );
2833 lutil_MD5Update( &MD5context,
2834 mr->smr_oid, mlen );
2835 lutil_MD5Update( &MD5context,
2836 value->bv_val, value->bv_len );
2837 lutil_MD5Final( MD5digest, &MD5context );
2839 keys[0] = ber_bvdup( &digest );
2842 ber_bvfree( value );
2846 return LDAP_SUCCESS;
2849 /* Substrings Index generation function */
2850 int caseIgnoreIA5SubstringsIndexer(
2855 struct berval *prefix,
2856 struct berval **values,
2857 struct berval ***keysp )
2861 struct berval **keys;
2862 lutil_MD5_CTX MD5context;
2863 unsigned char MD5digest[16];
2864 struct berval digest;
2865 digest.bv_val = MD5digest;
2866 digest.bv_len = sizeof(MD5digest);
2868 /* we should have at least one value at this point */
2869 assert( values != NULL && values[0] != NULL );
2872 for( i=0; values[i] != NULL; i++ ) {
2873 /* count number of indices to generate */
2874 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2878 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2879 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2880 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2881 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2883 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2887 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2888 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2889 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2893 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2894 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2895 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2896 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2898 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2904 /* no keys to generate */
2906 return LDAP_SUCCESS;
2909 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2911 slen = strlen( syntax->ssyn_oid );
2912 mlen = strlen( mr->smr_oid );
2915 for( i=0; values[i] != NULL; i++ ) {
2917 struct berval *value;
2919 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2921 value = ber_bvdup( values[i] );
2922 ldap_pvt_str2upper( value->bv_val );
2924 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2925 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2927 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2928 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2930 for( j=0; j<max; j++ ) {
2931 lutil_MD5Init( &MD5context );
2932 if( prefix != NULL && prefix->bv_len > 0 ) {
2933 lutil_MD5Update( &MD5context,
2934 prefix->bv_val, prefix->bv_len );
2937 lutil_MD5Update( &MD5context,
2938 &pre, sizeof( pre ) );
2939 lutil_MD5Update( &MD5context,
2940 syntax->ssyn_oid, slen );
2941 lutil_MD5Update( &MD5context,
2942 mr->smr_oid, mlen );
2943 lutil_MD5Update( &MD5context,
2945 SLAP_INDEX_SUBSTR_MAXLEN );
2946 lutil_MD5Final( MD5digest, &MD5context );
2948 keys[nkeys++] = ber_bvdup( &digest );
2952 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2953 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2955 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2958 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2959 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2960 lutil_MD5Init( &MD5context );
2961 if( prefix != NULL && prefix->bv_len > 0 ) {
2962 lutil_MD5Update( &MD5context,
2963 prefix->bv_val, prefix->bv_len );
2965 lutil_MD5Update( &MD5context,
2966 &pre, sizeof( pre ) );
2967 lutil_MD5Update( &MD5context,
2968 syntax->ssyn_oid, slen );
2969 lutil_MD5Update( &MD5context,
2970 mr->smr_oid, mlen );
2971 lutil_MD5Update( &MD5context,
2973 lutil_MD5Final( MD5digest, &MD5context );
2975 keys[nkeys++] = ber_bvdup( &digest );
2978 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2979 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2980 lutil_MD5Init( &MD5context );
2981 if( prefix != NULL && prefix->bv_len > 0 ) {
2982 lutil_MD5Update( &MD5context,
2983 prefix->bv_val, prefix->bv_len );
2985 lutil_MD5Update( &MD5context,
2986 &pre, sizeof( pre ) );
2987 lutil_MD5Update( &MD5context,
2988 syntax->ssyn_oid, slen );
2989 lutil_MD5Update( &MD5context,
2990 mr->smr_oid, mlen );
2991 lutil_MD5Update( &MD5context,
2992 &value->bv_val[value->bv_len-j], j );
2993 lutil_MD5Final( MD5digest, &MD5context );
2995 keys[nkeys++] = ber_bvdup( &digest );
3000 ber_bvfree( value );
3011 return LDAP_SUCCESS;
3014 int caseIgnoreIA5SubstringsFilter(
3019 struct berval *prefix,
3021 struct berval ***keysp )
3023 SubstringsAssertion *sa = assertValue;
3025 ber_len_t nkeys = 0;
3026 size_t slen, mlen, klen;
3027 struct berval **keys;
3028 lutil_MD5_CTX MD5context;
3029 unsigned char MD5digest[LUTIL_MD5_BYTES];
3030 struct berval *value;
3031 struct berval digest;
3033 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3034 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3039 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3041 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3042 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3043 /* don't bother accounting for stepping */
3044 nkeys += sa->sa_any[i]->bv_len -
3045 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3050 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3051 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3058 return LDAP_SUCCESS;
3061 digest.bv_val = MD5digest;
3062 digest.bv_len = sizeof(MD5digest);
3064 slen = strlen( syntax->ssyn_oid );
3065 mlen = strlen( mr->smr_oid );
3067 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
3070 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3071 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3073 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3074 value = ber_bvdup( sa->sa_initial );
3075 ldap_pvt_str2upper( value->bv_val );
3077 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3078 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3080 lutil_MD5Init( &MD5context );
3081 if( prefix != NULL && prefix->bv_len > 0 ) {
3082 lutil_MD5Update( &MD5context,
3083 prefix->bv_val, prefix->bv_len );
3085 lutil_MD5Update( &MD5context,
3086 &pre, sizeof( pre ) );
3087 lutil_MD5Update( &MD5context,
3088 syntax->ssyn_oid, slen );
3089 lutil_MD5Update( &MD5context,
3090 mr->smr_oid, mlen );
3091 lutil_MD5Update( &MD5context,
3092 value->bv_val, klen );
3093 lutil_MD5Final( MD5digest, &MD5context );
3095 ber_bvfree( value );
3096 keys[nkeys++] = ber_bvdup( &digest );
3099 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3101 pre = SLAP_INDEX_SUBSTR_PREFIX;
3102 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3104 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3105 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3109 value = ber_bvdup( sa->sa_any[i] );
3110 ldap_pvt_str2upper( value->bv_val );
3113 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3114 j += SLAP_INDEX_SUBSTR_STEP )
3116 lutil_MD5Init( &MD5context );
3117 if( prefix != NULL && prefix->bv_len > 0 ) {
3118 lutil_MD5Update( &MD5context,
3119 prefix->bv_val, prefix->bv_len );
3121 lutil_MD5Update( &MD5context,
3122 &pre, sizeof( pre ) );
3123 lutil_MD5Update( &MD5context,
3124 syntax->ssyn_oid, slen );
3125 lutil_MD5Update( &MD5context,
3126 mr->smr_oid, mlen );
3127 lutil_MD5Update( &MD5context,
3128 &value->bv_val[j], klen );
3129 lutil_MD5Final( MD5digest, &MD5context );
3131 keys[nkeys++] = ber_bvdup( &digest );
3134 ber_bvfree( value );
3138 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3139 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3141 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3142 value = ber_bvdup( sa->sa_final );
3143 ldap_pvt_str2upper( value->bv_val );
3145 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3146 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3148 lutil_MD5Init( &MD5context );
3149 if( prefix != NULL && prefix->bv_len > 0 ) {
3150 lutil_MD5Update( &MD5context,
3151 prefix->bv_val, prefix->bv_len );
3153 lutil_MD5Update( &MD5context,
3154 &pre, sizeof( pre ) );
3155 lutil_MD5Update( &MD5context,
3156 syntax->ssyn_oid, slen );
3157 lutil_MD5Update( &MD5context,
3158 mr->smr_oid, mlen );
3159 lutil_MD5Update( &MD5context,
3160 &value->bv_val[value->bv_len-klen], klen );
3161 lutil_MD5Final( MD5digest, &MD5context );
3163 ber_bvfree( value );
3164 keys[nkeys++] = ber_bvdup( &digest );
3175 return LDAP_SUCCESS;
3179 numericStringValidate(
3185 for(i=0; i < in->bv_len; i++) {
3186 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3187 return LDAP_INVALID_SYNTAX;
3191 return LDAP_SUCCESS;
3195 numericStringNormalize(
3198 struct berval **normalized )
3200 /* removal all spaces */
3201 struct berval *newval;
3204 newval = ch_malloc( sizeof( struct berval ) );
3205 newval->bv_val = ch_malloc( val->bv_len + 1 );
3211 if ( ASCII_SPACE( *p ) ) {
3212 /* Ignore whitespace */
3219 assert( newval->bv_val <= p );
3222 /* null terminate */
3225 newval->bv_len = q - newval->bv_val;
3226 *normalized = newval;
3228 return LDAP_SUCCESS;
3232 objectIdentifierFirstComponentMatch(
3237 struct berval *value,
3238 void *assertedValue )
3240 int rc = LDAP_SUCCESS;
3242 struct berval *asserted = (struct berval *) assertedValue;
3246 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3247 return LDAP_INVALID_SYNTAX;
3250 /* trim leading white space */
3251 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3255 /* grab next word */
3256 oid.bv_val = &value->bv_val[i];
3257 oid.bv_len = value->bv_len - i;
3258 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3263 /* insert attributeTypes, objectclass check here */
3264 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3265 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3268 char *stored = ch_malloc( oid.bv_len + 1 );
3269 AC_MEMCPY( stored, oid.bv_val, oid.bv_len );
3270 stored[oid.bv_len] = '\0';
3272 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3273 MatchingRule *asserted_mr = mr_find( asserted->bv_val );
3274 MatchingRule *stored_mr = mr_find( stored );
3276 if( asserted_mr == NULL ) {
3277 rc = SLAPD_COMPARE_UNDEFINED;
3279 match = asserted_mr != stored_mr;
3282 } else if ( !strcmp( syntax->ssyn_oid,
3283 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3285 AttributeType *asserted_at = at_find( asserted->bv_val );
3286 AttributeType *stored_at = at_find( stored );
3288 if( asserted_at == NULL ) {
3289 rc = SLAPD_COMPARE_UNDEFINED;
3291 match = asserted_at != stored_at;
3294 } else if ( !strcmp( syntax->ssyn_oid,
3295 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3297 ObjectClass *asserted_oc = oc_find( asserted->bv_val );
3298 ObjectClass *stored_oc = oc_find( stored );
3300 if( asserted_oc == NULL ) {
3301 rc = SLAPD_COMPARE_UNDEFINED;
3303 match = asserted_oc != stored_oc;
3310 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3311 "%d\n\t\"%s\"\n\t\"%s\"\n",
3312 match, value->bv_val, asserted->bv_val );
3314 if( rc == LDAP_SUCCESS ) *matchp = match;
3319 check_time_syntax (struct berval *val,
3323 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
3324 static int mdays[2][12] = {
3325 /* non-leap years */
3326 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
3328 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
3331 int part, c, tzoffset, leapyear = 0 ;
3333 if( val->bv_len == 0 ) {
3334 return LDAP_INVALID_SYNTAX;
3337 p = (char *)val->bv_val;
3338 e = p + val->bv_len;
3340 /* Ignore initial whitespace */
3341 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3345 if (e - p < 13 - (2 * start)) {
3346 return LDAP_INVALID_SYNTAX;
3349 for (part = 0; part < 9; part++) {
3353 for (part = start; part < 7; part++) {
3355 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
3362 return LDAP_INVALID_SYNTAX;
3364 if (c < 0 || c > 9) {
3365 return LDAP_INVALID_SYNTAX;
3371 return LDAP_INVALID_SYNTAX;
3373 if (c < 0 || c > 9) {
3374 return LDAP_INVALID_SYNTAX;
3379 if (part == 2 || part == 3) {
3382 if (parts[part] < 0) {
3383 return LDAP_INVALID_SYNTAX;
3385 if (parts[part] > ceiling[part]) {
3386 return LDAP_INVALID_SYNTAX;
3390 /* leapyear check for the Gregorian calendar (year>1581) */
3391 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
3392 ((parts[0] % 4 == 0) && (parts[1] == 0)))
3397 if (parts[3] > mdays[leapyear][parts[2]]) {
3398 return LDAP_INVALID_SYNTAX;
3403 tzoffset = 0; /* UTC */
3404 } else if (c != '+' && c != '-') {
3405 return LDAP_INVALID_SYNTAX;
3409 } else /* c == '+' */ {
3414 return LDAP_INVALID_SYNTAX;
3417 for (part = 7; part < 9; part++) {
3419 if (c < 0 || c > 9) {
3420 return LDAP_INVALID_SYNTAX;
3425 if (c < 0 || c > 9) {
3426 return LDAP_INVALID_SYNTAX;
3430 if (parts[part] < 0 || parts[part] > ceiling[part]) {
3431 return LDAP_INVALID_SYNTAX;
3436 /* Ignore trailing whitespace */
3437 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3441 return LDAP_INVALID_SYNTAX;
3444 switch ( tzoffset ) {
3445 case -1: /* negativ offset to UTC, ie west of Greenwich */
3446 parts[4] += parts[7];
3447 parts[5] += parts[8];
3448 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
3452 c = mdays[leapyear][parts[2]];
3454 if (parts[part] > c) {
3455 parts[part] -= c + 1;
3460 case 1: /* positive offset to UTC, ie east of Greenwich */
3461 parts[4] -= parts[7];
3462 parts[5] -= parts[8];
3463 for (part = 6; --part > 0; ) {
3467 /* first arg to % needs to be non negativ */
3468 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
3470 if (parts[part] < 0) {
3471 parts[part] += c + 1;
3476 case 0: /* already UTC */
3480 return LDAP_SUCCESS;
3487 struct berval **normalized )
3492 rc = check_time_syntax(val, 1, parts);
3493 if (rc != LDAP_SUCCESS) {
3498 out = ch_malloc( sizeof(struct berval) );
3500 return LBER_ERROR_MEMORY;
3503 out->bv_val = ch_malloc( 14 );
3504 if ( out->bv_val == NULL ) {
3506 return LBER_ERROR_MEMORY;
3509 sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ldZ",
3510 parts[1], parts[2] + 1, parts[3] + 1,
3511 parts[4], parts[5], parts[6] );
3515 return LDAP_SUCCESS;
3525 return check_time_syntax(in, 1, parts);
3529 generalizedTimeValidate(
3535 return check_time_syntax(in, 0, parts);
3539 generalizedTimeNormalize(
3542 struct berval **normalized )
3547 rc = check_time_syntax(val, 0, parts);
3548 if (rc != LDAP_SUCCESS) {
3553 out = ch_malloc( sizeof(struct berval) );
3555 return LBER_ERROR_MEMORY;
3558 out->bv_val = ch_malloc( 16 );
3559 if ( out->bv_val == NULL ) {
3561 return LBER_ERROR_MEMORY;
3564 sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ld%02ldZ",
3565 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
3566 parts[4], parts[5], parts[6] );
3570 return LDAP_SUCCESS;
3574 nisNetgroupTripleValidate(
3576 struct berval *val )
3581 if ( val->bv_len == 0 ) {
3582 return LDAP_INVALID_SYNTAX;
3585 p = (char *)val->bv_val;
3586 e = p + val->bv_len;
3589 /* syntax does not allow leading white space */
3590 /* Ignore initial whitespace */
3591 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3596 if ( *p != '(' /*')'*/ ) {
3597 return LDAP_INVALID_SYNTAX;
3600 for ( p++; ( p < e ) && ( *p != ')' ); p++ ) {
3604 return LDAP_INVALID_SYNTAX;
3607 } else if ( !ATTR_CHAR( *p ) ) {
3608 return LDAP_INVALID_SYNTAX;
3612 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
3613 return LDAP_INVALID_SYNTAX;
3619 /* syntax does not allow trailing white space */
3620 /* Ignore trailing whitespace */
3621 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
3627 return LDAP_INVALID_SYNTAX;
3630 return LDAP_SUCCESS;
3634 bootParameterValidate(
3636 struct berval *val )
3640 if ( val->bv_len == 0 ) {
3641 return LDAP_INVALID_SYNTAX;
3644 p = (char *)val->bv_val;
3645 e = p + val->bv_len;
3648 for (; ( p < e ) && ( *p != '=' ); p++ ) {
3649 if ( !ATTR_CHAR( *p ) ) {
3650 return LDAP_INVALID_SYNTAX;
3655 return LDAP_INVALID_SYNTAX;
3659 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
3660 if ( !ATTR_CHAR( *p ) ) {
3661 return LDAP_INVALID_SYNTAX;
3666 return LDAP_INVALID_SYNTAX;
3670 for ( p++; p < e; p++ ) {
3671 if ( !ATTR_CHAR( *p ) ) {
3672 return LDAP_INVALID_SYNTAX;
3676 return LDAP_SUCCESS;
3679 struct syntax_defs_rec {
3682 slap_syntax_validate_func *sd_validate;
3683 slap_syntax_transform_func *sd_normalize;
3684 slap_syntax_transform_func *sd_pretty;
3685 #ifdef SLAPD_BINARY_CONVERSION
3686 slap_syntax_transform_func *sd_ber2str;
3687 slap_syntax_transform_func *sd_str2ber;
3691 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
3692 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
3694 struct syntax_defs_rec syntax_defs[] = {
3695 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
3696 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
3697 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
3698 0, NULL, NULL, NULL},
3699 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
3700 0, NULL, NULL, NULL},
3701 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
3702 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
3703 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_NOT_H_R ")",
3704 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3705 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
3706 0, bitStringValidate, NULL, NULL },
3707 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
3708 0, booleanValidate, NULL, NULL},
3709 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
3710 X_BINARY X_NOT_H_R ")",
3711 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3712 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
3713 X_BINARY X_NOT_H_R ")",
3714 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3715 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
3716 X_BINARY X_NOT_H_R ")",
3717 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3718 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
3719 0, countryStringValidate, IA5StringNormalize, NULL},
3720 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
3721 0, dnValidate, dnNormalize, dnPretty},
3722 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
3723 0, NULL, NULL, NULL},
3724 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
3725 0, NULL, NULL, NULL},
3726 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
3727 0, UTF8StringValidate, UTF8StringNormalize, NULL},
3728 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
3729 0, NULL, NULL, NULL},
3730 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
3731 0, NULL, NULL, NULL},
3732 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
3733 0, NULL, NULL, NULL},
3734 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
3735 0, NULL, NULL, NULL},
3736 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
3737 0, NULL, NULL, NULL},
3738 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
3739 0, printablesStringValidate, IA5StringNormalize, NULL},
3740 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
3741 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
3742 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
3743 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
3744 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
3745 0, NULL, NULL, NULL},
3746 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
3747 0, IA5StringValidate, IA5StringNormalize, NULL},
3748 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
3749 0, integerValidate, integerNormalize, integerPretty},
3750 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
3751 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
3752 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
3753 0, NULL, NULL, NULL},
3754 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
3755 0, NULL, NULL, NULL},
3756 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
3757 0, NULL, NULL, NULL},
3758 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
3759 0, NULL, NULL, NULL},
3760 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
3761 0, NULL, NULL, NULL},
3762 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
3763 0, nameUIDValidate, nameUIDNormalize, NULL},
3764 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
3765 0, NULL, NULL, NULL},
3766 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
3767 0, numericStringValidate, numericStringNormalize, NULL},
3768 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
3769 0, NULL, NULL, NULL},
3770 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
3771 0, oidValidate, NULL, NULL},
3772 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
3773 0, IA5StringValidate, IA5StringNormalize, NULL},
3774 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
3775 0, blobValidate, NULL, NULL},
3776 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
3777 0, UTF8StringValidate, UTF8StringNormalize, NULL},
3778 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
3779 0, NULL, NULL, NULL},
3780 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
3781 0, NULL, NULL, NULL},
3782 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
3783 0, printableStringValidate, IA5StringNormalize, NULL},
3784 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
3785 X_BINARY X_NOT_H_R ")",
3786 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
3787 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
3788 0, printableStringValidate, IA5StringNormalize, NULL},
3789 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
3790 0, NULL, NULL, NULL},
3791 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
3792 0, printableStringValidate, IA5StringNormalize, NULL},
3793 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
3794 0, utcTimeValidate, utcTimeNormalize, NULL},
3795 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
3796 0, NULL, NULL, NULL},
3797 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
3798 0, NULL, NULL, NULL},
3799 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
3800 0, NULL, NULL, NULL},
3801 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
3802 0, NULL, NULL, NULL},
3803 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
3804 0, NULL, NULL, NULL},
3806 /* RFC 2307 NIS Syntaxes */
3807 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
3808 0, nisNetgroupTripleValidate, NULL, NULL},
3809 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
3810 0, bootParameterValidate, NULL, NULL},
3812 /* OpenLDAP Experimental Syntaxes */
3813 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
3814 0, UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
3816 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
3817 0, NULL, NULL, NULL},
3819 /* OpenLDAP Void Syntax */
3820 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
3821 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
3822 {NULL, 0, NULL, NULL, NULL}
3825 struct mrule_defs_rec {
3827 slap_mask_t mrd_usage;
3828 slap_mr_convert_func * mrd_convert;
3829 slap_mr_normalize_func * mrd_normalize;
3830 slap_mr_match_func * mrd_match;
3831 slap_mr_indexer_func * mrd_indexer;
3832 slap_mr_filter_func * mrd_filter;
3834 char * mrd_associated;
3838 * Other matching rules in X.520 that we do not use (yet):
3840 * 2.5.13.9 numericStringOrderingMatch
3841 * 2.5.13.15 integerOrderingMatch
3842 * 2.5.13.18 octetStringOrderingMatch
3843 * 2.5.13.19 octetStringSubstringsMatch
3844 * 2.5.13.25 uTCTimeMatch
3845 * 2.5.13.26 uTCTimeOrderingMatch
3846 * 2.5.13.31 directoryStringFirstComponentMatch
3847 * 2.5.13.32 wordMatch
3848 * 2.5.13.33 keywordMatch
3849 * 2.5.13.34 certificateExactMatch
3850 * 2.5.13.35 certificateMatch
3851 * 2.5.13.36 certificatePairExactMatch
3852 * 2.5.13.37 certificatePairMatch
3853 * 2.5.13.38 certificateListExactMatch
3854 * 2.5.13.39 certificateListMatch
3855 * 2.5.13.40 algorithmIdentifierMatch
3856 * 2.5.13.41 storedPrefixMatch
3857 * 2.5.13.42 attributeCertificateMatch
3858 * 2.5.13.43 readerAndKeyIDMatch
3859 * 2.5.13.44 attributeIntegrityMatch
3862 struct mrule_defs_rec mrule_defs[] = {
3864 * EQUALITY matching rules must be listed after associated APPROX
3865 * matching rules. So, we list all APPROX matching rules first.
3867 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
3868 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3869 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
3871 directoryStringApproxMatch, NULL, NULL,
3874 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
3875 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
3876 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
3878 IA5StringApproxMatch, NULL, NULL,
3882 * Other matching rules
3885 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
3886 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
3887 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3889 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
3892 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
3893 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
3894 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3896 dnMatch, dnIndexer, dnFilter,
3899 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
3900 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3901 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3903 caseIgnoreMatch, caseIgnoreIndexer, caseIgnoreFilter,
3904 directoryStringApproxMatchOID },
3906 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
3907 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3910 caseIgnoreOrderingMatch, NULL, NULL,
3913 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
3914 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3915 SLAP_MR_SUBSTR | SLAP_MR_EXT,
3917 caseIgnoreSubstringsMatch,
3918 caseIgnoreSubstringsIndexer,
3919 caseIgnoreSubstringsFilter,
3922 {"( 2.5.13.5 NAME 'caseExactMatch' "
3923 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3924 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3926 caseExactMatch, caseExactIndexer, caseExactFilter,
3927 directoryStringApproxMatchOID },
3929 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
3930 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3933 caseExactOrderingMatch, NULL, NULL,
3936 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
3937 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3938 SLAP_MR_SUBSTR | SLAP_MR_EXT,
3940 caseExactSubstringsMatch,
3941 caseExactSubstringsIndexer,
3942 caseExactSubstringsFilter,
3945 {"( 2.5.13.8 NAME 'numericStringMatch' "
3946 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
3947 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3950 caseIgnoreIA5Indexer,
3951 caseIgnoreIA5Filter,
3954 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
3955 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3956 SLAP_MR_SUBSTR | SLAP_MR_EXT,
3958 caseIgnoreIA5SubstringsMatch,
3959 caseIgnoreIA5SubstringsIndexer,
3960 caseIgnoreIA5SubstringsFilter,
3963 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
3964 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
3965 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3967 caseIgnoreListMatch, NULL, NULL,
3970 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
3971 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3972 SLAP_MR_SUBSTR | SLAP_MR_EXT,
3974 caseIgnoreListSubstringsMatch, NULL, NULL,
3977 {"( 2.5.13.13 NAME 'booleanMatch' "
3978 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
3979 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3981 booleanMatch, NULL, NULL,
3984 {"( 2.5.13.14 NAME 'integerMatch' "
3985 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
3986 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3988 integerMatch, integerIndexer, integerFilter,
3991 {"( 2.5.13.16 NAME 'bitStringMatch' "
3992 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
3993 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3995 bitStringMatch, NULL, NULL,
3998 {"( 2.5.13.17 NAME 'octetStringMatch' "
3999 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4000 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4002 octetStringMatch, octetStringIndexer, octetStringFilter,
4005 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4006 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4007 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4009 telephoneNumberMatch,
4010 telephoneNumberIndexer,
4011 telephoneNumberFilter,
4014 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4015 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4016 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4018 telephoneNumberSubstringsMatch,
4019 telephoneNumberSubstringsIndexer,
4020 telephoneNumberSubstringsFilter,
4023 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4024 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4025 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4030 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4031 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4032 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4034 uniqueMemberMatch, NULL, NULL,
4037 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4038 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4039 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4041 protocolInformationMatch, NULL, NULL,
4044 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4045 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4046 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4048 generalizedTimeMatch, NULL, NULL,
4051 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4052 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4055 generalizedTimeOrderingMatch, NULL, NULL,
4058 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4059 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4060 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4062 integerFirstComponentMatch, NULL, NULL,
4065 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4066 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4067 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4069 objectIdentifierFirstComponentMatch, NULL, NULL,
4072 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4073 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4074 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4076 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4077 IA5StringApproxMatchOID },
4079 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4080 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4081 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4083 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4084 IA5StringApproxMatchOID },
4086 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4087 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4090 caseIgnoreIA5SubstringsMatch,
4091 caseIgnoreIA5SubstringsIndexer,
4092 caseIgnoreIA5SubstringsFilter,
4095 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4096 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4099 caseExactIA5SubstringsMatch,
4100 caseExactIA5SubstringsIndexer,
4101 caseExactIA5SubstringsFilter,
4104 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4105 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4108 authPasswordMatch, NULL, NULL,
4111 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4112 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4115 OpenLDAPaciMatch, NULL, NULL,
4118 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
4127 /* we should only be called once (from main) */
4128 assert( schema_init_done == 0 );
4130 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4131 res = register_syntax( syntax_defs[i].sd_desc,
4132 syntax_defs[i].sd_flags,
4133 syntax_defs[i].sd_validate,
4134 syntax_defs[i].sd_normalize,
4135 syntax_defs[i].sd_pretty
4136 #ifdef SLAPD_BINARY_CONVERSION
4138 syntax_defs[i].sd_ber2str,
4139 syntax_defs[i].sd_str2ber
4144 fprintf( stderr, "schema_init: Error registering syntax %s\n",
4145 syntax_defs[i].sd_desc );
4150 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4151 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
4153 "schema_init: Ingoring unusable matching rule %s\n",
4154 mrule_defs[i].mrd_desc );
4158 res = register_matching_rule(
4159 mrule_defs[i].mrd_desc,
4160 mrule_defs[i].mrd_usage,
4161 mrule_defs[i].mrd_convert,
4162 mrule_defs[i].mrd_normalize,
4163 mrule_defs[i].mrd_match,
4164 mrule_defs[i].mrd_indexer,
4165 mrule_defs[i].mrd_filter,
4166 mrule_defs[i].mrd_associated );
4170 "schema_init: Error registering matching rule %s\n",
4171 mrule_defs[i].mrd_desc );
4175 schema_init_done = 1;
4176 return LDAP_SUCCESS;