1 /* schema_init.c - init builtin schema */
4 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
15 #include <ac/string.h>
16 #include <ac/socket.h>
21 #include "ldap_utf8.h"
23 #include "lutil_hash.h"
24 /* We should replace MD5 with a faster hash */
25 #define HASH_BYTES LUTIL_HASH_BYTES
26 #define HASH_CONTEXT lutil_HASH_CTX
27 #define HASH_Init(c) lutil_HASHInit(c)
28 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
29 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
31 /* recycled validatation routines */
32 #define berValidate blobValidate
34 /* unimplemented pretters */
35 #ifndef USE_LDAP_DN_PARSING
37 #endif /* !USE_LDAP_DN_PARSING */
38 #define integerPretty NULL
40 /* recycled matching routines */
41 #define bitStringMatch octetStringMatch
42 #define numericStringMatch caseIgnoreIA5Match
43 #define objectIdentifierMatch caseIgnoreIA5Match
44 #define telephoneNumberMatch caseIgnoreIA5Match
45 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
46 #define generalizedTimeMatch caseIgnoreIA5Match
47 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
48 #define uniqueMemberMatch dnMatch
50 /* approx matching rules */
51 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
52 #define directoryStringApproxMatch approxMatch
53 #define directoryStringApproxIndexer approxIndexer
54 #define directoryStringApproxFilter approxFilter
55 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
56 #define IA5StringApproxMatch approxMatch
57 #define IA5StringApproxIndexer approxIndexer
58 #define IA5StringApproxFilter approxFilter
60 /* orderring matching rules */
61 #define caseIgnoreOrderingMatch caseIgnoreMatch
62 #define caseExactOrderingMatch caseExactMatch
64 /* unimplemented matching routines */
65 #define caseIgnoreListMatch NULL
66 #define caseIgnoreListSubstringsMatch NULL
67 #define protocolInformationMatch NULL
68 #define integerFirstComponentMatch NULL
70 #define OpenLDAPaciMatch NULL
71 #define authPasswordMatch NULL
73 /* recycled indexing/filtering routines */
74 #define dnIndexer caseExactIgnoreIndexer
75 #define dnFilter caseExactIgnoreFilter
76 #define bitStringFilter octetStringFilter
77 #define bitStringIndexer octetStringIndexer
79 #define telephoneNumberIndexer caseIgnoreIA5Indexer
80 #define telephoneNumberFilter caseIgnoreIA5Filter
81 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
82 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
84 /* must match OIDs below */
85 #define caseExactMatchOID "2.5.13.5"
86 #define caseExactSubstringsMatchOID "2.5.13.7"
88 static char *strcasechr( const char *str, int c )
90 char *lower = strchr( str, TOLOWER(c) );
91 char *upper = strchr( str, TOUPPER(c) );
93 if( lower && upper ) {
94 return lower < upper ? lower : upper;
108 struct berval *value,
109 void *assertedValue )
111 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
114 match = memcmp( value->bv_val,
115 ((struct berval *) assertedValue)->bv_val,
123 /* Index generation function */
124 int octetStringIndexer(
129 struct berval *prefix,
130 struct berval **values,
131 struct berval ***keysp )
135 struct berval **keys;
136 HASH_CONTEXT HASHcontext;
137 unsigned char HASHdigest[HASH_BYTES];
138 struct berval digest;
139 digest.bv_val = HASHdigest;
140 digest.bv_len = sizeof(HASHdigest);
142 for( i=0; values[i] != NULL; i++ ) {
143 /* just count them */
146 /* we should have at least one value at this point */
149 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
151 slen = strlen( syntax->ssyn_oid );
152 mlen = strlen( mr->smr_oid );
154 for( i=0; values[i] != NULL; i++ ) {
155 HASH_Init( &HASHcontext );
156 if( prefix != NULL && prefix->bv_len > 0 ) {
157 HASH_Update( &HASHcontext,
158 prefix->bv_val, prefix->bv_len );
160 HASH_Update( &HASHcontext,
161 syntax->ssyn_oid, slen );
162 HASH_Update( &HASHcontext,
164 HASH_Update( &HASHcontext,
165 values[i]->bv_val, values[i]->bv_len );
166 HASH_Final( HASHdigest, &HASHcontext );
168 keys[i] = ber_bvdup( &digest );
178 /* Index generation function */
179 int octetStringFilter(
184 struct berval *prefix,
186 struct berval ***keysp )
189 struct berval **keys;
190 HASH_CONTEXT HASHcontext;
191 unsigned char HASHdigest[HASH_BYTES];
192 struct berval *value = (struct berval *) assertValue;
193 struct berval digest;
194 digest.bv_val = HASHdigest;
195 digest.bv_len = sizeof(HASHdigest);
197 slen = strlen( syntax->ssyn_oid );
198 mlen = strlen( mr->smr_oid );
200 keys = ch_malloc( sizeof( struct berval * ) * 2 );
202 HASH_Init( &HASHcontext );
203 if( prefix != NULL && prefix->bv_len > 0 ) {
204 HASH_Update( &HASHcontext,
205 prefix->bv_val, prefix->bv_len );
207 HASH_Update( &HASHcontext,
208 syntax->ssyn_oid, slen );
209 HASH_Update( &HASHcontext,
211 HASH_Update( &HASHcontext,
212 value->bv_val, value->bv_len );
213 HASH_Final( HASHdigest, &HASHcontext );
215 keys[0] = ber_bvdup( &digest );
223 #ifdef USE_LDAP_DN_PARSING
232 if ( in->bv_len == 0 ) {
233 return( LDAP_SUCCESS );
236 rc = ldap_str2dn( in->bv_val, &dn, LDAP_DN_FORMAT_LDAPV3 );
237 ldapava_free_dn( dn );
239 if ( rc != LDAP_SUCCESS ) {
240 return( LDAP_INVALID_SYNTAX );
243 return( LDAP_SUCCESS );
250 struct berval **normalized )
252 struct berval *out = NULL;
254 if ( val->bv_len != 0 ) {
259 rc = ldap_str2dn( val->bv_val, &dn, LDAP_DN_FORMAT_LDAPV3 );
260 if ( rc != LDAP_SUCCESS ) {
261 return( LDAP_INVALID_SYNTAX );
264 rc = ldap_dn2str( dn, &dn_out, LDAP_DN_FORMAT_LDAPV3 );
265 ldapava_free_dn( dn );
267 if ( rc != LDAP_SUCCESS ) {
268 return( LDAP_INVALID_SYNTAX );
271 out = ber_bvstr( dn_out );
274 out = ber_bvdup( val );
279 return( LDAP_SUCCESS );
286 struct berval **normalized)
288 struct berval *out = NULL;
290 if ( val->bv_len != 0 ) {
293 unsigned flags = LDAP_DN_FORMAT_LDAPV3;
296 rc = ldap_str2dn( val->bv_val, &dn, flags );
297 if ( rc != LDAP_SUCCESS ) {
298 return( LDAP_INVALID_SYNTAX );
301 flags |= LDAP_DN_PRETTY;
303 rc = ldap_dn2str( dn, &dn_out, flags );
304 ldapava_free_dn( dn );
306 if ( rc != LDAP_SUCCESS ) {
307 return( LDAP_INVALID_SYNTAX );
310 out = ber_bvstr( dn_out );
313 out = ber_bvdup( val );
318 return( LDAP_SUCCESS );
327 struct berval *value,
328 void *assertedValue )
331 struct berval *asserted = (struct berval *) assertedValue;
333 match = value->bv_len - asserted->bv_len;
336 #ifdef USE_DN_NORMALIZE
337 match = strcmp( value->bv_val, asserted->bv_val );
338 fprintf(stderr, "USE_DN_NORMALIZE :(\n");
340 match = strcasecmp( value->bv_val, asserted->bv_val );
341 fprintf(stderr, "!USE_DN_NORMALIZE :)\n");
346 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
347 "dnMatch: %d\n %s\n %s\n", match,
348 value->bv_val, asserted->bv_val ));
350 Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
351 match, value->bv_val, asserted->bv_val );
355 return( LDAP_SUCCESS );
358 #else /* !USE_LDAP_DN_PARSING */
368 if( in->bv_len == 0 ) return LDAP_SUCCESS;
370 dn = ch_strdup( in->bv_val );
373 return LDAP_INVALID_SYNTAX;
375 } else if ( strlen( in->bv_val ) != in->bv_len ) {
376 rc = LDAP_INVALID_SYNTAX;
378 } else if ( dn_validate( dn ) == NULL ) {
379 rc = LDAP_INVALID_SYNTAX;
393 struct berval **normalized )
397 if ( val->bv_len != 0 ) {
399 out = ber_bvstr( UTF8normalize( val, UTF8_CASEFOLD ) );
401 dn = dn_validate( out->bv_val );
405 return LDAP_INVALID_SYNTAX;
409 out->bv_len = strlen( dn );
411 out = ber_bvdup( val );
424 struct berval *value,
425 void *assertedValue )
428 struct berval *asserted = (struct berval *) assertedValue;
430 match = value->bv_len - asserted->bv_len;
433 #ifdef USE_DN_NORMALIZE
434 match = strcmp( value->bv_val, asserted->bv_val );
436 match = strcasecmp( value->bv_val, asserted->bv_val );
441 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
442 "dnMatch: %d\n %s\n %s\n", match,
443 value->bv_val, asserted->bv_val ));
445 Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
446 match, value->bv_val, asserted->bv_val );
454 #endif /* !USE_LDAP_DN_PARSING */
464 if( in->bv_len == 0 ) return LDAP_SUCCESS;
466 dn = ber_bvdup( in );
468 if( dn->bv_val[dn->bv_len-1] == '\'' ) {
469 /* assume presence of optional UID */
472 for(i=dn->bv_len-2; i>2; i--) {
473 if( dn->bv_val[i] != '0' && dn->bv_val[i] != '1' ) {
477 if( dn->bv_val[i] != '\'' ||
478 dn->bv_val[i-1] != 'B' ||
479 dn->bv_val[i-2] != '#' ) {
481 return LDAP_INVALID_SYNTAX;
484 /* trim the UID to allow use of dn_validate */
485 dn->bv_val[i-2] = '\0';
488 rc = dn_validate( dn->bv_val ) == NULL
489 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
499 struct berval **normalized )
501 struct berval *out = ber_bvdup( val );
503 if( out->bv_len != 0 ) {
507 ber_len_t uidlen = 0;
509 if( out->bv_val[out->bv_len-1] == '\'' ) {
510 /* assume presence of optional UID */
511 uid = strrchr( out->bv_val, '#' );
515 return LDAP_INVALID_SYNTAX;
518 uidlen = out->bv_len - (out->bv_val - uid);
519 /* temporarily trim the UID */
523 #ifdef USE_DN_NORMALIZE
524 dn = dn_normalize( out->bv_val );
526 dn = dn_validate( out->bv_val );
531 return LDAP_INVALID_SYNTAX;
537 /* restore the separator */
540 SAFEMEMCPY( &dn[dnlen], uid, uidlen );
544 out->bv_len = dnlen + uidlen;
556 /* any value allowed */
565 /* any value allowed */
576 /* very unforgiving validation, requires no normalization
577 * before simplistic matching
579 if( in->bv_len < 3 ) {
580 return LDAP_INVALID_SYNTAX;
584 * rfc 2252 section 6.3 Bit String
585 * bitstring = "'" *binary-digit "'"
586 * binary-digit = "0" / "1"
587 * example: '0101111101'B
590 if( in->bv_val[0] != '\'' ||
591 in->bv_val[in->bv_len-2] != '\'' ||
592 in->bv_val[in->bv_len-1] != 'B' )
594 return LDAP_INVALID_SYNTAX;
597 for( i=in->bv_len-3; i>0; i-- ) {
598 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
599 return LDAP_INVALID_SYNTAX;
610 struct berval **normalized )
613 * A normalized bitString is has no extaneous (leading) zero bits.
614 * That is, '00010'B is normalized to '10'B
615 * However, as a special case, '0'B requires no normalization.
617 struct berval *newval;
620 /* start at the first bit */
623 /* Find the first non-zero bit */
624 while ( *p == '0' ) p++;
626 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
629 /* no non-zero bits */
630 newval->bv_val = ch_strdup("\'0\'B");
631 newval->bv_len = sizeof("\'0\'B") - 1;
635 newval->bv_val = ch_malloc( val->bv_len + 1 );
637 newval->bv_val[0] = '\'';
640 for( ; *p != '\0'; p++ ) {
641 newval->bv_val[newval->bv_len++] = *p;
644 newval->bv_val[newval->bv_len] = '\0';
647 *normalized = newval;
652 * Handling boolean syntax and matching is quite rigid.
653 * A more flexible approach would be to allow a variety
654 * of strings to be normalized and prettied into TRUE
662 /* very unforgiving validation, requires no normalization
663 * before simplistic matching
666 if( in->bv_len == 4 ) {
667 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
670 } else if( in->bv_len == 5 ) {
671 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
676 return LDAP_INVALID_SYNTAX;
685 struct berval *value,
686 void *assertedValue )
688 /* simplistic matching allowed by rigid validation */
689 struct berval *asserted = (struct berval *) assertedValue;
690 *matchp = value->bv_len != asserted->bv_len;
701 unsigned char *u = in->bv_val;
703 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
705 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
706 /* get the length indicated by the first byte */
707 len = LDAP_UTF8_CHARLEN( u );
709 /* should not be zero */
710 if( len == 0 ) return LDAP_INVALID_SYNTAX;
712 /* make sure len corresponds with the offset
713 to the next character */
714 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
717 if( count != 0 ) return LDAP_INVALID_SYNTAX;
726 struct berval **normalized )
728 struct berval *newval;
731 newval = ch_malloc( sizeof( struct berval ) );
735 /* Ignore initial whitespace */
736 while ( ldap_utf8_isspace( p ) ) {
742 return LDAP_INVALID_SYNTAX;
745 newval->bv_val = ch_strdup( p );
746 p = q = newval->bv_val;
752 if ( ldap_utf8_isspace( p ) ) {
753 len = LDAP_UTF8_COPY(q,p);
758 /* Ignore the extra whitespace */
759 while ( ldap_utf8_isspace( p ) ) {
763 len = LDAP_UTF8_COPY(q,p);
770 assert( *newval->bv_val );
771 assert( newval->bv_val < p );
774 /* cannot start with a space */
775 assert( !ldap_utf8_isspace(newval->bv_val) );
778 * If the string ended in space, backup the pointer one
779 * position. One is enough because the above loop collapsed
780 * all whitespace to a single space.
787 /* cannot end with a space */
788 assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
793 newval->bv_len = q - newval->bv_val;
794 *normalized = newval;
799 /* Returns Unicode cannonically normalized copy of a substring assertion
800 * Skipping attribute description */
801 SubstringsAssertion *
802 UTF8SubstringsassertionNormalize(
803 SubstringsAssertion *sa,
806 SubstringsAssertion *nsa;
809 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
814 if( sa->sa_initial != NULL ) {
815 nsa->sa_initial = ber_bvstr( UTF8normalize( sa->sa_initial, casefold ) );
816 if( nsa->sa_initial == NULL ) {
821 if( sa->sa_any != NULL ) {
822 for( i=0; sa->sa_any[i] != NULL; i++ ) {
825 nsa->sa_any = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
826 for( i=0; sa->sa_any[i] != NULL; i++ ) {
827 nsa->sa_any[i] = ber_bvstr( UTF8normalize( sa->sa_any[i], casefold ) );
828 if( nsa->sa_any[i] == NULL ) {
832 nsa->sa_any[i] = NULL;
835 if( sa->sa_final != NULL ) {
836 nsa->sa_final = ber_bvstr( UTF8normalize( sa->sa_final, casefold ) );
837 if( nsa->sa_final == NULL ) {
845 ber_bvfree( nsa->sa_final );
846 ber_bvecfree( nsa->sa_any );
847 ber_bvfree( nsa->sa_initial );
852 /* Strip characters with the 8th bit set */
865 while( *++q & 0x80 ) {
868 p = memmove(p, q, strlen(q) + 1);
876 #ifndef SLAPD_APPROX_OLDSINGLESTRING
878 #if defined(SLAPD_APPROX_INITIALS)
879 #define SLAPD_APPROX_DELIMITER "._ "
880 #define SLAPD_APPROX_WORDLEN 2
882 #define SLAPD_APPROX_DELIMITER " "
883 #define SLAPD_APPROX_WORDLEN 1
892 struct berval *value,
893 void *assertedValue )
895 char *val, *nval, *assertv, **values, **words, *c;
896 int i, count, len, nextchunk=0, nextavail=0;
899 /* Yes, this is necessary */
900 nval = UTF8normalize( value, UTF8_NOCASEFOLD );
905 strip8bitChars( nval );
907 /* Yes, this is necessary */
908 assertv = UTF8normalize( ((struct berval *)assertedValue),
910 if( assertv == NULL ) {
915 strip8bitChars( assertv );
916 avlen = strlen( assertv );
918 /* Isolate how many words there are */
919 for( c=nval,count=1; *c; c++ ) {
920 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
921 if ( c == NULL ) break;
926 /* Get a phonetic copy of each word */
927 words = (char **)ch_malloc( count * sizeof(char *) );
928 values = (char **)ch_malloc( count * sizeof(char *) );
929 for( c=nval,i=0; i<count; i++,c+=strlen(c)+1 ) {
931 values[i] = phonetic(c);
934 /* Work through the asserted value's words, to see if at least some
935 of the words are there, in the same order. */
937 while ( nextchunk < avlen ) {
938 len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER);
943 #if defined(SLAPD_APPROX_INITIALS)
944 else if( len == 1 ) {
945 /* Single letter words need to at least match one word's initial */
946 for( i=nextavail; i<count; i++ )
947 if( !strncasecmp( assertv+nextchunk, words[i], 1 )) {
954 /* Isolate the next word in the asserted value and phonetic it */
955 assertv[nextchunk+len] = '\0';
956 val = phonetic( assertv + nextchunk );
958 /* See if this phonetic chunk is in the remaining words of *value */
959 for( i=nextavail; i<count; i++ ){
960 if( !strcmp( val, values[i] ) ){
968 /* This chunk in the asserted value was NOT within the *value. */
974 /* Go on to the next word in the asserted value */
978 /* If some of the words were seen, call it a match */
979 if( nextavail > 0 ) {
988 for( i=0; i<count; i++ ) {
989 ch_free( values[i] );
1004 struct berval *prefix,
1005 struct berval **values,
1006 struct berval ***keysp )
1009 int i,j, len, wordcount, keycount=0;
1010 struct berval **newkeys, **keys=NULL;
1012 for( j=0; values[j] != NULL; j++ ) {
1013 /* Yes, this is necessary */
1014 val = UTF8normalize( values[j], UTF8_NOCASEFOLD );
1015 strip8bitChars( val );
1017 /* Isolate how many words there are. There will be a key for each */
1018 for( wordcount=0,c=val; *c; c++) {
1019 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1020 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1022 if (*c == '\0') break;
1026 /* Allocate/increase storage to account for new keys */
1027 newkeys = (struct berval **)ch_malloc( (keycount + wordcount + 1)
1028 * sizeof(struct berval *) );
1029 memcpy( newkeys, keys, keycount * sizeof(struct berval *) );
1030 if( keys ) ch_free( keys );
1033 /* Get a phonetic copy of each word */
1034 for( c=val,i=0; i<wordcount; c+=len+1 ) {
1036 if( len < SLAPD_APPROX_WORDLEN ) continue;
1037 keys[keycount] = (struct berval *)ch_malloc( sizeof(struct berval) );
1038 keys[keycount]->bv_val = phonetic( c );
1039 keys[keycount]->bv_len = strlen( keys[keycount]->bv_val );
1046 keys[keycount] = NULL;
1049 return LDAP_SUCCESS;
1058 struct berval *prefix,
1060 struct berval ***keysp )
1064 struct berval **keys;
1066 /* Yes, this is necessary */
1067 val = UTF8normalize( ((struct berval *)assertValue),
1070 keys = (struct berval **)ch_malloc( sizeof(struct berval *) );
1073 return LDAP_SUCCESS;
1075 strip8bitChars( val );
1077 /* Isolate how many words there are. There will be a key for each */
1078 for( count=0,c=val; *c; c++) {
1079 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1080 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1082 if (*c == '\0') break;
1086 /* Allocate storage for new keys */
1087 keys = (struct berval **)ch_malloc( (count + 1) * sizeof(struct berval *) );
1089 /* Get a phonetic copy of each word */
1090 for( c=val,i=0; i<count; c+=len+1 ) {
1092 if( len < SLAPD_APPROX_WORDLEN ) continue;
1093 keys[i] = ber_bvstr( phonetic( c ) );
1102 return LDAP_SUCCESS;
1107 /* No other form of Approximate Matching is defined */
1115 struct berval *value,
1116 void *assertedValue )
1118 char *vapprox, *avapprox;
1121 /* Yes, this is necessary */
1122 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1125 return LDAP_SUCCESS;
1128 /* Yes, this is necessary */
1129 t = UTF8normalize( ((struct berval *)assertedValue),
1134 return LDAP_SUCCESS;
1137 vapprox = phonetic( strip8bitChars( s ) );
1138 avapprox = phonetic( strip8bitChars( t ) );
1143 *matchp = strcmp( vapprox, avapprox );
1146 ch_free( avapprox );
1148 return LDAP_SUCCESS;
1157 struct berval *prefix,
1158 struct berval **values,
1159 struct berval ***keysp )
1162 struct berval **keys;
1165 for( i=0; values[i] != NULL; i++ ) {
1166 /* empty - just count them */
1169 /* we should have at least one value at this point */
1172 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * (i+1) );
1174 /* Copy each value and run it through phonetic() */
1175 for( i=0; values[i] != NULL; i++ ) {
1176 /* Yes, this is necessary */
1177 s = UTF8normalize( values[i], UTF8_NOCASEFOLD );
1179 /* strip 8-bit chars and run through phonetic() */
1180 keys[i] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1186 return LDAP_SUCCESS;
1196 struct berval *prefix,
1198 struct berval ***keysp )
1200 struct berval **keys;
1203 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * 2 );
1205 /* Yes, this is necessary */
1206 s = UTF8normalize( ((struct berval *)assertValue),
1211 /* strip 8-bit chars and run through phonetic() */
1212 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1218 return LDAP_SUCCESS;
1229 struct berval *value,
1230 void *assertedValue )
1232 *matchp = UTF8normcmp( value->bv_val,
1233 ((struct berval *) assertedValue)->bv_val,
1235 return LDAP_SUCCESS;
1239 caseExactIgnoreSubstringsMatch(
1244 struct berval *value,
1245 void *assertedValue )
1248 SubstringsAssertion *sub = NULL;
1252 char *nav, casefold;
1254 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1255 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1257 nav = UTF8normalize( value, casefold );
1263 left.bv_len = strlen( nav );
1265 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1271 /* Add up asserted input length */
1272 if( sub->sa_initial ) {
1273 inlen += sub->sa_initial->bv_len;
1276 for(i=0; sub->sa_any[i] != NULL; i++) {
1277 inlen += sub->sa_any[i]->bv_len;
1280 if( sub->sa_final ) {
1281 inlen += sub->sa_final->bv_len;
1284 if( sub->sa_initial ) {
1285 if( inlen > left.bv_len ) {
1290 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
1291 sub->sa_initial->bv_len );
1297 left.bv_val += sub->sa_initial->bv_len;
1298 left.bv_len -= sub->sa_initial->bv_len;
1299 inlen -= sub->sa_initial->bv_len;
1302 if( sub->sa_final ) {
1303 if( inlen > left.bv_len ) {
1308 match = strncmp( sub->sa_final->bv_val,
1309 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
1310 sub->sa_final->bv_len );
1316 left.bv_len -= sub->sa_final->bv_len;
1317 inlen -= sub->sa_final->bv_len;
1321 for(i=0; sub->sa_any[i]; i++) {
1326 if( inlen > left.bv_len ) {
1327 /* not enough length */
1332 if( sub->sa_any[i]->bv_len == 0 ) {
1336 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
1343 idx = p - left.bv_val;
1344 assert( idx < left.bv_len );
1346 if( idx >= left.bv_len ) {
1347 /* this shouldn't happen */
1349 ch_free( sub->sa_final );
1350 ber_bvecfree( sub->sa_any );
1351 ch_free( sub->sa_initial );
1359 if( sub->sa_any[i]->bv_len > left.bv_len ) {
1360 /* not enough left */
1365 match = strncmp( left.bv_val,
1366 sub->sa_any[i]->bv_val,
1367 sub->sa_any[i]->bv_len );
1375 left.bv_val += sub->sa_any[i]->bv_len;
1376 left.bv_len -= sub->sa_any[i]->bv_len;
1377 inlen -= sub->sa_any[i]->bv_len;
1384 ber_bvfree( sub->sa_final );
1385 ber_bvecfree( sub->sa_any );
1386 ber_bvfree( sub->sa_initial );
1390 return LDAP_SUCCESS;
1393 /* Index generation function */
1394 int caseExactIgnoreIndexer(
1399 struct berval *prefix,
1400 struct berval **values,
1401 struct berval ***keysp )
1406 struct berval **keys;
1407 HASH_CONTEXT HASHcontext;
1408 unsigned char HASHdigest[HASH_BYTES];
1409 struct berval digest;
1410 digest.bv_val = HASHdigest;
1411 digest.bv_len = sizeof(HASHdigest);
1413 for( i=0; values[i] != NULL; i++ ) {
1414 /* empty - just count them */
1417 /* we should have at least one value at this point */
1420 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
1422 slen = strlen( syntax->ssyn_oid );
1423 mlen = strlen( mr->smr_oid );
1425 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1426 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1428 for( i=0; values[i] != NULL; i++ ) {
1429 struct berval *value;
1430 value = ber_bvstr( UTF8normalize( values[i],
1433 HASH_Init( &HASHcontext );
1434 if( prefix != NULL && prefix->bv_len > 0 ) {
1435 HASH_Update( &HASHcontext,
1436 prefix->bv_val, prefix->bv_len );
1438 HASH_Update( &HASHcontext,
1439 syntax->ssyn_oid, slen );
1440 HASH_Update( &HASHcontext,
1441 mr->smr_oid, mlen );
1442 HASH_Update( &HASHcontext,
1443 value->bv_val, value->bv_len );
1444 HASH_Final( HASHdigest, &HASHcontext );
1446 ber_bvfree( value );
1448 keys[i] = ber_bvdup( &digest );
1453 return LDAP_SUCCESS;
1456 /* Index generation function */
1457 int caseExactIgnoreFilter(
1462 struct berval *prefix,
1464 struct berval ***keysp )
1468 struct berval **keys;
1469 HASH_CONTEXT HASHcontext;
1470 unsigned char HASHdigest[HASH_BYTES];
1471 struct berval *value;
1472 struct berval digest;
1473 digest.bv_val = HASHdigest;
1474 digest.bv_len = sizeof(HASHdigest);
1476 slen = strlen( syntax->ssyn_oid );
1477 mlen = strlen( mr->smr_oid );
1479 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1480 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1482 value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue),
1484 /* This usually happens if filter contains bad UTF8 */
1485 if( value == NULL ) {
1486 keys = ch_malloc( sizeof( struct berval * ) );
1488 return LDAP_SUCCESS;
1491 keys = ch_malloc( sizeof( struct berval * ) * 2 );
1493 HASH_Init( &HASHcontext );
1494 if( prefix != NULL && prefix->bv_len > 0 ) {
1495 HASH_Update( &HASHcontext,
1496 prefix->bv_val, prefix->bv_len );
1498 HASH_Update( &HASHcontext,
1499 syntax->ssyn_oid, slen );
1500 HASH_Update( &HASHcontext,
1501 mr->smr_oid, mlen );
1502 HASH_Update( &HASHcontext,
1503 value->bv_val, value->bv_len );
1504 HASH_Final( HASHdigest, &HASHcontext );
1506 keys[0] = ber_bvdup( &digest );
1509 ber_bvfree( value );
1512 return LDAP_SUCCESS;
1515 /* Substrings Index generation function */
1516 int caseExactIgnoreSubstringsIndexer(
1521 struct berval *prefix,
1522 struct berval **values,
1523 struct berval ***keysp )
1528 struct berval **keys;
1529 struct berval **nvalues;
1531 HASH_CONTEXT HASHcontext;
1532 unsigned char HASHdigest[HASH_BYTES];
1533 struct berval digest;
1534 digest.bv_val = HASHdigest;
1535 digest.bv_len = sizeof(HASHdigest);
1539 for( i=0; values[i] != NULL; i++ ) {
1540 /* empty - just count them */
1543 /* we should have at least one value at this point */
1546 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1547 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1549 nvalues = ch_malloc( sizeof( struct berval * ) * (i+1) );
1550 for( i=0; values[i] != NULL; i++ ) {
1551 nvalues[i] = ber_bvstr( UTF8normalize( values[i],
1557 for( i=0; values[i] != NULL; i++ ) {
1558 /* count number of indices to generate */
1559 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1563 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1564 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1565 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1566 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1568 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1572 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1573 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1574 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1578 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1579 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1580 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1581 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1583 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1589 /* no keys to generate */
1591 ber_bvecfree( nvalues );
1592 return LDAP_SUCCESS;
1595 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1597 slen = strlen( syntax->ssyn_oid );
1598 mlen = strlen( mr->smr_oid );
1601 for( i=0; values[i] != NULL; i++ ) {
1603 struct berval *value;
1605 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1609 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1610 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1612 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1613 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1615 for( j=0; j<max; j++ ) {
1616 HASH_Init( &HASHcontext );
1617 if( prefix != NULL && prefix->bv_len > 0 ) {
1618 HASH_Update( &HASHcontext,
1619 prefix->bv_val, prefix->bv_len );
1622 HASH_Update( &HASHcontext,
1623 &pre, sizeof( pre ) );
1624 HASH_Update( &HASHcontext,
1625 syntax->ssyn_oid, slen );
1626 HASH_Update( &HASHcontext,
1627 mr->smr_oid, mlen );
1628 HASH_Update( &HASHcontext,
1630 SLAP_INDEX_SUBSTR_MAXLEN );
1631 HASH_Final( HASHdigest, &HASHcontext );
1633 keys[nkeys++] = ber_bvdup( &digest );
1637 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1638 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1640 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1643 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1644 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1645 HASH_Init( &HASHcontext );
1646 if( prefix != NULL && prefix->bv_len > 0 ) {
1647 HASH_Update( &HASHcontext,
1648 prefix->bv_val, prefix->bv_len );
1650 HASH_Update( &HASHcontext,
1651 &pre, sizeof( pre ) );
1652 HASH_Update( &HASHcontext,
1653 syntax->ssyn_oid, slen );
1654 HASH_Update( &HASHcontext,
1655 mr->smr_oid, mlen );
1656 HASH_Update( &HASHcontext,
1658 HASH_Final( HASHdigest, &HASHcontext );
1660 keys[nkeys++] = ber_bvdup( &digest );
1663 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1664 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1665 HASH_Init( &HASHcontext );
1666 if( prefix != NULL && prefix->bv_len > 0 ) {
1667 HASH_Update( &HASHcontext,
1668 prefix->bv_val, prefix->bv_len );
1670 HASH_Update( &HASHcontext,
1671 &pre, sizeof( pre ) );
1672 HASH_Update( &HASHcontext,
1673 syntax->ssyn_oid, slen );
1674 HASH_Update( &HASHcontext,
1675 mr->smr_oid, mlen );
1676 HASH_Update( &HASHcontext,
1677 &value->bv_val[value->bv_len-j], j );
1678 HASH_Final( HASHdigest, &HASHcontext );
1680 keys[nkeys++] = ber_bvdup( &digest );
1695 ber_bvecfree( nvalues );
1697 return LDAP_SUCCESS;
1700 int caseExactIgnoreSubstringsFilter(
1705 struct berval *prefix,
1707 struct berval ***keysp )
1709 SubstringsAssertion *sa;
1711 ber_len_t nkeys = 0;
1712 size_t slen, mlen, klen;
1713 struct berval **keys;
1714 HASH_CONTEXT HASHcontext;
1715 unsigned char HASHdigest[HASH_BYTES];
1716 struct berval *value;
1717 struct berval digest;
1719 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1720 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1722 sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
1725 return LDAP_SUCCESS;
1728 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1729 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1734 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1736 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1737 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1738 /* don't bother accounting for stepping */
1739 nkeys += sa->sa_any[i]->bv_len -
1740 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1745 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1746 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1752 ber_bvfree( sa->sa_final );
1753 ber_bvecfree( sa->sa_any );
1754 ber_bvfree( sa->sa_initial );
1757 return LDAP_SUCCESS;
1760 digest.bv_val = HASHdigest;
1761 digest.bv_len = sizeof(HASHdigest);
1763 slen = strlen( syntax->ssyn_oid );
1764 mlen = strlen( mr->smr_oid );
1766 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1769 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1770 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1772 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1773 value = sa->sa_initial;
1775 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1776 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1778 HASH_Init( &HASHcontext );
1779 if( prefix != NULL && prefix->bv_len > 0 ) {
1780 HASH_Update( &HASHcontext,
1781 prefix->bv_val, prefix->bv_len );
1783 HASH_Update( &HASHcontext,
1784 &pre, sizeof( pre ) );
1785 HASH_Update( &HASHcontext,
1786 syntax->ssyn_oid, slen );
1787 HASH_Update( &HASHcontext,
1788 mr->smr_oid, mlen );
1789 HASH_Update( &HASHcontext,
1790 value->bv_val, klen );
1791 HASH_Final( HASHdigest, &HASHcontext );
1793 keys[nkeys++] = ber_bvdup( &digest );
1796 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1798 pre = SLAP_INDEX_SUBSTR_PREFIX;
1799 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1801 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1802 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1806 value = sa->sa_any[i];
1809 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1810 j += SLAP_INDEX_SUBSTR_STEP )
1812 HASH_Init( &HASHcontext );
1813 if( prefix != NULL && prefix->bv_len > 0 ) {
1814 HASH_Update( &HASHcontext,
1815 prefix->bv_val, prefix->bv_len );
1817 HASH_Update( &HASHcontext,
1818 &pre, sizeof( pre ) );
1819 HASH_Update( &HASHcontext,
1820 syntax->ssyn_oid, slen );
1821 HASH_Update( &HASHcontext,
1822 mr->smr_oid, mlen );
1823 HASH_Update( &HASHcontext,
1824 &value->bv_val[j], klen );
1825 HASH_Final( HASHdigest, &HASHcontext );
1827 keys[nkeys++] = ber_bvdup( &digest );
1833 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1834 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1836 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1837 value = sa->sa_final;
1839 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1840 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1842 HASH_Init( &HASHcontext );
1843 if( prefix != NULL && prefix->bv_len > 0 ) {
1844 HASH_Update( &HASHcontext,
1845 prefix->bv_val, prefix->bv_len );
1847 HASH_Update( &HASHcontext,
1848 &pre, sizeof( pre ) );
1849 HASH_Update( &HASHcontext,
1850 syntax->ssyn_oid, slen );
1851 HASH_Update( &HASHcontext,
1852 mr->smr_oid, mlen );
1853 HASH_Update( &HASHcontext,
1854 &value->bv_val[value->bv_len-klen], klen );
1855 HASH_Final( HASHdigest, &HASHcontext );
1857 keys[nkeys++] = ber_bvdup( &digest );
1867 ber_bvfree( sa->sa_final );
1868 ber_bvecfree( sa->sa_any );
1869 ber_bvfree( sa->sa_initial );
1872 return LDAP_SUCCESS;
1881 struct berval *value,
1882 void *assertedValue )
1884 *matchp = UTF8normcmp( value->bv_val,
1885 ((struct berval *) assertedValue)->bv_val,
1887 return LDAP_SUCCESS;
1893 struct berval *val )
1897 if( val->bv_len == 0 ) {
1898 /* disallow empty strings */
1899 return LDAP_INVALID_SYNTAX;
1902 if( OID_LEADCHAR(val->bv_val[0]) ) {
1904 for(i=1; i < val->bv_len; i++) {
1905 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1906 if( dot++ ) return 1;
1907 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1910 return LDAP_INVALID_SYNTAX;
1914 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1916 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1917 for(i=1; i < val->bv_len; i++) {
1918 if( !DESC_CHAR(val->bv_val[i] ) ) {
1919 return LDAP_INVALID_SYNTAX;
1923 return LDAP_SUCCESS;
1926 return LDAP_INVALID_SYNTAX;
1935 struct berval *value,
1936 void *assertedValue )
1939 int vsign=0, avsign=0;
1940 struct berval *asserted;
1941 ber_len_t vlen, avlen;
1944 /* Start off pessimistic */
1947 /* Skip past leading spaces/zeros, and get the sign of the *value number */
1949 vlen = value->bv_len;
1951 if( ASCII_SPACE(*v) || ( *v == '0' )) {
1952 /* empty -- skip spaces */
1954 else if ( *v == '+' ) {
1957 else if ( *v == '-' ) {
1960 else if ( ASCII_DIGIT(*v) ) {
1961 if ( vsign == 0 ) vsign = 1;
1969 /* Skip past leading spaces/zeros, and get the sign of the *assertedValue
1971 asserted = (struct berval *) assertedValue;
1972 av = asserted->bv_val;
1973 avlen = asserted->bv_len;
1975 if( ASCII_SPACE(*av) || ( *av == '0' )) {
1976 /* empty -- skip spaces */
1978 else if ( *av == '+' ) {
1981 else if ( *av == '-' ) {
1984 else if ( ASCII_DIGIT(*av) ) {
1985 if ( avsign == 0 ) avsign = 1;
1993 /* The two ?sign vars are now one of :
1994 -2 negative non-zero number
1996 0 0 collapse these three to 0
1998 +2 positive non-zero number
2000 if ( abs( vsign ) == 1 ) vsign = 0;
2001 if ( abs( avsign ) == 1 ) avsign = 0;
2003 if( vsign != avsign ) return LDAP_SUCCESS;
2005 /* Check the significant digits */
2006 while( vlen && avlen ) {
2007 if( *v != *av ) break;
2014 /* If all digits compared equal, the numbers are equal */
2015 if(( vlen == 0 ) && ( avlen == 0 )) {
2018 return LDAP_SUCCESS;
2024 struct berval *val )
2028 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2030 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2031 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2032 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2033 return LDAP_INVALID_SYNTAX;
2036 for( i=1; i < val->bv_len; i++ ) {
2037 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2040 return LDAP_SUCCESS;
2047 struct berval **normalized )
2051 struct berval *newval;
2058 /* Ignore leading spaces */
2059 while ( len && ( *p == ' ' )) {
2066 negative = ( *p == '-' );
2067 if(( *p == '-' ) || ( *p == '+' )) {
2073 /* Ignore leading zeros */
2074 while ( len && ( *p == '0' )) {
2079 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
2081 /* If there are no non-zero digits left, the number is zero, otherwise
2082 allocate space for the number and copy it into the buffer */
2084 newval->bv_val = ch_strdup("0");
2088 newval->bv_len = len+negative;
2089 newval->bv_val = ch_malloc( newval->bv_len );
2091 newval->bv_val[0] = '-';
2093 memcpy( newval->bv_val + negative, p, len );
2096 *normalized = newval;
2097 return LDAP_SUCCESS;
2100 /* Index generation function */
2106 struct berval *prefix,
2107 struct berval **values,
2108 struct berval ***keysp )
2111 struct berval **keys;
2113 /* we should have at least one value at this point */
2114 assert( values != NULL && values[0] != NULL );
2116 for( i=0; values[i] != NULL; i++ ) {
2117 /* empty -- just count them */
2120 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2122 for( i=0; values[i] != NULL; i++ ) {
2123 integerNormalize( syntax, values[i], &keys[i] );
2128 return LDAP_SUCCESS;
2131 /* Index generation function */
2137 struct berval *prefix,
2139 struct berval ***keysp )
2141 struct berval **keys;
2143 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2144 integerNormalize( syntax, assertValue, &keys[0] );
2148 return LDAP_SUCCESS;
2153 countryStringValidate(
2155 struct berval *val )
2157 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2159 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2160 return LDAP_INVALID_SYNTAX;
2162 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2163 return LDAP_INVALID_SYNTAX;
2166 return LDAP_SUCCESS;
2170 printableStringValidate(
2172 struct berval *val )
2176 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2178 for(i=0; i < val->bv_len; i++) {
2179 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2180 return LDAP_INVALID_SYNTAX;
2184 return LDAP_SUCCESS;
2188 printablesStringValidate(
2190 struct berval *val )
2194 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2196 for(i=0; i < val->bv_len; i++) {
2197 if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
2198 return LDAP_INVALID_SYNTAX;
2202 return LDAP_SUCCESS;
2208 struct berval *val )
2212 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2214 for(i=0; i < val->bv_len; i++) {
2215 if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2218 return LDAP_SUCCESS;
2225 struct berval **normalized )
2227 struct berval *newval;
2230 newval = ch_malloc( sizeof( struct berval ) );
2234 /* Ignore initial whitespace */
2235 while ( ASCII_SPACE( *p ) ) {
2241 return LDAP_INVALID_SYNTAX;
2244 newval->bv_val = ch_strdup( p );
2245 p = q = newval->bv_val;
2248 if ( ASCII_SPACE( *p ) ) {
2251 /* Ignore the extra whitespace */
2252 while ( ASCII_SPACE( *p ) ) {
2260 assert( *newval->bv_val );
2261 assert( newval->bv_val < p );
2264 /* cannot start with a space */
2265 assert( !ASCII_SPACE(*newval->bv_val) );
2268 * If the string ended in space, backup the pointer one
2269 * position. One is enough because the above loop collapsed
2270 * all whitespace to a single space.
2273 if ( ASCII_SPACE( q[-1] ) ) {
2277 /* cannot end with a space */
2278 assert( !ASCII_SPACE( q[-1] ) );
2280 /* null terminate */
2283 newval->bv_len = q - newval->bv_val;
2284 *normalized = newval;
2286 return LDAP_SUCCESS;
2295 struct berval *value,
2296 void *assertedValue )
2298 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2301 match = strncmp( value->bv_val,
2302 ((struct berval *) assertedValue)->bv_val,
2307 return LDAP_SUCCESS;
2311 caseExactIA5SubstringsMatch(
2316 struct berval *value,
2317 void *assertedValue )
2320 SubstringsAssertion *sub = assertedValue;
2321 struct berval left = *value;
2325 /* Add up asserted input length */
2326 if( sub->sa_initial ) {
2327 inlen += sub->sa_initial->bv_len;
2330 for(i=0; sub->sa_any[i] != NULL; i++) {
2331 inlen += sub->sa_any[i]->bv_len;
2334 if( sub->sa_final ) {
2335 inlen += sub->sa_final->bv_len;
2338 if( sub->sa_initial ) {
2339 if( inlen > left.bv_len ) {
2344 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
2345 sub->sa_initial->bv_len );
2351 left.bv_val += sub->sa_initial->bv_len;
2352 left.bv_len -= sub->sa_initial->bv_len;
2353 inlen -= sub->sa_initial->bv_len;
2356 if( sub->sa_final ) {
2357 if( inlen > left.bv_len ) {
2362 match = strncmp( sub->sa_final->bv_val,
2363 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2364 sub->sa_final->bv_len );
2370 left.bv_len -= sub->sa_final->bv_len;
2371 inlen -= sub->sa_final->bv_len;
2375 for(i=0; sub->sa_any[i]; i++) {
2380 if( inlen > left.bv_len ) {
2381 /* not enough length */
2386 if( sub->sa_any[i]->bv_len == 0 ) {
2390 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
2397 idx = p - left.bv_val;
2398 assert( idx < left.bv_len );
2400 if( idx >= left.bv_len ) {
2401 /* this shouldn't happen */
2408 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2409 /* not enough left */
2414 match = strncmp( left.bv_val,
2415 sub->sa_any[i]->bv_val,
2416 sub->sa_any[i]->bv_len );
2424 left.bv_val += sub->sa_any[i]->bv_len;
2425 left.bv_len -= sub->sa_any[i]->bv_len;
2426 inlen -= sub->sa_any[i]->bv_len;
2432 return LDAP_SUCCESS;
2435 /* Index generation function */
2436 int caseExactIA5Indexer(
2441 struct berval *prefix,
2442 struct berval **values,
2443 struct berval ***keysp )
2447 struct berval **keys;
2448 HASH_CONTEXT HASHcontext;
2449 unsigned char HASHdigest[HASH_BYTES];
2450 struct berval digest;
2451 digest.bv_val = HASHdigest;
2452 digest.bv_len = sizeof(HASHdigest);
2454 for( i=0; values[i] != NULL; i++ ) {
2455 /* empty - just count them */
2458 /* we should have at least one value at this point */
2461 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2463 slen = strlen( syntax->ssyn_oid );
2464 mlen = strlen( mr->smr_oid );
2466 for( i=0; values[i] != NULL; i++ ) {
2467 struct berval *value = values[i];
2469 HASH_Init( &HASHcontext );
2470 if( prefix != NULL && prefix->bv_len > 0 ) {
2471 HASH_Update( &HASHcontext,
2472 prefix->bv_val, prefix->bv_len );
2474 HASH_Update( &HASHcontext,
2475 syntax->ssyn_oid, slen );
2476 HASH_Update( &HASHcontext,
2477 mr->smr_oid, mlen );
2478 HASH_Update( &HASHcontext,
2479 value->bv_val, value->bv_len );
2480 HASH_Final( HASHdigest, &HASHcontext );
2482 keys[i] = ber_bvdup( &digest );
2487 return LDAP_SUCCESS;
2490 /* Index generation function */
2491 int caseExactIA5Filter(
2496 struct berval *prefix,
2498 struct berval ***keysp )
2501 struct berval **keys;
2502 HASH_CONTEXT HASHcontext;
2503 unsigned char HASHdigest[HASH_BYTES];
2504 struct berval *value;
2505 struct berval digest;
2506 digest.bv_val = HASHdigest;
2507 digest.bv_len = sizeof(HASHdigest);
2509 slen = strlen( syntax->ssyn_oid );
2510 mlen = strlen( mr->smr_oid );
2512 value = (struct berval *) assertValue;
2514 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2516 HASH_Init( &HASHcontext );
2517 if( prefix != NULL && prefix->bv_len > 0 ) {
2518 HASH_Update( &HASHcontext,
2519 prefix->bv_val, prefix->bv_len );
2521 HASH_Update( &HASHcontext,
2522 syntax->ssyn_oid, slen );
2523 HASH_Update( &HASHcontext,
2524 mr->smr_oid, mlen );
2525 HASH_Update( &HASHcontext,
2526 value->bv_val, value->bv_len );
2527 HASH_Final( HASHdigest, &HASHcontext );
2529 keys[0] = ber_bvdup( &digest );
2533 return LDAP_SUCCESS;
2536 /* Substrings Index generation function */
2537 int caseExactIA5SubstringsIndexer(
2542 struct berval *prefix,
2543 struct berval **values,
2544 struct berval ***keysp )
2548 struct berval **keys;
2549 HASH_CONTEXT HASHcontext;
2550 unsigned char HASHdigest[HASH_BYTES];
2551 struct berval digest;
2552 digest.bv_val = HASHdigest;
2553 digest.bv_len = sizeof(HASHdigest);
2555 /* we should have at least one value at this point */
2556 assert( values != NULL && values[0] != NULL );
2559 for( i=0; values[i] != NULL; i++ ) {
2560 /* count number of indices to generate */
2561 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2565 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2566 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2567 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2568 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2570 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2574 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2575 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2576 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2580 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2581 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2582 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2583 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2585 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2591 /* no keys to generate */
2593 return LDAP_SUCCESS;
2596 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2598 slen = strlen( syntax->ssyn_oid );
2599 mlen = strlen( mr->smr_oid );
2602 for( i=0; values[i] != NULL; i++ ) {
2604 struct berval *value;
2607 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2609 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2610 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2612 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2613 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2615 for( j=0; j<max; j++ ) {
2616 HASH_Init( &HASHcontext );
2617 if( prefix != NULL && prefix->bv_len > 0 ) {
2618 HASH_Update( &HASHcontext,
2619 prefix->bv_val, prefix->bv_len );
2622 HASH_Update( &HASHcontext,
2623 &pre, sizeof( pre ) );
2624 HASH_Update( &HASHcontext,
2625 syntax->ssyn_oid, slen );
2626 HASH_Update( &HASHcontext,
2627 mr->smr_oid, mlen );
2628 HASH_Update( &HASHcontext,
2630 SLAP_INDEX_SUBSTR_MAXLEN );
2631 HASH_Final( HASHdigest, &HASHcontext );
2633 keys[nkeys++] = ber_bvdup( &digest );
2637 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2638 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2640 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2643 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2644 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2645 HASH_Init( &HASHcontext );
2646 if( prefix != NULL && prefix->bv_len > 0 ) {
2647 HASH_Update( &HASHcontext,
2648 prefix->bv_val, prefix->bv_len );
2650 HASH_Update( &HASHcontext,
2651 &pre, sizeof( pre ) );
2652 HASH_Update( &HASHcontext,
2653 syntax->ssyn_oid, slen );
2654 HASH_Update( &HASHcontext,
2655 mr->smr_oid, mlen );
2656 HASH_Update( &HASHcontext,
2658 HASH_Final( HASHdigest, &HASHcontext );
2660 keys[nkeys++] = ber_bvdup( &digest );
2663 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2664 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2665 HASH_Init( &HASHcontext );
2666 if( prefix != NULL && prefix->bv_len > 0 ) {
2667 HASH_Update( &HASHcontext,
2668 prefix->bv_val, prefix->bv_len );
2670 HASH_Update( &HASHcontext,
2671 &pre, sizeof( pre ) );
2672 HASH_Update( &HASHcontext,
2673 syntax->ssyn_oid, slen );
2674 HASH_Update( &HASHcontext,
2675 mr->smr_oid, mlen );
2676 HASH_Update( &HASHcontext,
2677 &value->bv_val[value->bv_len-j], j );
2678 HASH_Final( HASHdigest, &HASHcontext );
2680 keys[nkeys++] = ber_bvdup( &digest );
2694 return LDAP_SUCCESS;
2697 int caseExactIA5SubstringsFilter(
2702 struct berval *prefix,
2704 struct berval ***keysp )
2706 SubstringsAssertion *sa = assertValue;
2708 ber_len_t nkeys = 0;
2709 size_t slen, mlen, klen;
2710 struct berval **keys;
2711 HASH_CONTEXT HASHcontext;
2712 unsigned char HASHdigest[HASH_BYTES];
2713 struct berval *value;
2714 struct berval digest;
2716 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2717 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2722 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2724 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2725 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2726 /* don't bother accounting for stepping */
2727 nkeys += sa->sa_any[i]->bv_len -
2728 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2733 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2734 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2741 return LDAP_SUCCESS;
2744 digest.bv_val = HASHdigest;
2745 digest.bv_len = sizeof(HASHdigest);
2747 slen = strlen( syntax->ssyn_oid );
2748 mlen = strlen( mr->smr_oid );
2750 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2753 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2754 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2756 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2757 value = sa->sa_initial;
2759 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2760 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2762 HASH_Init( &HASHcontext );
2763 if( prefix != NULL && prefix->bv_len > 0 ) {
2764 HASH_Update( &HASHcontext,
2765 prefix->bv_val, prefix->bv_len );
2767 HASH_Update( &HASHcontext,
2768 &pre, sizeof( pre ) );
2769 HASH_Update( &HASHcontext,
2770 syntax->ssyn_oid, slen );
2771 HASH_Update( &HASHcontext,
2772 mr->smr_oid, mlen );
2773 HASH_Update( &HASHcontext,
2774 value->bv_val, klen );
2775 HASH_Final( HASHdigest, &HASHcontext );
2777 keys[nkeys++] = ber_bvdup( &digest );
2780 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2782 pre = SLAP_INDEX_SUBSTR_PREFIX;
2783 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2785 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2786 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2790 value = sa->sa_any[i];
2793 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2794 j += SLAP_INDEX_SUBSTR_STEP )
2796 HASH_Init( &HASHcontext );
2797 if( prefix != NULL && prefix->bv_len > 0 ) {
2798 HASH_Update( &HASHcontext,
2799 prefix->bv_val, prefix->bv_len );
2801 HASH_Update( &HASHcontext,
2802 &pre, sizeof( pre ) );
2803 HASH_Update( &HASHcontext,
2804 syntax->ssyn_oid, slen );
2805 HASH_Update( &HASHcontext,
2806 mr->smr_oid, mlen );
2807 HASH_Update( &HASHcontext,
2808 &value->bv_val[j], klen );
2809 HASH_Final( HASHdigest, &HASHcontext );
2811 keys[nkeys++] = ber_bvdup( &digest );
2816 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2817 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2819 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2820 value = sa->sa_final;
2822 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2823 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2825 HASH_Init( &HASHcontext );
2826 if( prefix != NULL && prefix->bv_len > 0 ) {
2827 HASH_Update( &HASHcontext,
2828 prefix->bv_val, prefix->bv_len );
2830 HASH_Update( &HASHcontext,
2831 &pre, sizeof( pre ) );
2832 HASH_Update( &HASHcontext,
2833 syntax->ssyn_oid, slen );
2834 HASH_Update( &HASHcontext,
2835 mr->smr_oid, mlen );
2836 HASH_Update( &HASHcontext,
2837 &value->bv_val[value->bv_len-klen], klen );
2838 HASH_Final( HASHdigest, &HASHcontext );
2840 keys[nkeys++] = ber_bvdup( &digest );
2851 return LDAP_SUCCESS;
2860 struct berval *value,
2861 void *assertedValue )
2863 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2865 if( match == 0 && value->bv_len ) {
2866 match = strncasecmp( value->bv_val,
2867 ((struct berval *) assertedValue)->bv_val,
2872 return LDAP_SUCCESS;
2876 caseIgnoreIA5SubstringsMatch(
2881 struct berval *value,
2882 void *assertedValue )
2885 SubstringsAssertion *sub = assertedValue;
2886 struct berval left = *value;
2890 /* Add up asserted input length */
2891 if( sub->sa_initial ) {
2892 inlen += sub->sa_initial->bv_len;
2895 for(i=0; sub->sa_any[i] != NULL; i++) {
2896 inlen += sub->sa_any[i]->bv_len;
2899 if( sub->sa_final ) {
2900 inlen += sub->sa_final->bv_len;
2903 if( sub->sa_initial ) {
2904 if( inlen > left.bv_len ) {
2909 match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
2910 sub->sa_initial->bv_len );
2916 left.bv_val += sub->sa_initial->bv_len;
2917 left.bv_len -= sub->sa_initial->bv_len;
2918 inlen -= sub->sa_initial->bv_len;
2921 if( sub->sa_final ) {
2922 if( inlen > left.bv_len ) {
2927 match = strncasecmp( sub->sa_final->bv_val,
2928 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2929 sub->sa_final->bv_len );
2935 left.bv_len -= sub->sa_final->bv_len;
2936 inlen -= sub->sa_final->bv_len;
2940 for(i=0; sub->sa_any[i]; i++) {
2945 if( inlen > left.bv_len ) {
2946 /* not enough length */
2951 if( sub->sa_any[i]->bv_len == 0 ) {
2955 p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
2962 idx = p - left.bv_val;
2963 assert( idx < left.bv_len );
2965 if( idx >= left.bv_len ) {
2966 /* this shouldn't happen */
2973 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2974 /* not enough left */
2979 match = strncasecmp( left.bv_val,
2980 sub->sa_any[i]->bv_val,
2981 sub->sa_any[i]->bv_len );
2990 left.bv_val += sub->sa_any[i]->bv_len;
2991 left.bv_len -= sub->sa_any[i]->bv_len;
2992 inlen -= sub->sa_any[i]->bv_len;
2998 return LDAP_SUCCESS;
3001 /* Index generation function */
3002 int caseIgnoreIA5Indexer(
3007 struct berval *prefix,
3008 struct berval **values,
3009 struct berval ***keysp )
3013 struct berval **keys;
3014 HASH_CONTEXT HASHcontext;
3015 unsigned char HASHdigest[HASH_BYTES];
3016 struct berval digest;
3017 digest.bv_val = HASHdigest;
3018 digest.bv_len = sizeof(HASHdigest);
3020 /* we should have at least one value at this point */
3021 assert( values != NULL && values[0] != NULL );
3023 for( i=0; values[i] != NULL; i++ ) {
3024 /* just count them */
3027 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
3029 slen = strlen( syntax->ssyn_oid );
3030 mlen = strlen( mr->smr_oid );
3032 for( i=0; values[i] != NULL; i++ ) {
3033 struct berval *value = ber_bvdup( values[i] );
3034 ldap_pvt_str2upper( value->bv_val );
3036 HASH_Init( &HASHcontext );
3037 if( prefix != NULL && prefix->bv_len > 0 ) {
3038 HASH_Update( &HASHcontext,
3039 prefix->bv_val, prefix->bv_len );
3041 HASH_Update( &HASHcontext,
3042 syntax->ssyn_oid, slen );
3043 HASH_Update( &HASHcontext,
3044 mr->smr_oid, mlen );
3045 HASH_Update( &HASHcontext,
3046 value->bv_val, value->bv_len );
3047 HASH_Final( HASHdigest, &HASHcontext );
3049 ber_bvfree( value );
3051 keys[i] = ber_bvdup( &digest );
3056 return LDAP_SUCCESS;
3059 /* Index generation function */
3060 int caseIgnoreIA5Filter(
3065 struct berval *prefix,
3067 struct berval ***keysp )
3070 struct berval **keys;
3071 HASH_CONTEXT HASHcontext;
3072 unsigned char HASHdigest[HASH_BYTES];
3073 struct berval *value;
3074 struct berval digest;
3075 digest.bv_val = HASHdigest;
3076 digest.bv_len = sizeof(HASHdigest);
3078 slen = strlen( syntax->ssyn_oid );
3079 mlen = strlen( mr->smr_oid );
3081 value = ber_bvdup( (struct berval *) assertValue );
3082 ldap_pvt_str2upper( value->bv_val );
3084 keys = ch_malloc( sizeof( struct berval * ) * 2 );
3086 HASH_Init( &HASHcontext );
3087 if( prefix != NULL && prefix->bv_len > 0 ) {
3088 HASH_Update( &HASHcontext,
3089 prefix->bv_val, prefix->bv_len );
3091 HASH_Update( &HASHcontext,
3092 syntax->ssyn_oid, slen );
3093 HASH_Update( &HASHcontext,
3094 mr->smr_oid, mlen );
3095 HASH_Update( &HASHcontext,
3096 value->bv_val, value->bv_len );
3097 HASH_Final( HASHdigest, &HASHcontext );
3099 keys[0] = ber_bvdup( &digest );
3102 ber_bvfree( value );
3106 return LDAP_SUCCESS;
3109 /* Substrings Index generation function */
3110 int caseIgnoreIA5SubstringsIndexer(
3115 struct berval *prefix,
3116 struct berval **values,
3117 struct berval ***keysp )
3121 struct berval **keys;
3122 HASH_CONTEXT HASHcontext;
3123 unsigned char HASHdigest[HASH_BYTES];
3124 struct berval digest;
3125 digest.bv_val = HASHdigest;
3126 digest.bv_len = sizeof(HASHdigest);
3128 /* we should have at least one value at this point */
3129 assert( values != NULL && values[0] != NULL );
3132 for( i=0; values[i] != NULL; i++ ) {
3133 /* count number of indices to generate */
3134 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3138 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3139 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3140 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3141 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3143 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3147 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3148 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3149 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3153 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3154 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3155 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3156 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3158 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3164 /* no keys to generate */
3166 return LDAP_SUCCESS;
3169 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
3171 slen = strlen( syntax->ssyn_oid );
3172 mlen = strlen( mr->smr_oid );
3175 for( i=0; values[i] != NULL; i++ ) {
3177 struct berval *value;
3179 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3181 value = ber_bvdup( values[i] );
3182 ldap_pvt_str2upper( value->bv_val );
3184 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3185 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3187 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3188 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3190 for( j=0; j<max; j++ ) {
3191 HASH_Init( &HASHcontext );
3192 if( prefix != NULL && prefix->bv_len > 0 ) {
3193 HASH_Update( &HASHcontext,
3194 prefix->bv_val, prefix->bv_len );
3197 HASH_Update( &HASHcontext,
3198 &pre, sizeof( pre ) );
3199 HASH_Update( &HASHcontext,
3200 syntax->ssyn_oid, slen );
3201 HASH_Update( &HASHcontext,
3202 mr->smr_oid, mlen );
3203 HASH_Update( &HASHcontext,
3205 SLAP_INDEX_SUBSTR_MAXLEN );
3206 HASH_Final( HASHdigest, &HASHcontext );
3208 keys[nkeys++] = ber_bvdup( &digest );
3212 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3213 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3215 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3218 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3219 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3220 HASH_Init( &HASHcontext );
3221 if( prefix != NULL && prefix->bv_len > 0 ) {
3222 HASH_Update( &HASHcontext,
3223 prefix->bv_val, prefix->bv_len );
3225 HASH_Update( &HASHcontext,
3226 &pre, sizeof( pre ) );
3227 HASH_Update( &HASHcontext,
3228 syntax->ssyn_oid, slen );
3229 HASH_Update( &HASHcontext,
3230 mr->smr_oid, mlen );
3231 HASH_Update( &HASHcontext,
3233 HASH_Final( HASHdigest, &HASHcontext );
3235 keys[nkeys++] = ber_bvdup( &digest );
3238 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3239 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3240 HASH_Init( &HASHcontext );
3241 if( prefix != NULL && prefix->bv_len > 0 ) {
3242 HASH_Update( &HASHcontext,
3243 prefix->bv_val, prefix->bv_len );
3245 HASH_Update( &HASHcontext,
3246 &pre, sizeof( pre ) );
3247 HASH_Update( &HASHcontext,
3248 syntax->ssyn_oid, slen );
3249 HASH_Update( &HASHcontext,
3250 mr->smr_oid, mlen );
3251 HASH_Update( &HASHcontext,
3252 &value->bv_val[value->bv_len-j], j );
3253 HASH_Final( HASHdigest, &HASHcontext );
3255 keys[nkeys++] = ber_bvdup( &digest );
3260 ber_bvfree( value );
3271 return LDAP_SUCCESS;
3274 int caseIgnoreIA5SubstringsFilter(
3279 struct berval *prefix,
3281 struct berval ***keysp )
3283 SubstringsAssertion *sa = assertValue;
3285 ber_len_t nkeys = 0;
3286 size_t slen, mlen, klen;
3287 struct berval **keys;
3288 HASH_CONTEXT HASHcontext;
3289 unsigned char HASHdigest[HASH_BYTES];
3290 struct berval *value;
3291 struct berval digest;
3293 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3294 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3299 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3301 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3302 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3303 /* don't bother accounting for stepping */
3304 nkeys += sa->sa_any[i]->bv_len -
3305 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3310 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3311 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3318 return LDAP_SUCCESS;
3321 digest.bv_val = HASHdigest;
3322 digest.bv_len = sizeof(HASHdigest);
3324 slen = strlen( syntax->ssyn_oid );
3325 mlen = strlen( mr->smr_oid );
3327 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
3330 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3331 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3333 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3334 value = ber_bvdup( sa->sa_initial );
3335 ldap_pvt_str2upper( value->bv_val );
3337 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3338 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3340 HASH_Init( &HASHcontext );
3341 if( prefix != NULL && prefix->bv_len > 0 ) {
3342 HASH_Update( &HASHcontext,
3343 prefix->bv_val, prefix->bv_len );
3345 HASH_Update( &HASHcontext,
3346 &pre, sizeof( pre ) );
3347 HASH_Update( &HASHcontext,
3348 syntax->ssyn_oid, slen );
3349 HASH_Update( &HASHcontext,
3350 mr->smr_oid, mlen );
3351 HASH_Update( &HASHcontext,
3352 value->bv_val, klen );
3353 HASH_Final( HASHdigest, &HASHcontext );
3355 ber_bvfree( value );
3356 keys[nkeys++] = ber_bvdup( &digest );
3359 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3361 pre = SLAP_INDEX_SUBSTR_PREFIX;
3362 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3364 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3365 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3369 value = ber_bvdup( sa->sa_any[i] );
3370 ldap_pvt_str2upper( value->bv_val );
3373 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3374 j += SLAP_INDEX_SUBSTR_STEP )
3376 HASH_Init( &HASHcontext );
3377 if( prefix != NULL && prefix->bv_len > 0 ) {
3378 HASH_Update( &HASHcontext,
3379 prefix->bv_val, prefix->bv_len );
3381 HASH_Update( &HASHcontext,
3382 &pre, sizeof( pre ) );
3383 HASH_Update( &HASHcontext,
3384 syntax->ssyn_oid, slen );
3385 HASH_Update( &HASHcontext,
3386 mr->smr_oid, mlen );
3387 HASH_Update( &HASHcontext,
3388 &value->bv_val[j], klen );
3389 HASH_Final( HASHdigest, &HASHcontext );
3391 keys[nkeys++] = ber_bvdup( &digest );
3394 ber_bvfree( value );
3398 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3399 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3401 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3402 value = ber_bvdup( sa->sa_final );
3403 ldap_pvt_str2upper( value->bv_val );
3405 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3406 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3408 HASH_Init( &HASHcontext );
3409 if( prefix != NULL && prefix->bv_len > 0 ) {
3410 HASH_Update( &HASHcontext,
3411 prefix->bv_val, prefix->bv_len );
3413 HASH_Update( &HASHcontext,
3414 &pre, sizeof( pre ) );
3415 HASH_Update( &HASHcontext,
3416 syntax->ssyn_oid, slen );
3417 HASH_Update( &HASHcontext,
3418 mr->smr_oid, mlen );
3419 HASH_Update( &HASHcontext,
3420 &value->bv_val[value->bv_len-klen], klen );
3421 HASH_Final( HASHdigest, &HASHcontext );
3423 ber_bvfree( value );
3424 keys[nkeys++] = ber_bvdup( &digest );
3435 return LDAP_SUCCESS;
3439 numericStringValidate(
3445 for(i=0; i < in->bv_len; i++) {
3446 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3447 return LDAP_INVALID_SYNTAX;
3451 return LDAP_SUCCESS;
3455 numericStringNormalize(
3458 struct berval **normalized )
3460 /* removal all spaces */
3461 struct berval *newval;
3464 newval = ch_malloc( sizeof( struct berval ) );
3465 newval->bv_val = ch_malloc( val->bv_len + 1 );
3471 if ( ASCII_SPACE( *p ) ) {
3472 /* Ignore whitespace */
3479 /* we should have copied no more then is in val */
3480 assert( (q - newval->bv_val) <= (p - val->bv_val) );
3482 /* null terminate */
3485 newval->bv_len = q - newval->bv_val;
3486 *normalized = newval;
3488 return LDAP_SUCCESS;
3492 objectIdentifierFirstComponentMatch(
3497 struct berval *value,
3498 void *assertedValue )
3500 int rc = LDAP_SUCCESS;
3502 struct berval *asserted = (struct berval *) assertedValue;
3506 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3507 return LDAP_INVALID_SYNTAX;
3510 /* trim leading white space */
3511 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3515 /* grab next word */
3516 oid.bv_val = &value->bv_val[i];
3517 oid.bv_len = value->bv_len - i;
3518 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3523 /* insert attributeTypes, objectclass check here */
3524 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3525 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3528 char *stored = ch_malloc( oid.bv_len + 1 );
3529 AC_MEMCPY( stored, oid.bv_val, oid.bv_len );
3530 stored[oid.bv_len] = '\0';
3532 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3533 MatchingRule *asserted_mr = mr_find( asserted->bv_val );
3534 MatchingRule *stored_mr = mr_find( stored );
3536 if( asserted_mr == NULL ) {
3537 rc = SLAPD_COMPARE_UNDEFINED;
3539 match = asserted_mr != stored_mr;
3542 } else if ( !strcmp( syntax->ssyn_oid,
3543 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3545 AttributeType *asserted_at = at_find( asserted->bv_val );
3546 AttributeType *stored_at = at_find( stored );
3548 if( asserted_at == NULL ) {
3549 rc = SLAPD_COMPARE_UNDEFINED;
3551 match = asserted_at != stored_at;
3554 } else if ( !strcmp( syntax->ssyn_oid,
3555 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3557 ObjectClass *asserted_oc = oc_find( asserted->bv_val );
3558 ObjectClass *stored_oc = oc_find( stored );
3560 if( asserted_oc == NULL ) {
3561 rc = SLAPD_COMPARE_UNDEFINED;
3563 match = asserted_oc != stored_oc;
3571 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3572 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3573 match, value->bv_val, asserted->bv_val ));
3575 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3576 "%d\n\t\"%s\"\n\t\"%s\"\n",
3577 match, value->bv_val, asserted->bv_val );
3581 if( rc == LDAP_SUCCESS ) *matchp = match;
3591 struct berval *value,
3592 void *assertedValue )
3594 long lValue, lAssertedValue;
3596 /* safe to assume integers are NUL terminated? */
3597 lValue = strtoul(value->bv_val, NULL, 10);
3598 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3599 return LDAP_CONSTRAINT_VIOLATION;
3601 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3602 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3603 return LDAP_CONSTRAINT_VIOLATION;
3605 *matchp = (lValue & lAssertedValue);
3606 return LDAP_SUCCESS;
3615 struct berval *value,
3616 void *assertedValue )
3618 long lValue, lAssertedValue;
3620 /* safe to assume integers are NUL terminated? */
3621 lValue = strtoul(value->bv_val, NULL, 10);
3622 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3623 return LDAP_CONSTRAINT_VIOLATION;
3625 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3626 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3627 return LDAP_CONSTRAINT_VIOLATION;
3629 *matchp = (lValue | lAssertedValue);
3630 return LDAP_SUCCESS;
3634 #include <openssl/x509.h>
3635 #include <openssl/err.h>
3636 char digit[] = "0123456789";
3639 * Next function returns a string representation of a ASN1_INTEGER.
3640 * It works for unlimited lengths.
3643 static struct berval *
3644 asn1_integer2str(ASN1_INTEGER *a)
3649 /* We work backwards, make it fill from the end of buf */
3650 p = buf + sizeof(buf) - 1;
3653 if ( a == NULL || a->length == 0 ) {
3661 /* We want to preserve the original */
3662 copy = ch_malloc(n*sizeof(unsigned int));
3663 for (i = 0; i<n; i++) {
3664 copy[i] = a->data[i];
3668 * base indicates the index of the most significant
3669 * byte that might be nonzero. When it goes off the
3670 * end, we now there is nothing left to do.
3676 for (i = base; i<n; i++ ) {
3677 copy[i] += carry*256;
3678 carry = copy[i] % 10;
3683 * Way too large, we need to leave
3684 * room for sign if negative
3689 *--p = digit[carry];
3690 if (copy[base] == 0)
3696 if ( a->type == V_ASN1_NEG_INTEGER ) {
3700 return ber_bvstrdup(p);
3703 /* Get a DN in RFC2253 format from a X509_NAME internal struct */
3704 static struct berval *
3705 dn_openssl2ldap(X509_NAME *name)
3707 char issuer_dn[1024];
3710 bio = BIO_new(BIO_s_mem());
3713 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3714 "dn_openssl2ldap: error creating BIO_s_mem: %s\n",
3715 ERR_error_string(ERR_get_error(),NULL)));
3717 Debug( LDAP_DEBUG_ARGS, "dn_openssl2ldap: "
3718 "error creating BIO: %s\n",
3719 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3723 X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253);
3725 BIO_gets(bio, issuer_dn, 1024);
3728 return ber_bvstrdup(issuer_dn);
3732 * Given a certificate in DER format, extract the corresponding
3733 * assertion value for certificateExactMatch
3736 certificateExactConvert(
3738 struct berval ** out )
3741 unsigned char *p = in->bv_val;
3742 struct berval *serial;
3743 struct berval *issuer_dn;
3744 struct berval *bv_tmp;
3746 xcert = d2i_X509(NULL, &p, in->bv_len);
3749 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3750 "certificateExactConvert: error parsing cert: %s\n",
3751 ERR_error_string(ERR_get_error(),NULL)));
3753 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3754 "error parsing cert: %s\n",
3755 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3757 return LDAP_INVALID_SYNTAX;
3760 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3763 return LDAP_INVALID_SYNTAX;
3765 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
3769 return LDAP_INVALID_SYNTAX;
3771 /* Actually, dn_openssl2ldap returns in a normalized format, but
3772 it is different from our normalized format */
3774 if ( dnNormalize(NULL, bv_tmp, &issuer_dn) != LDAP_SUCCESS ) {
3778 return LDAP_INVALID_SYNTAX;
3784 *out = ch_malloc(sizeof(struct berval));
3785 (*out)->bv_len = serial->bv_len + 3 + issuer_dn->bv_len + 1;
3786 (*out)->bv_val = ch_malloc((*out)->bv_len);
3788 AC_MEMCPY(p, serial->bv_val, serial->bv_len);
3789 p += serial->bv_len;
3790 AC_MEMCPY(p, " $ ", 3);
3792 AC_MEMCPY(p, issuer_dn->bv_val, issuer_dn->bv_len);
3793 p += issuer_dn->bv_len;
3797 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3798 "certificateExactConvert: \n %s\n",
3801 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3803 (*out)->bv_val, NULL, NULL );
3807 ber_bvfree(issuer_dn);
3809 return LDAP_SUCCESS;
3813 serial_and_issuer_parse(
3814 struct berval *assertion,
3815 struct berval **serial,
3816 struct berval **issuer_dn
3824 begin = assertion->bv_val;
3825 end = assertion->bv_val+assertion->bv_len-1;
3826 for (p=begin; p<=end && *p != '$'; p++)
3829 return LDAP_INVALID_SYNTAX;
3831 /* p now points at the $ sign, now use begin and end to delimit the
3833 while (ASCII_SPACE(*begin))
3836 while (ASCII_SPACE(*end))
3839 q = ch_malloc( (end-begin+1)+1 );
3840 AC_MEMCPY( q, begin, end-begin+1 );
3841 q[end-begin+1] = '\0';
3842 *serial = ber_bvstr(q);
3844 /* now extract the issuer, remember p was at the dollar sign */
3846 end = assertion->bv_val+assertion->bv_len-1;
3847 while (ASCII_SPACE(*begin))
3849 /* should we trim spaces at the end too? is it safe always? */
3851 q = ch_malloc( (end-begin+1)+1 );
3852 AC_MEMCPY( q, begin, end-begin+1 );
3853 q[end-begin+1] = '\0';
3854 *issuer_dn = ber_bvstr(dn_normalize(q));
3856 return LDAP_SUCCESS;
3860 certificateExactMatch(
3865 struct berval *value,
3866 void *assertedValue )
3869 unsigned char *p = value->bv_val;
3870 struct berval *serial;
3871 struct berval *issuer_dn;
3872 struct berval *asserted_serial;
3873 struct berval *asserted_issuer_dn;
3876 xcert = d2i_X509(NULL, &p, value->bv_len);
3879 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3880 "certificateExactMatch: error parsing cert: %s\n",
3881 ERR_error_string(ERR_get_error(),NULL)));
3883 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
3884 "error parsing cert: %s\n",
3885 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3887 return LDAP_INVALID_SYNTAX;
3890 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3891 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
3895 serial_and_issuer_parse(assertedValue,
3897 &asserted_issuer_dn);
3902 slap_schema.si_syn_integer,
3903 slap_schema.si_mr_integerMatch,
3906 if ( ret == LDAP_SUCCESS ) {
3907 if ( *matchp == 0 ) {
3908 /* We need to normalize everything for dnMatch */
3912 slap_schema.si_syn_distinguishedName,
3913 slap_schema.si_mr_distinguishedNameMatch,
3915 asserted_issuer_dn);
3920 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3921 "certificateExactMatch: %d\n %s $ %s\n %s $ %s\n",
3922 *matchp, serial->bv_val, issuer_dn->bv_val,
3923 asserted->serial->bv_val, asserted_issuer_dn->bv_val));
3925 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3926 "%d\n\t\"%s $ %s\"\n",
3927 *matchp, serial->bv_val, issuer_dn->bv_val );
3928 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3929 asserted_serial->bv_val, asserted_issuer_dn->bv_val,
3934 ber_bvfree(issuer_dn);
3935 ber_bvfree(asserted_serial);
3936 ber_bvfree(asserted_issuer_dn);
3942 * Index generation function
3943 * We just index the serials, in most scenarios the issuer DN is one of
3944 * a very small set of values.
3946 int certificateExactIndexer(
3951 struct berval *prefix,
3952 struct berval **values,
3953 struct berval ***keysp )
3956 struct berval **keys;
3959 struct berval * serial;
3961 /* we should have at least one value at this point */
3962 assert( values != NULL && values[0] != NULL );
3964 for( i=0; values[i] != NULL; i++ ) {
3965 /* empty -- just count them */
3968 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
3970 for( i=0; values[i] != NULL; i++ ) {
3971 p = values[i]->bv_val;
3972 xcert = d2i_X509(NULL, &p, values[i]->bv_len);
3975 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3976 "certificateExactIndexer: error parsing cert: %s\n",
3977 ERR_error_string(ERR_get_error(),NULL)));
3979 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
3980 "error parsing cert: %s\n",
3981 ERR_error_string(ERR_get_error(),NULL),
3984 /* Do we leak keys on error? */
3985 return LDAP_INVALID_SYNTAX;
3988 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3990 integerNormalize( slap_schema.si_syn_integer,
3995 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3996 "certificateExactIndexer: returning: %s\n",
3999 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4008 return LDAP_SUCCESS;
4011 /* Index generation function */
4012 /* We think this is always called with a value in matching rule syntax */
4013 int certificateExactFilter(
4018 struct berval *prefix,
4020 struct berval ***keysp )
4022 struct berval **keys;
4023 struct berval *asserted_serial;
4024 struct berval *asserted_issuer_dn;
4026 serial_and_issuer_parse(assertValue,
4028 &asserted_issuer_dn);
4030 keys = ch_malloc( sizeof( struct berval * ) * 2 );
4031 integerNormalize( syntax, asserted_serial, &keys[0] );
4035 ber_bvfree(asserted_serial);
4036 ber_bvfree(asserted_issuer_dn);
4037 return LDAP_SUCCESS;
4042 check_time_syntax (struct berval *val,
4046 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4047 static int mdays[2][12] = {
4048 /* non-leap years */
4049 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4051 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4054 int part, c, tzoffset, leapyear = 0 ;
4056 if( val->bv_len == 0 ) {
4057 return LDAP_INVALID_SYNTAX;
4060 p = (char *)val->bv_val;
4061 e = p + val->bv_len;
4063 /* Ignore initial whitespace */
4064 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4068 if (e - p < 13 - (2 * start)) {
4069 return LDAP_INVALID_SYNTAX;
4072 for (part = 0; part < 9; part++) {
4076 for (part = start; part < 7; part++) {
4078 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4085 return LDAP_INVALID_SYNTAX;
4087 if (c < 0 || c > 9) {
4088 return LDAP_INVALID_SYNTAX;
4094 return LDAP_INVALID_SYNTAX;
4096 if (c < 0 || c > 9) {
4097 return LDAP_INVALID_SYNTAX;
4102 if (part == 2 || part == 3) {
4105 if (parts[part] < 0) {
4106 return LDAP_INVALID_SYNTAX;
4108 if (parts[part] > ceiling[part]) {
4109 return LDAP_INVALID_SYNTAX;
4113 /* leapyear check for the Gregorian calendar (year>1581) */
4114 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4115 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4120 if (parts[3] > mdays[leapyear][parts[2]]) {
4121 return LDAP_INVALID_SYNTAX;
4126 tzoffset = 0; /* UTC */
4127 } else if (c != '+' && c != '-') {
4128 return LDAP_INVALID_SYNTAX;
4132 } else /* c == '+' */ {
4137 return LDAP_INVALID_SYNTAX;
4140 for (part = 7; part < 9; part++) {
4142 if (c < 0 || c > 9) {
4143 return LDAP_INVALID_SYNTAX;
4148 if (c < 0 || c > 9) {
4149 return LDAP_INVALID_SYNTAX;
4153 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4154 return LDAP_INVALID_SYNTAX;
4159 /* Ignore trailing whitespace */
4160 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4164 return LDAP_INVALID_SYNTAX;
4167 switch ( tzoffset ) {
4168 case -1: /* negativ offset to UTC, ie west of Greenwich */
4169 parts[4] += parts[7];
4170 parts[5] += parts[8];
4171 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4175 c = mdays[leapyear][parts[2]];
4177 if (parts[part] > c) {
4178 parts[part] -= c + 1;
4183 case 1: /* positive offset to UTC, ie east of Greenwich */
4184 parts[4] -= parts[7];
4185 parts[5] -= parts[8];
4186 for (part = 6; --part > 0; ) {
4190 /* first arg to % needs to be non negativ */
4191 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4193 if (parts[part] < 0) {
4194 parts[part] += c + 1;
4199 case 0: /* already UTC */
4203 return LDAP_SUCCESS;
4210 struct berval **normalized )
4215 rc = check_time_syntax(val, 1, parts);
4216 if (rc != LDAP_SUCCESS) {
4221 out = ch_malloc( sizeof(struct berval) );
4223 return LBER_ERROR_MEMORY;
4226 out->bv_val = ch_malloc( 14 );
4227 if ( out->bv_val == NULL ) {
4229 return LBER_ERROR_MEMORY;
4232 sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4233 parts[1], parts[2] + 1, parts[3] + 1,
4234 parts[4], parts[5], parts[6] );
4238 return LDAP_SUCCESS;
4248 return check_time_syntax(in, 1, parts);
4252 generalizedTimeValidate(
4258 return check_time_syntax(in, 0, parts);
4262 generalizedTimeNormalize(
4265 struct berval **normalized )
4270 rc = check_time_syntax(val, 0, parts);
4271 if (rc != LDAP_SUCCESS) {
4276 out = ch_malloc( sizeof(struct berval) );
4278 return LBER_ERROR_MEMORY;
4281 out->bv_val = ch_malloc( 16 );
4282 if ( out->bv_val == NULL ) {
4284 return LBER_ERROR_MEMORY;
4287 sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4288 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4289 parts[4], parts[5], parts[6] );
4293 return LDAP_SUCCESS;
4297 nisNetgroupTripleValidate(
4299 struct berval *val )
4304 if ( val->bv_len == 0 ) {
4305 return LDAP_INVALID_SYNTAX;
4308 p = (char *)val->bv_val;
4309 e = p + val->bv_len;
4311 if ( *p != '(' /*')'*/ ) {
4312 return LDAP_INVALID_SYNTAX;
4315 for ( p++; ( p < e ) && ( *p != ')' ); p++ ) {
4319 return LDAP_INVALID_SYNTAX;
4322 } else if ( !ATTR_CHAR( *p ) ) {
4323 return LDAP_INVALID_SYNTAX;
4327 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4328 return LDAP_INVALID_SYNTAX;
4334 return LDAP_INVALID_SYNTAX;
4337 return LDAP_SUCCESS;
4341 bootParameterValidate(
4343 struct berval *val )
4347 if ( val->bv_len == 0 ) {
4348 return LDAP_INVALID_SYNTAX;
4351 p = (char *)val->bv_val;
4352 e = p + val->bv_len;
4355 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4356 if ( !ATTR_CHAR( *p ) ) {
4357 return LDAP_INVALID_SYNTAX;
4362 return LDAP_INVALID_SYNTAX;
4366 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4367 if ( !ATTR_CHAR( *p ) ) {
4368 return LDAP_INVALID_SYNTAX;
4373 return LDAP_INVALID_SYNTAX;
4377 for ( p++; p < e; p++ ) {
4378 if ( !ATTR_CHAR( *p ) ) {
4379 return LDAP_INVALID_SYNTAX;
4383 return LDAP_SUCCESS;
4386 struct syntax_defs_rec {
4389 slap_syntax_validate_func *sd_validate;
4390 slap_syntax_transform_func *sd_normalize;
4391 slap_syntax_transform_func *sd_pretty;
4392 #ifdef SLAPD_BINARY_CONVERSION
4393 slap_syntax_transform_func *sd_ber2str;
4394 slap_syntax_transform_func *sd_str2ber;
4398 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4399 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4401 struct syntax_defs_rec syntax_defs[] = {
4402 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
4403 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4404 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4405 0, NULL, NULL, NULL},
4406 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4407 0, NULL, NULL, NULL},
4408 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
4409 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4410 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_NOT_H_R ")",
4411 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4412 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4413 0, bitStringValidate, bitStringNormalize, NULL },
4414 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4415 0, booleanValidate, NULL, NULL},
4416 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4417 X_BINARY X_NOT_H_R ")",
4418 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4419 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4420 X_BINARY X_NOT_H_R ")",
4421 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4422 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4423 X_BINARY X_NOT_H_R ")",
4424 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4425 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4426 0, countryStringValidate, IA5StringNormalize, NULL},
4427 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4428 0, dnValidate, dnNormalize, dnPretty},
4429 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4430 0, NULL, NULL, NULL},
4431 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4432 0, NULL, NULL, NULL},
4433 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4434 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4435 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4436 0, NULL, NULL, NULL},
4437 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4438 0, NULL, NULL, NULL},
4439 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4440 0, NULL, NULL, NULL},
4441 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4442 0, NULL, NULL, NULL},
4443 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4444 0, NULL, NULL, NULL},
4445 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4446 0, printablesStringValidate, IA5StringNormalize, NULL},
4447 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4448 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4449 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4450 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4451 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4452 0, NULL, NULL, NULL},
4453 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4454 0, IA5StringValidate, IA5StringNormalize, NULL},
4455 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4456 0, integerValidate, integerNormalize, NULL},
4457 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4458 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4459 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4460 0, NULL, NULL, NULL},
4461 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4462 0, NULL, NULL, NULL},
4463 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4464 0, NULL, NULL, NULL},
4465 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4466 0, NULL, NULL, NULL},
4467 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4468 0, NULL, NULL, NULL},
4469 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4470 0, nameUIDValidate, nameUIDNormalize, NULL},
4471 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4472 0, NULL, NULL, NULL},
4473 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4474 0, numericStringValidate, numericStringNormalize, NULL},
4475 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4476 0, NULL, NULL, NULL},
4477 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4478 0, oidValidate, NULL, NULL},
4479 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4480 0, IA5StringValidate, IA5StringNormalize, NULL},
4481 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4482 0, blobValidate, NULL, NULL},
4483 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4484 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4485 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4486 0, NULL, NULL, NULL},
4487 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4488 0, NULL, NULL, NULL},
4489 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4490 0, printableStringValidate, IA5StringNormalize, NULL},
4491 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4492 X_BINARY X_NOT_H_R ")",
4493 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4494 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4495 0, printableStringValidate, IA5StringNormalize, NULL},
4496 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4497 0, NULL, NULL, NULL},
4498 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4499 0, printablesStringValidate, IA5StringNormalize, NULL},
4500 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4501 0, utcTimeValidate, utcTimeNormalize, NULL},
4502 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4503 0, NULL, NULL, NULL},
4504 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4505 0, NULL, NULL, NULL},
4506 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4507 0, NULL, NULL, NULL},
4508 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4509 0, NULL, NULL, NULL},
4510 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4511 0, NULL, NULL, NULL},
4513 /* RFC 2307 NIS Syntaxes */
4514 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4515 0, nisNetgroupTripleValidate, NULL, NULL},
4516 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4517 0, bootParameterValidate, NULL, NULL},
4521 /* These OIDs are not published yet, but will be in the next
4522 * I-D for PKIX LDAPv3 schema as have been advanced by David
4523 * Chadwick in private mail.
4525 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4526 0, NULL, NULL, NULL},
4529 /* OpenLDAP Experimental Syntaxes */
4530 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4532 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4535 /* needs updating */
4536 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4537 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4539 /* OpenLDAP Void Syntax */
4540 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4541 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4542 {NULL, 0, NULL, NULL, NULL}
4545 struct mrule_defs_rec {
4547 slap_mask_t mrd_usage;
4548 slap_mr_convert_func * mrd_convert;
4549 slap_mr_normalize_func * mrd_normalize;
4550 slap_mr_match_func * mrd_match;
4551 slap_mr_indexer_func * mrd_indexer;
4552 slap_mr_filter_func * mrd_filter;
4554 char * mrd_associated;
4558 * Other matching rules in X.520 that we do not use (yet):
4560 * 2.5.13.9 numericStringOrderingMatch
4561 * 2.5.13.15 integerOrderingMatch
4562 * 2.5.13.18 octetStringOrderingMatch
4563 * 2.5.13.19 octetStringSubstringsMatch
4564 * 2.5.13.25 uTCTimeMatch
4565 * 2.5.13.26 uTCTimeOrderingMatch
4566 * 2.5.13.31 directoryStringFirstComponentMatch
4567 * 2.5.13.32 wordMatch
4568 * 2.5.13.33 keywordMatch
4569 * 2.5.13.35 certificateMatch
4570 * 2.5.13.36 certificatePairExactMatch
4571 * 2.5.13.37 certificatePairMatch
4572 * 2.5.13.38 certificateListExactMatch
4573 * 2.5.13.39 certificateListMatch
4574 * 2.5.13.40 algorithmIdentifierMatch
4575 * 2.5.13.41 storedPrefixMatch
4576 * 2.5.13.42 attributeCertificateMatch
4577 * 2.5.13.43 readerAndKeyIDMatch
4578 * 2.5.13.44 attributeIntegrityMatch
4581 struct mrule_defs_rec mrule_defs[] = {
4583 * EQUALITY matching rules must be listed after associated APPROX
4584 * matching rules. So, we list all APPROX matching rules first.
4586 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4587 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4588 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4590 directoryStringApproxMatch,
4591 directoryStringApproxIndexer,
4592 directoryStringApproxFilter,
4595 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4596 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4597 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4599 IA5StringApproxMatch,
4600 IA5StringApproxIndexer,
4601 IA5StringApproxFilter,
4605 * Other matching rules
4608 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4609 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4610 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4612 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4615 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4616 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4617 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4619 dnMatch, dnIndexer, dnFilter,
4622 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4623 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4624 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4626 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4627 directoryStringApproxMatchOID },
4629 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4630 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4633 caseIgnoreOrderingMatch, NULL, NULL,
4636 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4637 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4638 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4640 caseExactIgnoreSubstringsMatch,
4641 caseExactIgnoreSubstringsIndexer,
4642 caseExactIgnoreSubstringsFilter,
4645 {"( 2.5.13.5 NAME 'caseExactMatch' "
4646 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4647 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4649 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4650 directoryStringApproxMatchOID },
4652 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4653 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4656 caseExactOrderingMatch, NULL, NULL,
4659 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4660 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4661 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4663 caseExactIgnoreSubstringsMatch,
4664 caseExactIgnoreSubstringsIndexer,
4665 caseExactIgnoreSubstringsFilter,
4668 {"( 2.5.13.8 NAME 'numericStringMatch' "
4669 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4670 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4673 caseIgnoreIA5Indexer,
4674 caseIgnoreIA5Filter,
4677 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4678 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4679 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4681 caseIgnoreIA5SubstringsMatch,
4682 caseIgnoreIA5SubstringsIndexer,
4683 caseIgnoreIA5SubstringsFilter,
4686 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4687 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4688 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4690 caseIgnoreListMatch, NULL, NULL,
4693 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4694 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4695 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4697 caseIgnoreListSubstringsMatch, NULL, NULL,
4700 {"( 2.5.13.13 NAME 'booleanMatch' "
4701 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4702 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4704 booleanMatch, NULL, NULL,
4707 {"( 2.5.13.14 NAME 'integerMatch' "
4708 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4709 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4711 integerMatch, integerIndexer, integerFilter,
4714 {"( 2.5.13.16 NAME 'bitStringMatch' "
4715 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4716 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4718 bitStringMatch, bitStringIndexer, bitStringFilter,
4721 {"( 2.5.13.17 NAME 'octetStringMatch' "
4722 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4723 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4725 octetStringMatch, octetStringIndexer, octetStringFilter,
4728 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4729 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4730 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4732 telephoneNumberMatch,
4733 telephoneNumberIndexer,
4734 telephoneNumberFilter,
4737 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4738 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4739 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4741 telephoneNumberSubstringsMatch,
4742 telephoneNumberSubstringsIndexer,
4743 telephoneNumberSubstringsFilter,
4746 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4747 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4748 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4753 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4754 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4755 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4757 uniqueMemberMatch, NULL, NULL,
4760 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4761 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4762 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4764 protocolInformationMatch, NULL, NULL,
4767 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4768 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4769 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4771 generalizedTimeMatch, NULL, NULL,
4774 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4775 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4778 generalizedTimeOrderingMatch, NULL, NULL,
4781 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4782 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4783 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4785 integerFirstComponentMatch, NULL, NULL,
4788 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4789 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4790 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4792 objectIdentifierFirstComponentMatch, NULL, NULL,
4796 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4797 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4798 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4799 certificateExactConvert, NULL,
4800 certificateExactMatch,
4801 certificateExactIndexer, certificateExactFilter,
4805 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4806 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4807 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4809 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4810 IA5StringApproxMatchOID },
4812 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4813 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4814 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4816 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4817 IA5StringApproxMatchOID },
4819 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4820 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4823 caseIgnoreIA5SubstringsMatch,
4824 caseIgnoreIA5SubstringsIndexer,
4825 caseIgnoreIA5SubstringsFilter,
4828 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4829 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4832 caseExactIA5SubstringsMatch,
4833 caseExactIA5SubstringsIndexer,
4834 caseExactIA5SubstringsFilter,
4837 /* needs updating */
4838 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4839 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4842 authPasswordMatch, NULL, NULL,
4845 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4846 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4849 OpenLDAPaciMatch, NULL, NULL,
4852 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4853 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4856 integerBitAndMatch, NULL, NULL,
4859 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4860 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4863 integerBitOrMatch, NULL, NULL,
4866 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
4875 /* we should only be called once (from main) */
4876 assert( schema_init_done == 0 );
4878 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4879 res = register_syntax( syntax_defs[i].sd_desc,
4880 syntax_defs[i].sd_flags,
4881 syntax_defs[i].sd_validate,
4882 syntax_defs[i].sd_normalize,
4883 syntax_defs[i].sd_pretty
4884 #ifdef SLAPD_BINARY_CONVERSION
4886 syntax_defs[i].sd_ber2str,
4887 syntax_defs[i].sd_str2ber
4892 fprintf( stderr, "schema_init: Error registering syntax %s\n",
4893 syntax_defs[i].sd_desc );
4898 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4899 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
4901 "schema_init: Ingoring unusable matching rule %s\n",
4902 mrule_defs[i].mrd_desc );
4906 res = register_matching_rule(
4907 mrule_defs[i].mrd_desc,
4908 mrule_defs[i].mrd_usage,
4909 mrule_defs[i].mrd_convert,
4910 mrule_defs[i].mrd_normalize,
4911 mrule_defs[i].mrd_match,
4912 mrule_defs[i].mrd_indexer,
4913 mrule_defs[i].mrd_filter,
4914 mrule_defs[i].mrd_associated );
4918 "schema_init: Error registering matching rule %s\n",
4919 mrule_defs[i].mrd_desc );
4923 schema_init_done = 1;
4924 return LDAP_SUCCESS;
4928 schema_destroy( void )