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 );
266 * Add schema-aware normalization stuff
268 for ( iRDN = 0; dn[ iRDN ]; iRDN++ ) {
269 LDAPRDN *rdn = dn[ iRDN ][ 0 ];
272 for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) {
273 LDAPAVA *ava = rdn[ iAVA ][ 0 ];
274 AttributeDescription *ad = NULL;
275 const char *text = NULL;
276 slap_syntax_transform_func *nf = NULL;
277 struct berval *bv = NULL;
279 rc = slap_bv2ad( ava->la_attr, &ad, &text );
280 if ( rc != LDAP_SUCCESS ) {
285 * FIXME: is this required?
287 if ( isalpha( ava->la_attr->bv_val[0] ) ) {
288 (void) ldap_pvt_str2upper( ava->la_attr->bv_val );
292 * FIXME: What is this intended for?
294 nf = ad->ad_type->sat_syntax->ssyn_normalize;
299 rc = ( *nf )( ad->ad_type->sat_syntax,
300 ava->la_value, &bv );
302 if ( rc != LDAP_SUCCESS ) {
307 * FIXME: shouldn't this happen inside
308 * ssyn_normalize if the syntax is case
311 if ( !( ava->la_flags & LDAP_AVA_BINARY ) ) {
312 struct berval *s = bv;
314 bv = ber_bvstr( UTF8normalize( bv,
319 ber_bvfree( ava->la_value );
325 rc = ldap_dn2str( dn, &dn_out, LDAP_DN_FORMAT_LDAPV3 );
327 if ( rc != LDAP_SUCCESS ) {
329 ldapava_free_dn( dn );
330 return( LDAP_INVALID_SYNTAX );
333 ldapava_free_dn( dn );
335 out = ber_bvstr( dn_out );
338 out = ber_bvdup( val );
343 return( LDAP_SUCCESS );
350 struct berval **normalized)
352 struct berval *out = NULL;
354 if ( val->bv_len != 0 ) {
357 unsigned flags = LDAP_DN_FORMAT_LDAPV3;
360 rc = ldap_str2dn( val->bv_val, &dn, flags );
361 if ( rc != LDAP_SUCCESS ) {
362 return( LDAP_INVALID_SYNTAX );
365 flags |= LDAP_DN_PRETTY;
367 rc = ldap_dn2str( dn, &dn_out, flags );
368 ldapava_free_dn( dn );
370 if ( rc != LDAP_SUCCESS ) {
371 return( LDAP_INVALID_SYNTAX );
374 out = ber_bvstr( dn_out );
377 out = ber_bvdup( val );
382 return( LDAP_SUCCESS );
391 struct berval *value,
392 void *assertedValue )
395 struct berval *asserted = (struct berval *) assertedValue;
397 match = value->bv_len - asserted->bv_len;
400 #ifdef USE_DN_NORMALIZE
401 match = strcmp( value->bv_val, asserted->bv_val );
402 fprintf(stderr, "USE_DN_NORMALIZE :(\n");
404 match = strcasecmp( value->bv_val, asserted->bv_val );
405 fprintf(stderr, "!USE_DN_NORMALIZE :)\n");
410 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
411 "dnMatch: %d\n %s\n %s\n", match,
412 value->bv_val, asserted->bv_val ));
414 Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
415 match, value->bv_val, asserted->bv_val );
419 return( LDAP_SUCCESS );
422 #else /* !USE_LDAP_DN_PARSING */
432 if( in->bv_len == 0 ) return LDAP_SUCCESS;
434 dn = ch_strdup( in->bv_val );
437 return LDAP_INVALID_SYNTAX;
439 } else if ( strlen( in->bv_val ) != in->bv_len ) {
440 rc = LDAP_INVALID_SYNTAX;
442 } else if ( dn_validate( dn ) == NULL ) {
443 rc = LDAP_INVALID_SYNTAX;
457 struct berval **normalized )
461 if ( val->bv_len != 0 ) {
463 out = ber_bvstr( UTF8normalize( val, UTF8_CASEFOLD ) );
465 dn = dn_validate( out->bv_val );
469 return LDAP_INVALID_SYNTAX;
473 out->bv_len = strlen( dn );
475 out = ber_bvdup( val );
488 struct berval *value,
489 void *assertedValue )
492 struct berval *asserted = (struct berval *) assertedValue;
494 match = value->bv_len - asserted->bv_len;
497 #ifdef USE_DN_NORMALIZE
498 match = strcmp( value->bv_val, asserted->bv_val );
500 match = strcasecmp( value->bv_val, asserted->bv_val );
505 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
506 "dnMatch: %d\n %s\n %s\n", match,
507 value->bv_val, asserted->bv_val ));
509 Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
510 match, value->bv_val, asserted->bv_val );
518 #endif /* !USE_LDAP_DN_PARSING */
528 if( in->bv_len == 0 ) return LDAP_SUCCESS;
530 dn = ber_bvdup( in );
532 if( dn->bv_val[dn->bv_len-1] == '\'' ) {
533 /* assume presence of optional UID */
536 for(i=dn->bv_len-2; i>2; i--) {
537 if( dn->bv_val[i] != '0' && dn->bv_val[i] != '1' ) {
541 if( dn->bv_val[i] != '\'' ||
542 dn->bv_val[i-1] != 'B' ||
543 dn->bv_val[i-2] != '#' ) {
545 return LDAP_INVALID_SYNTAX;
548 /* trim the UID to allow use of dn_validate */
549 dn->bv_val[i-2] = '\0';
552 rc = dn_validate( dn->bv_val ) == NULL
553 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
563 struct berval **normalized )
565 struct berval *out = ber_bvdup( val );
567 if( out->bv_len != 0 ) {
571 ber_len_t uidlen = 0;
573 if( out->bv_val[out->bv_len-1] == '\'' ) {
574 /* assume presence of optional UID */
575 uid = strrchr( out->bv_val, '#' );
579 return LDAP_INVALID_SYNTAX;
582 uidlen = out->bv_len - (out->bv_val - uid);
583 /* temporarily trim the UID */
587 #ifdef USE_DN_NORMALIZE
588 dn = dn_normalize( out->bv_val );
590 dn = dn_validate( out->bv_val );
595 return LDAP_INVALID_SYNTAX;
601 /* restore the separator */
604 SAFEMEMCPY( &dn[dnlen], uid, uidlen );
608 out->bv_len = dnlen + uidlen;
620 /* any value allowed */
629 /* any value allowed */
640 /* very unforgiving validation, requires no normalization
641 * before simplistic matching
643 if( in->bv_len < 3 ) {
644 return LDAP_INVALID_SYNTAX;
648 * rfc 2252 section 6.3 Bit String
649 * bitstring = "'" *binary-digit "'"
650 * binary-digit = "0" / "1"
651 * example: '0101111101'B
654 if( in->bv_val[0] != '\'' ||
655 in->bv_val[in->bv_len-2] != '\'' ||
656 in->bv_val[in->bv_len-1] != 'B' )
658 return LDAP_INVALID_SYNTAX;
661 for( i=in->bv_len-3; i>0; i-- ) {
662 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
663 return LDAP_INVALID_SYNTAX;
674 struct berval **normalized )
677 * A normalized bitString is has no extaneous (leading) zero bits.
678 * That is, '00010'B is normalized to '10'B
679 * However, as a special case, '0'B requires no normalization.
681 struct berval *newval;
684 /* start at the first bit */
687 /* Find the first non-zero bit */
688 while ( *p == '0' ) p++;
690 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
693 /* no non-zero bits */
694 newval->bv_val = ch_strdup("\'0\'B");
695 newval->bv_len = sizeof("\'0\'B") - 1;
699 newval->bv_val = ch_malloc( val->bv_len + 1 );
701 newval->bv_val[0] = '\'';
704 for( ; *p != '\0'; p++ ) {
705 newval->bv_val[newval->bv_len++] = *p;
708 newval->bv_val[newval->bv_len] = '\0';
711 *normalized = newval;
716 * Handling boolean syntax and matching is quite rigid.
717 * A more flexible approach would be to allow a variety
718 * of strings to be normalized and prettied into TRUE
726 /* very unforgiving validation, requires no normalization
727 * before simplistic matching
730 if( in->bv_len == 4 ) {
731 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
734 } else if( in->bv_len == 5 ) {
735 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
740 return LDAP_INVALID_SYNTAX;
749 struct berval *value,
750 void *assertedValue )
752 /* simplistic matching allowed by rigid validation */
753 struct berval *asserted = (struct berval *) assertedValue;
754 *matchp = value->bv_len != asserted->bv_len;
765 unsigned char *u = in->bv_val;
767 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
769 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
770 /* get the length indicated by the first byte */
771 len = LDAP_UTF8_CHARLEN( u );
773 /* should not be zero */
774 if( len == 0 ) return LDAP_INVALID_SYNTAX;
776 /* make sure len corresponds with the offset
777 to the next character */
778 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
781 if( count != 0 ) return LDAP_INVALID_SYNTAX;
790 struct berval **normalized )
792 struct berval *newval;
795 newval = ch_malloc( sizeof( struct berval ) );
799 /* Ignore initial whitespace */
800 while ( ldap_utf8_isspace( p ) ) {
806 return LDAP_INVALID_SYNTAX;
809 newval->bv_val = ch_strdup( p );
810 p = q = newval->bv_val;
816 if ( ldap_utf8_isspace( p ) ) {
817 len = LDAP_UTF8_COPY(q,p);
822 /* Ignore the extra whitespace */
823 while ( ldap_utf8_isspace( p ) ) {
827 len = LDAP_UTF8_COPY(q,p);
834 assert( *newval->bv_val );
835 assert( newval->bv_val < p );
838 /* cannot start with a space */
839 assert( !ldap_utf8_isspace(newval->bv_val) );
842 * If the string ended in space, backup the pointer one
843 * position. One is enough because the above loop collapsed
844 * all whitespace to a single space.
851 /* cannot end with a space */
852 assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
857 newval->bv_len = q - newval->bv_val;
858 *normalized = newval;
863 /* Returns Unicode cannonically normalized copy of a substring assertion
864 * Skipping attribute description */
865 SubstringsAssertion *
866 UTF8SubstringsassertionNormalize(
867 SubstringsAssertion *sa,
870 SubstringsAssertion *nsa;
873 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
878 if( sa->sa_initial != NULL ) {
879 nsa->sa_initial = ber_bvstr( UTF8normalize( sa->sa_initial, casefold ) );
880 if( nsa->sa_initial == NULL ) {
885 if( sa->sa_any != NULL ) {
886 for( i=0; sa->sa_any[i] != NULL; i++ ) {
889 nsa->sa_any = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
890 for( i=0; sa->sa_any[i] != NULL; i++ ) {
891 nsa->sa_any[i] = ber_bvstr( UTF8normalize( sa->sa_any[i], casefold ) );
892 if( nsa->sa_any[i] == NULL ) {
896 nsa->sa_any[i] = NULL;
899 if( sa->sa_final != NULL ) {
900 nsa->sa_final = ber_bvstr( UTF8normalize( sa->sa_final, casefold ) );
901 if( nsa->sa_final == NULL ) {
909 ber_bvfree( nsa->sa_final );
910 ber_bvecfree( nsa->sa_any );
911 ber_bvfree( nsa->sa_initial );
916 /* Strip characters with the 8th bit set */
929 while( *++q & 0x80 ) {
932 p = memmove(p, q, strlen(q) + 1);
940 #ifndef SLAPD_APPROX_OLDSINGLESTRING
942 #if defined(SLAPD_APPROX_INITIALS)
943 #define SLAPD_APPROX_DELIMITER "._ "
944 #define SLAPD_APPROX_WORDLEN 2
946 #define SLAPD_APPROX_DELIMITER " "
947 #define SLAPD_APPROX_WORDLEN 1
956 struct berval *value,
957 void *assertedValue )
959 char *val, *nval, *assertv, **values, **words, *c;
960 int i, count, len, nextchunk=0, nextavail=0;
963 /* Yes, this is necessary */
964 nval = UTF8normalize( value, UTF8_NOCASEFOLD );
969 strip8bitChars( nval );
971 /* Yes, this is necessary */
972 assertv = UTF8normalize( ((struct berval *)assertedValue),
974 if( assertv == NULL ) {
979 strip8bitChars( assertv );
980 avlen = strlen( assertv );
982 /* Isolate how many words there are */
983 for( c=nval,count=1; *c; c++ ) {
984 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
985 if ( c == NULL ) break;
990 /* Get a phonetic copy of each word */
991 words = (char **)ch_malloc( count * sizeof(char *) );
992 values = (char **)ch_malloc( count * sizeof(char *) );
993 for( c=nval,i=0; i<count; i++,c+=strlen(c)+1 ) {
995 values[i] = phonetic(c);
998 /* Work through the asserted value's words, to see if at least some
999 of the words are there, in the same order. */
1001 while ( nextchunk < avlen ) {
1002 len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER);
1007 #if defined(SLAPD_APPROX_INITIALS)
1008 else if( len == 1 ) {
1009 /* Single letter words need to at least match one word's initial */
1010 for( i=nextavail; i<count; i++ )
1011 if( !strncasecmp( assertv+nextchunk, words[i], 1 )) {
1018 /* Isolate the next word in the asserted value and phonetic it */
1019 assertv[nextchunk+len] = '\0';
1020 val = phonetic( assertv + nextchunk );
1022 /* See if this phonetic chunk is in the remaining words of *value */
1023 for( i=nextavail; i<count; i++ ){
1024 if( !strcmp( val, values[i] ) ){
1032 /* This chunk in the asserted value was NOT within the *value. */
1038 /* Go on to the next word in the asserted value */
1042 /* If some of the words were seen, call it a match */
1043 if( nextavail > 0 ) {
1050 /* Cleanup allocs */
1052 for( i=0; i<count; i++ ) {
1053 ch_free( values[i] );
1059 return LDAP_SUCCESS;
1068 struct berval *prefix,
1069 struct berval **values,
1070 struct berval ***keysp )
1073 int i,j, len, wordcount, keycount=0;
1074 struct berval **newkeys, **keys=NULL;
1076 for( j=0; values[j] != NULL; j++ ) {
1077 /* Yes, this is necessary */
1078 val = UTF8normalize( values[j], UTF8_NOCASEFOLD );
1079 strip8bitChars( val );
1081 /* Isolate how many words there are. There will be a key for each */
1082 for( wordcount=0,c=val; *c; c++) {
1083 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1084 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1086 if (*c == '\0') break;
1090 /* Allocate/increase storage to account for new keys */
1091 newkeys = (struct berval **)ch_malloc( (keycount + wordcount + 1)
1092 * sizeof(struct berval *) );
1093 memcpy( newkeys, keys, keycount * sizeof(struct berval *) );
1094 if( keys ) ch_free( keys );
1097 /* Get a phonetic copy of each word */
1098 for( c=val,i=0; i<wordcount; c+=len+1 ) {
1100 if( len < SLAPD_APPROX_WORDLEN ) continue;
1101 keys[keycount] = (struct berval *)ch_malloc( sizeof(struct berval) );
1102 keys[keycount]->bv_val = phonetic( c );
1103 keys[keycount]->bv_len = strlen( keys[keycount]->bv_val );
1110 keys[keycount] = NULL;
1113 return LDAP_SUCCESS;
1122 struct berval *prefix,
1124 struct berval ***keysp )
1128 struct berval **keys;
1130 /* Yes, this is necessary */
1131 val = UTF8normalize( ((struct berval *)assertValue),
1134 keys = (struct berval **)ch_malloc( sizeof(struct berval *) );
1137 return LDAP_SUCCESS;
1139 strip8bitChars( val );
1141 /* Isolate how many words there are. There will be a key for each */
1142 for( count=0,c=val; *c; c++) {
1143 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1144 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1146 if (*c == '\0') break;
1150 /* Allocate storage for new keys */
1151 keys = (struct berval **)ch_malloc( (count + 1) * sizeof(struct berval *) );
1153 /* Get a phonetic copy of each word */
1154 for( c=val,i=0; i<count; c+=len+1 ) {
1156 if( len < SLAPD_APPROX_WORDLEN ) continue;
1157 keys[i] = ber_bvstr( phonetic( c ) );
1166 return LDAP_SUCCESS;
1171 /* No other form of Approximate Matching is defined */
1179 struct berval *value,
1180 void *assertedValue )
1182 char *vapprox, *avapprox;
1185 /* Yes, this is necessary */
1186 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1189 return LDAP_SUCCESS;
1192 /* Yes, this is necessary */
1193 t = UTF8normalize( ((struct berval *)assertedValue),
1198 return LDAP_SUCCESS;
1201 vapprox = phonetic( strip8bitChars( s ) );
1202 avapprox = phonetic( strip8bitChars( t ) );
1207 *matchp = strcmp( vapprox, avapprox );
1210 ch_free( avapprox );
1212 return LDAP_SUCCESS;
1221 struct berval *prefix,
1222 struct berval **values,
1223 struct berval ***keysp )
1226 struct berval **keys;
1229 for( i=0; values[i] != NULL; i++ ) {
1230 /* empty - just count them */
1233 /* we should have at least one value at this point */
1236 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * (i+1) );
1238 /* Copy each value and run it through phonetic() */
1239 for( i=0; values[i] != NULL; i++ ) {
1240 /* Yes, this is necessary */
1241 s = UTF8normalize( values[i], UTF8_NOCASEFOLD );
1243 /* strip 8-bit chars and run through phonetic() */
1244 keys[i] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1250 return LDAP_SUCCESS;
1260 struct berval *prefix,
1262 struct berval ***keysp )
1264 struct berval **keys;
1267 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * 2 );
1269 /* Yes, this is necessary */
1270 s = UTF8normalize( ((struct berval *)assertValue),
1275 /* strip 8-bit chars and run through phonetic() */
1276 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1282 return LDAP_SUCCESS;
1293 struct berval *value,
1294 void *assertedValue )
1296 *matchp = UTF8normcmp( value->bv_val,
1297 ((struct berval *) assertedValue)->bv_val,
1299 return LDAP_SUCCESS;
1303 caseExactIgnoreSubstringsMatch(
1308 struct berval *value,
1309 void *assertedValue )
1312 SubstringsAssertion *sub = NULL;
1316 char *nav, casefold;
1318 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1319 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1321 nav = UTF8normalize( value, casefold );
1327 left.bv_len = strlen( nav );
1329 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1335 /* Add up asserted input length */
1336 if( sub->sa_initial ) {
1337 inlen += sub->sa_initial->bv_len;
1340 for(i=0; sub->sa_any[i] != NULL; i++) {
1341 inlen += sub->sa_any[i]->bv_len;
1344 if( sub->sa_final ) {
1345 inlen += sub->sa_final->bv_len;
1348 if( sub->sa_initial ) {
1349 if( inlen > left.bv_len ) {
1354 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
1355 sub->sa_initial->bv_len );
1361 left.bv_val += sub->sa_initial->bv_len;
1362 left.bv_len -= sub->sa_initial->bv_len;
1363 inlen -= sub->sa_initial->bv_len;
1366 if( sub->sa_final ) {
1367 if( inlen > left.bv_len ) {
1372 match = strncmp( sub->sa_final->bv_val,
1373 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
1374 sub->sa_final->bv_len );
1380 left.bv_len -= sub->sa_final->bv_len;
1381 inlen -= sub->sa_final->bv_len;
1385 for(i=0; sub->sa_any[i]; i++) {
1390 if( inlen > left.bv_len ) {
1391 /* not enough length */
1396 if( sub->sa_any[i]->bv_len == 0 ) {
1400 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
1407 idx = p - left.bv_val;
1408 assert( idx < left.bv_len );
1410 if( idx >= left.bv_len ) {
1411 /* this shouldn't happen */
1413 ch_free( sub->sa_final );
1414 ber_bvecfree( sub->sa_any );
1415 ch_free( sub->sa_initial );
1423 if( sub->sa_any[i]->bv_len > left.bv_len ) {
1424 /* not enough left */
1429 match = strncmp( left.bv_val,
1430 sub->sa_any[i]->bv_val,
1431 sub->sa_any[i]->bv_len );
1439 left.bv_val += sub->sa_any[i]->bv_len;
1440 left.bv_len -= sub->sa_any[i]->bv_len;
1441 inlen -= sub->sa_any[i]->bv_len;
1448 ber_bvfree( sub->sa_final );
1449 ber_bvecfree( sub->sa_any );
1450 ber_bvfree( sub->sa_initial );
1454 return LDAP_SUCCESS;
1457 /* Index generation function */
1458 int caseExactIgnoreIndexer(
1463 struct berval *prefix,
1464 struct berval **values,
1465 struct berval ***keysp )
1470 struct berval **keys;
1471 HASH_CONTEXT HASHcontext;
1472 unsigned char HASHdigest[HASH_BYTES];
1473 struct berval digest;
1474 digest.bv_val = HASHdigest;
1475 digest.bv_len = sizeof(HASHdigest);
1477 for( i=0; values[i] != NULL; i++ ) {
1478 /* empty - just count them */
1481 /* we should have at least one value at this point */
1484 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
1486 slen = strlen( syntax->ssyn_oid );
1487 mlen = strlen( mr->smr_oid );
1489 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1490 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1492 for( i=0; values[i] != NULL; i++ ) {
1493 struct berval *value;
1494 value = ber_bvstr( UTF8normalize( values[i],
1497 HASH_Init( &HASHcontext );
1498 if( prefix != NULL && prefix->bv_len > 0 ) {
1499 HASH_Update( &HASHcontext,
1500 prefix->bv_val, prefix->bv_len );
1502 HASH_Update( &HASHcontext,
1503 syntax->ssyn_oid, slen );
1504 HASH_Update( &HASHcontext,
1505 mr->smr_oid, mlen );
1506 HASH_Update( &HASHcontext,
1507 value->bv_val, value->bv_len );
1508 HASH_Final( HASHdigest, &HASHcontext );
1510 ber_bvfree( value );
1512 keys[i] = ber_bvdup( &digest );
1517 return LDAP_SUCCESS;
1520 /* Index generation function */
1521 int caseExactIgnoreFilter(
1526 struct berval *prefix,
1528 struct berval ***keysp )
1532 struct berval **keys;
1533 HASH_CONTEXT HASHcontext;
1534 unsigned char HASHdigest[HASH_BYTES];
1535 struct berval *value;
1536 struct berval digest;
1537 digest.bv_val = HASHdigest;
1538 digest.bv_len = sizeof(HASHdigest);
1540 slen = strlen( syntax->ssyn_oid );
1541 mlen = strlen( mr->smr_oid );
1543 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1544 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1546 value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue),
1548 /* This usually happens if filter contains bad UTF8 */
1549 if( value == NULL ) {
1550 keys = ch_malloc( sizeof( struct berval * ) );
1552 return LDAP_SUCCESS;
1555 keys = ch_malloc( sizeof( struct berval * ) * 2 );
1557 HASH_Init( &HASHcontext );
1558 if( prefix != NULL && prefix->bv_len > 0 ) {
1559 HASH_Update( &HASHcontext,
1560 prefix->bv_val, prefix->bv_len );
1562 HASH_Update( &HASHcontext,
1563 syntax->ssyn_oid, slen );
1564 HASH_Update( &HASHcontext,
1565 mr->smr_oid, mlen );
1566 HASH_Update( &HASHcontext,
1567 value->bv_val, value->bv_len );
1568 HASH_Final( HASHdigest, &HASHcontext );
1570 keys[0] = ber_bvdup( &digest );
1573 ber_bvfree( value );
1576 return LDAP_SUCCESS;
1579 /* Substrings Index generation function */
1580 int caseExactIgnoreSubstringsIndexer(
1585 struct berval *prefix,
1586 struct berval **values,
1587 struct berval ***keysp )
1592 struct berval **keys;
1593 struct berval **nvalues;
1595 HASH_CONTEXT HASHcontext;
1596 unsigned char HASHdigest[HASH_BYTES];
1597 struct berval digest;
1598 digest.bv_val = HASHdigest;
1599 digest.bv_len = sizeof(HASHdigest);
1603 for( i=0; values[i] != NULL; i++ ) {
1604 /* empty - just count them */
1607 /* we should have at least one value at this point */
1610 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1611 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1613 nvalues = ch_malloc( sizeof( struct berval * ) * (i+1) );
1614 for( i=0; values[i] != NULL; i++ ) {
1615 nvalues[i] = ber_bvstr( UTF8normalize( values[i],
1621 for( i=0; values[i] != NULL; i++ ) {
1622 /* count number of indices to generate */
1623 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1627 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1628 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1629 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1630 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1632 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1636 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1637 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1638 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1642 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1643 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1644 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1645 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1647 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1653 /* no keys to generate */
1655 ber_bvecfree( nvalues );
1656 return LDAP_SUCCESS;
1659 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1661 slen = strlen( syntax->ssyn_oid );
1662 mlen = strlen( mr->smr_oid );
1665 for( i=0; values[i] != NULL; i++ ) {
1667 struct berval *value;
1669 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1673 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1674 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1676 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1677 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1679 for( j=0; j<max; j++ ) {
1680 HASH_Init( &HASHcontext );
1681 if( prefix != NULL && prefix->bv_len > 0 ) {
1682 HASH_Update( &HASHcontext,
1683 prefix->bv_val, prefix->bv_len );
1686 HASH_Update( &HASHcontext,
1687 &pre, sizeof( pre ) );
1688 HASH_Update( &HASHcontext,
1689 syntax->ssyn_oid, slen );
1690 HASH_Update( &HASHcontext,
1691 mr->smr_oid, mlen );
1692 HASH_Update( &HASHcontext,
1694 SLAP_INDEX_SUBSTR_MAXLEN );
1695 HASH_Final( HASHdigest, &HASHcontext );
1697 keys[nkeys++] = ber_bvdup( &digest );
1701 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1702 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1704 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1707 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1708 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1709 HASH_Init( &HASHcontext );
1710 if( prefix != NULL && prefix->bv_len > 0 ) {
1711 HASH_Update( &HASHcontext,
1712 prefix->bv_val, prefix->bv_len );
1714 HASH_Update( &HASHcontext,
1715 &pre, sizeof( pre ) );
1716 HASH_Update( &HASHcontext,
1717 syntax->ssyn_oid, slen );
1718 HASH_Update( &HASHcontext,
1719 mr->smr_oid, mlen );
1720 HASH_Update( &HASHcontext,
1722 HASH_Final( HASHdigest, &HASHcontext );
1724 keys[nkeys++] = ber_bvdup( &digest );
1727 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1728 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1729 HASH_Init( &HASHcontext );
1730 if( prefix != NULL && prefix->bv_len > 0 ) {
1731 HASH_Update( &HASHcontext,
1732 prefix->bv_val, prefix->bv_len );
1734 HASH_Update( &HASHcontext,
1735 &pre, sizeof( pre ) );
1736 HASH_Update( &HASHcontext,
1737 syntax->ssyn_oid, slen );
1738 HASH_Update( &HASHcontext,
1739 mr->smr_oid, mlen );
1740 HASH_Update( &HASHcontext,
1741 &value->bv_val[value->bv_len-j], j );
1742 HASH_Final( HASHdigest, &HASHcontext );
1744 keys[nkeys++] = ber_bvdup( &digest );
1759 ber_bvecfree( nvalues );
1761 return LDAP_SUCCESS;
1764 int caseExactIgnoreSubstringsFilter(
1769 struct berval *prefix,
1771 struct berval ***keysp )
1773 SubstringsAssertion *sa;
1775 ber_len_t nkeys = 0;
1776 size_t slen, mlen, klen;
1777 struct berval **keys;
1778 HASH_CONTEXT HASHcontext;
1779 unsigned char HASHdigest[HASH_BYTES];
1780 struct berval *value;
1781 struct berval digest;
1783 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1784 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1786 sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
1789 return LDAP_SUCCESS;
1792 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1793 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1798 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1800 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1801 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1802 /* don't bother accounting for stepping */
1803 nkeys += sa->sa_any[i]->bv_len -
1804 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1809 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1810 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1816 ber_bvfree( sa->sa_final );
1817 ber_bvecfree( sa->sa_any );
1818 ber_bvfree( sa->sa_initial );
1821 return LDAP_SUCCESS;
1824 digest.bv_val = HASHdigest;
1825 digest.bv_len = sizeof(HASHdigest);
1827 slen = strlen( syntax->ssyn_oid );
1828 mlen = strlen( mr->smr_oid );
1830 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1833 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1834 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1836 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1837 value = sa->sa_initial;
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, klen );
1855 HASH_Final( HASHdigest, &HASHcontext );
1857 keys[nkeys++] = ber_bvdup( &digest );
1860 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1862 pre = SLAP_INDEX_SUBSTR_PREFIX;
1863 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1865 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1866 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1870 value = sa->sa_any[i];
1873 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1874 j += SLAP_INDEX_SUBSTR_STEP )
1876 HASH_Init( &HASHcontext );
1877 if( prefix != NULL && prefix->bv_len > 0 ) {
1878 HASH_Update( &HASHcontext,
1879 prefix->bv_val, prefix->bv_len );
1881 HASH_Update( &HASHcontext,
1882 &pre, sizeof( pre ) );
1883 HASH_Update( &HASHcontext,
1884 syntax->ssyn_oid, slen );
1885 HASH_Update( &HASHcontext,
1886 mr->smr_oid, mlen );
1887 HASH_Update( &HASHcontext,
1888 &value->bv_val[j], klen );
1889 HASH_Final( HASHdigest, &HASHcontext );
1891 keys[nkeys++] = ber_bvdup( &digest );
1897 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1898 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1900 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1901 value = sa->sa_final;
1903 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1904 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1906 HASH_Init( &HASHcontext );
1907 if( prefix != NULL && prefix->bv_len > 0 ) {
1908 HASH_Update( &HASHcontext,
1909 prefix->bv_val, prefix->bv_len );
1911 HASH_Update( &HASHcontext,
1912 &pre, sizeof( pre ) );
1913 HASH_Update( &HASHcontext,
1914 syntax->ssyn_oid, slen );
1915 HASH_Update( &HASHcontext,
1916 mr->smr_oid, mlen );
1917 HASH_Update( &HASHcontext,
1918 &value->bv_val[value->bv_len-klen], klen );
1919 HASH_Final( HASHdigest, &HASHcontext );
1921 keys[nkeys++] = ber_bvdup( &digest );
1931 ber_bvfree( sa->sa_final );
1932 ber_bvecfree( sa->sa_any );
1933 ber_bvfree( sa->sa_initial );
1936 return LDAP_SUCCESS;
1945 struct berval *value,
1946 void *assertedValue )
1948 *matchp = UTF8normcmp( value->bv_val,
1949 ((struct berval *) assertedValue)->bv_val,
1951 return LDAP_SUCCESS;
1957 struct berval *val )
1961 if( val->bv_len == 0 ) {
1962 /* disallow empty strings */
1963 return LDAP_INVALID_SYNTAX;
1966 if( OID_LEADCHAR(val->bv_val[0]) ) {
1968 for(i=1; i < val->bv_len; i++) {
1969 if( OID_SEPARATOR( val->bv_val[i] ) ) {
1970 if( dot++ ) return 1;
1971 } else if ( OID_CHAR( val->bv_val[i] ) ) {
1974 return LDAP_INVALID_SYNTAX;
1978 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
1980 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
1981 for(i=1; i < val->bv_len; i++) {
1982 if( !DESC_CHAR(val->bv_val[i] ) ) {
1983 return LDAP_INVALID_SYNTAX;
1987 return LDAP_SUCCESS;
1990 return LDAP_INVALID_SYNTAX;
1999 struct berval *value,
2000 void *assertedValue )
2003 int vsign=0, avsign=0;
2004 struct berval *asserted;
2005 ber_len_t vlen, avlen;
2008 /* Start off pessimistic */
2011 /* Skip past leading spaces/zeros, and get the sign of the *value number */
2013 vlen = value->bv_len;
2015 if( ASCII_SPACE(*v) || ( *v == '0' )) {
2016 /* empty -- skip spaces */
2018 else if ( *v == '+' ) {
2021 else if ( *v == '-' ) {
2024 else if ( ASCII_DIGIT(*v) ) {
2025 if ( vsign == 0 ) vsign = 1;
2033 /* Skip past leading spaces/zeros, and get the sign of the *assertedValue
2035 asserted = (struct berval *) assertedValue;
2036 av = asserted->bv_val;
2037 avlen = asserted->bv_len;
2039 if( ASCII_SPACE(*av) || ( *av == '0' )) {
2040 /* empty -- skip spaces */
2042 else if ( *av == '+' ) {
2045 else if ( *av == '-' ) {
2048 else if ( ASCII_DIGIT(*av) ) {
2049 if ( avsign == 0 ) avsign = 1;
2057 /* The two ?sign vars are now one of :
2058 -2 negative non-zero number
2060 0 0 collapse these three to 0
2062 +2 positive non-zero number
2064 if ( abs( vsign ) == 1 ) vsign = 0;
2065 if ( abs( avsign ) == 1 ) avsign = 0;
2067 if( vsign != avsign ) return LDAP_SUCCESS;
2069 /* Check the significant digits */
2070 while( vlen && avlen ) {
2071 if( *v != *av ) break;
2078 /* If all digits compared equal, the numbers are equal */
2079 if(( vlen == 0 ) && ( avlen == 0 )) {
2082 return LDAP_SUCCESS;
2088 struct berval *val )
2092 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2094 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2095 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2096 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2097 return LDAP_INVALID_SYNTAX;
2100 for( i=1; i < val->bv_len; i++ ) {
2101 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2104 return LDAP_SUCCESS;
2111 struct berval **normalized )
2115 struct berval *newval;
2122 /* Ignore leading spaces */
2123 while ( len && ( *p == ' ' )) {
2130 negative = ( *p == '-' );
2131 if(( *p == '-' ) || ( *p == '+' )) {
2137 /* Ignore leading zeros */
2138 while ( len && ( *p == '0' )) {
2143 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
2145 /* If there are no non-zero digits left, the number is zero, otherwise
2146 allocate space for the number and copy it into the buffer */
2148 newval->bv_val = ch_strdup("0");
2152 newval->bv_len = len+negative;
2153 newval->bv_val = ch_malloc( newval->bv_len );
2155 newval->bv_val[0] = '-';
2157 memcpy( newval->bv_val + negative, p, len );
2160 *normalized = newval;
2161 return LDAP_SUCCESS;
2164 /* Index generation function */
2170 struct berval *prefix,
2171 struct berval **values,
2172 struct berval ***keysp )
2175 struct berval **keys;
2177 /* we should have at least one value at this point */
2178 assert( values != NULL && values[0] != NULL );
2180 for( i=0; values[i] != NULL; i++ ) {
2181 /* empty -- just count them */
2184 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2186 for( i=0; values[i] != NULL; i++ ) {
2187 integerNormalize( syntax, values[i], &keys[i] );
2192 return LDAP_SUCCESS;
2195 /* Index generation function */
2201 struct berval *prefix,
2203 struct berval ***keysp )
2205 struct berval **keys;
2207 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2208 integerNormalize( syntax, assertValue, &keys[0] );
2212 return LDAP_SUCCESS;
2217 countryStringValidate(
2219 struct berval *val )
2221 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2223 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2224 return LDAP_INVALID_SYNTAX;
2226 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2227 return LDAP_INVALID_SYNTAX;
2230 return LDAP_SUCCESS;
2234 printableStringValidate(
2236 struct berval *val )
2240 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2242 for(i=0; i < val->bv_len; i++) {
2243 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2244 return LDAP_INVALID_SYNTAX;
2248 return LDAP_SUCCESS;
2252 printablesStringValidate(
2254 struct berval *val )
2258 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2260 for(i=0; i < val->bv_len; i++) {
2261 if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
2262 return LDAP_INVALID_SYNTAX;
2266 return LDAP_SUCCESS;
2272 struct berval *val )
2276 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2278 for(i=0; i < val->bv_len; i++) {
2279 if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2282 return LDAP_SUCCESS;
2289 struct berval **normalized )
2291 struct berval *newval;
2294 newval = ch_malloc( sizeof( struct berval ) );
2298 /* Ignore initial whitespace */
2299 while ( ASCII_SPACE( *p ) ) {
2305 return LDAP_INVALID_SYNTAX;
2308 newval->bv_val = ch_strdup( p );
2309 p = q = newval->bv_val;
2312 if ( ASCII_SPACE( *p ) ) {
2315 /* Ignore the extra whitespace */
2316 while ( ASCII_SPACE( *p ) ) {
2324 assert( *newval->bv_val );
2325 assert( newval->bv_val < p );
2328 /* cannot start with a space */
2329 assert( !ASCII_SPACE(*newval->bv_val) );
2332 * If the string ended in space, backup the pointer one
2333 * position. One is enough because the above loop collapsed
2334 * all whitespace to a single space.
2337 if ( ASCII_SPACE( q[-1] ) ) {
2341 /* cannot end with a space */
2342 assert( !ASCII_SPACE( q[-1] ) );
2344 /* null terminate */
2347 newval->bv_len = q - newval->bv_val;
2348 *normalized = newval;
2350 return LDAP_SUCCESS;
2359 struct berval *value,
2360 void *assertedValue )
2362 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2365 match = strncmp( value->bv_val,
2366 ((struct berval *) assertedValue)->bv_val,
2371 return LDAP_SUCCESS;
2375 caseExactIA5SubstringsMatch(
2380 struct berval *value,
2381 void *assertedValue )
2384 SubstringsAssertion *sub = assertedValue;
2385 struct berval left = *value;
2389 /* Add up asserted input length */
2390 if( sub->sa_initial ) {
2391 inlen += sub->sa_initial->bv_len;
2394 for(i=0; sub->sa_any[i] != NULL; i++) {
2395 inlen += sub->sa_any[i]->bv_len;
2398 if( sub->sa_final ) {
2399 inlen += sub->sa_final->bv_len;
2402 if( sub->sa_initial ) {
2403 if( inlen > left.bv_len ) {
2408 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
2409 sub->sa_initial->bv_len );
2415 left.bv_val += sub->sa_initial->bv_len;
2416 left.bv_len -= sub->sa_initial->bv_len;
2417 inlen -= sub->sa_initial->bv_len;
2420 if( sub->sa_final ) {
2421 if( inlen > left.bv_len ) {
2426 match = strncmp( sub->sa_final->bv_val,
2427 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2428 sub->sa_final->bv_len );
2434 left.bv_len -= sub->sa_final->bv_len;
2435 inlen -= sub->sa_final->bv_len;
2439 for(i=0; sub->sa_any[i]; i++) {
2444 if( inlen > left.bv_len ) {
2445 /* not enough length */
2450 if( sub->sa_any[i]->bv_len == 0 ) {
2454 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
2461 idx = p - left.bv_val;
2462 assert( idx < left.bv_len );
2464 if( idx >= left.bv_len ) {
2465 /* this shouldn't happen */
2472 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2473 /* not enough left */
2478 match = strncmp( left.bv_val,
2479 sub->sa_any[i]->bv_val,
2480 sub->sa_any[i]->bv_len );
2488 left.bv_val += sub->sa_any[i]->bv_len;
2489 left.bv_len -= sub->sa_any[i]->bv_len;
2490 inlen -= sub->sa_any[i]->bv_len;
2496 return LDAP_SUCCESS;
2499 /* Index generation function */
2500 int caseExactIA5Indexer(
2505 struct berval *prefix,
2506 struct berval **values,
2507 struct berval ***keysp )
2511 struct berval **keys;
2512 HASH_CONTEXT HASHcontext;
2513 unsigned char HASHdigest[HASH_BYTES];
2514 struct berval digest;
2515 digest.bv_val = HASHdigest;
2516 digest.bv_len = sizeof(HASHdigest);
2518 for( i=0; values[i] != NULL; i++ ) {
2519 /* empty - just count them */
2522 /* we should have at least one value at this point */
2525 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2527 slen = strlen( syntax->ssyn_oid );
2528 mlen = strlen( mr->smr_oid );
2530 for( i=0; values[i] != NULL; i++ ) {
2531 struct berval *value = values[i];
2533 HASH_Init( &HASHcontext );
2534 if( prefix != NULL && prefix->bv_len > 0 ) {
2535 HASH_Update( &HASHcontext,
2536 prefix->bv_val, prefix->bv_len );
2538 HASH_Update( &HASHcontext,
2539 syntax->ssyn_oid, slen );
2540 HASH_Update( &HASHcontext,
2541 mr->smr_oid, mlen );
2542 HASH_Update( &HASHcontext,
2543 value->bv_val, value->bv_len );
2544 HASH_Final( HASHdigest, &HASHcontext );
2546 keys[i] = ber_bvdup( &digest );
2551 return LDAP_SUCCESS;
2554 /* Index generation function */
2555 int caseExactIA5Filter(
2560 struct berval *prefix,
2562 struct berval ***keysp )
2565 struct berval **keys;
2566 HASH_CONTEXT HASHcontext;
2567 unsigned char HASHdigest[HASH_BYTES];
2568 struct berval *value;
2569 struct berval digest;
2570 digest.bv_val = HASHdigest;
2571 digest.bv_len = sizeof(HASHdigest);
2573 slen = strlen( syntax->ssyn_oid );
2574 mlen = strlen( mr->smr_oid );
2576 value = (struct berval *) assertValue;
2578 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2580 HASH_Init( &HASHcontext );
2581 if( prefix != NULL && prefix->bv_len > 0 ) {
2582 HASH_Update( &HASHcontext,
2583 prefix->bv_val, prefix->bv_len );
2585 HASH_Update( &HASHcontext,
2586 syntax->ssyn_oid, slen );
2587 HASH_Update( &HASHcontext,
2588 mr->smr_oid, mlen );
2589 HASH_Update( &HASHcontext,
2590 value->bv_val, value->bv_len );
2591 HASH_Final( HASHdigest, &HASHcontext );
2593 keys[0] = ber_bvdup( &digest );
2597 return LDAP_SUCCESS;
2600 /* Substrings Index generation function */
2601 int caseExactIA5SubstringsIndexer(
2606 struct berval *prefix,
2607 struct berval **values,
2608 struct berval ***keysp )
2612 struct berval **keys;
2613 HASH_CONTEXT HASHcontext;
2614 unsigned char HASHdigest[HASH_BYTES];
2615 struct berval digest;
2616 digest.bv_val = HASHdigest;
2617 digest.bv_len = sizeof(HASHdigest);
2619 /* we should have at least one value at this point */
2620 assert( values != NULL && values[0] != NULL );
2623 for( i=0; values[i] != NULL; i++ ) {
2624 /* count number of indices to generate */
2625 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2629 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2630 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2631 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2632 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2634 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2638 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2639 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2640 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2644 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2645 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2646 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2647 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2649 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2655 /* no keys to generate */
2657 return LDAP_SUCCESS;
2660 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2662 slen = strlen( syntax->ssyn_oid );
2663 mlen = strlen( mr->smr_oid );
2666 for( i=0; values[i] != NULL; i++ ) {
2668 struct berval *value;
2671 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2673 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2674 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2676 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2677 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2679 for( j=0; j<max; j++ ) {
2680 HASH_Init( &HASHcontext );
2681 if( prefix != NULL && prefix->bv_len > 0 ) {
2682 HASH_Update( &HASHcontext,
2683 prefix->bv_val, prefix->bv_len );
2686 HASH_Update( &HASHcontext,
2687 &pre, sizeof( pre ) );
2688 HASH_Update( &HASHcontext,
2689 syntax->ssyn_oid, slen );
2690 HASH_Update( &HASHcontext,
2691 mr->smr_oid, mlen );
2692 HASH_Update( &HASHcontext,
2694 SLAP_INDEX_SUBSTR_MAXLEN );
2695 HASH_Final( HASHdigest, &HASHcontext );
2697 keys[nkeys++] = ber_bvdup( &digest );
2701 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2702 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2704 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2707 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2708 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2709 HASH_Init( &HASHcontext );
2710 if( prefix != NULL && prefix->bv_len > 0 ) {
2711 HASH_Update( &HASHcontext,
2712 prefix->bv_val, prefix->bv_len );
2714 HASH_Update( &HASHcontext,
2715 &pre, sizeof( pre ) );
2716 HASH_Update( &HASHcontext,
2717 syntax->ssyn_oid, slen );
2718 HASH_Update( &HASHcontext,
2719 mr->smr_oid, mlen );
2720 HASH_Update( &HASHcontext,
2722 HASH_Final( HASHdigest, &HASHcontext );
2724 keys[nkeys++] = ber_bvdup( &digest );
2727 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2728 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2729 HASH_Init( &HASHcontext );
2730 if( prefix != NULL && prefix->bv_len > 0 ) {
2731 HASH_Update( &HASHcontext,
2732 prefix->bv_val, prefix->bv_len );
2734 HASH_Update( &HASHcontext,
2735 &pre, sizeof( pre ) );
2736 HASH_Update( &HASHcontext,
2737 syntax->ssyn_oid, slen );
2738 HASH_Update( &HASHcontext,
2739 mr->smr_oid, mlen );
2740 HASH_Update( &HASHcontext,
2741 &value->bv_val[value->bv_len-j], j );
2742 HASH_Final( HASHdigest, &HASHcontext );
2744 keys[nkeys++] = ber_bvdup( &digest );
2758 return LDAP_SUCCESS;
2761 int caseExactIA5SubstringsFilter(
2766 struct berval *prefix,
2768 struct berval ***keysp )
2770 SubstringsAssertion *sa = assertValue;
2772 ber_len_t nkeys = 0;
2773 size_t slen, mlen, klen;
2774 struct berval **keys;
2775 HASH_CONTEXT HASHcontext;
2776 unsigned char HASHdigest[HASH_BYTES];
2777 struct berval *value;
2778 struct berval digest;
2780 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2781 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2786 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2788 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2789 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2790 /* don't bother accounting for stepping */
2791 nkeys += sa->sa_any[i]->bv_len -
2792 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2797 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2798 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2805 return LDAP_SUCCESS;
2808 digest.bv_val = HASHdigest;
2809 digest.bv_len = sizeof(HASHdigest);
2811 slen = strlen( syntax->ssyn_oid );
2812 mlen = strlen( mr->smr_oid );
2814 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2817 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2818 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2820 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2821 value = sa->sa_initial;
2823 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2824 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2826 HASH_Init( &HASHcontext );
2827 if( prefix != NULL && prefix->bv_len > 0 ) {
2828 HASH_Update( &HASHcontext,
2829 prefix->bv_val, prefix->bv_len );
2831 HASH_Update( &HASHcontext,
2832 &pre, sizeof( pre ) );
2833 HASH_Update( &HASHcontext,
2834 syntax->ssyn_oid, slen );
2835 HASH_Update( &HASHcontext,
2836 mr->smr_oid, mlen );
2837 HASH_Update( &HASHcontext,
2838 value->bv_val, klen );
2839 HASH_Final( HASHdigest, &HASHcontext );
2841 keys[nkeys++] = ber_bvdup( &digest );
2844 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2846 pre = SLAP_INDEX_SUBSTR_PREFIX;
2847 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2849 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2850 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2854 value = sa->sa_any[i];
2857 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2858 j += SLAP_INDEX_SUBSTR_STEP )
2860 HASH_Init( &HASHcontext );
2861 if( prefix != NULL && prefix->bv_len > 0 ) {
2862 HASH_Update( &HASHcontext,
2863 prefix->bv_val, prefix->bv_len );
2865 HASH_Update( &HASHcontext,
2866 &pre, sizeof( pre ) );
2867 HASH_Update( &HASHcontext,
2868 syntax->ssyn_oid, slen );
2869 HASH_Update( &HASHcontext,
2870 mr->smr_oid, mlen );
2871 HASH_Update( &HASHcontext,
2872 &value->bv_val[j], klen );
2873 HASH_Final( HASHdigest, &HASHcontext );
2875 keys[nkeys++] = ber_bvdup( &digest );
2880 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2881 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2883 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2884 value = sa->sa_final;
2886 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2887 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2889 HASH_Init( &HASHcontext );
2890 if( prefix != NULL && prefix->bv_len > 0 ) {
2891 HASH_Update( &HASHcontext,
2892 prefix->bv_val, prefix->bv_len );
2894 HASH_Update( &HASHcontext,
2895 &pre, sizeof( pre ) );
2896 HASH_Update( &HASHcontext,
2897 syntax->ssyn_oid, slen );
2898 HASH_Update( &HASHcontext,
2899 mr->smr_oid, mlen );
2900 HASH_Update( &HASHcontext,
2901 &value->bv_val[value->bv_len-klen], klen );
2902 HASH_Final( HASHdigest, &HASHcontext );
2904 keys[nkeys++] = ber_bvdup( &digest );
2915 return LDAP_SUCCESS;
2924 struct berval *value,
2925 void *assertedValue )
2927 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2929 if( match == 0 && value->bv_len ) {
2930 match = strncasecmp( value->bv_val,
2931 ((struct berval *) assertedValue)->bv_val,
2936 return LDAP_SUCCESS;
2940 caseIgnoreIA5SubstringsMatch(
2945 struct berval *value,
2946 void *assertedValue )
2949 SubstringsAssertion *sub = assertedValue;
2950 struct berval left = *value;
2954 /* Add up asserted input length */
2955 if( sub->sa_initial ) {
2956 inlen += sub->sa_initial->bv_len;
2959 for(i=0; sub->sa_any[i] != NULL; i++) {
2960 inlen += sub->sa_any[i]->bv_len;
2963 if( sub->sa_final ) {
2964 inlen += sub->sa_final->bv_len;
2967 if( sub->sa_initial ) {
2968 if( inlen > left.bv_len ) {
2973 match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
2974 sub->sa_initial->bv_len );
2980 left.bv_val += sub->sa_initial->bv_len;
2981 left.bv_len -= sub->sa_initial->bv_len;
2982 inlen -= sub->sa_initial->bv_len;
2985 if( sub->sa_final ) {
2986 if( inlen > left.bv_len ) {
2991 match = strncasecmp( sub->sa_final->bv_val,
2992 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2993 sub->sa_final->bv_len );
2999 left.bv_len -= sub->sa_final->bv_len;
3000 inlen -= sub->sa_final->bv_len;
3004 for(i=0; sub->sa_any[i]; i++) {
3009 if( inlen > left.bv_len ) {
3010 /* not enough length */
3015 if( sub->sa_any[i]->bv_len == 0 ) {
3019 p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
3026 idx = p - left.bv_val;
3027 assert( idx < left.bv_len );
3029 if( idx >= left.bv_len ) {
3030 /* this shouldn't happen */
3037 if( sub->sa_any[i]->bv_len > left.bv_len ) {
3038 /* not enough left */
3043 match = strncasecmp( left.bv_val,
3044 sub->sa_any[i]->bv_val,
3045 sub->sa_any[i]->bv_len );
3054 left.bv_val += sub->sa_any[i]->bv_len;
3055 left.bv_len -= sub->sa_any[i]->bv_len;
3056 inlen -= sub->sa_any[i]->bv_len;
3062 return LDAP_SUCCESS;
3065 /* Index generation function */
3066 int caseIgnoreIA5Indexer(
3071 struct berval *prefix,
3072 struct berval **values,
3073 struct berval ***keysp )
3077 struct berval **keys;
3078 HASH_CONTEXT HASHcontext;
3079 unsigned char HASHdigest[HASH_BYTES];
3080 struct berval digest;
3081 digest.bv_val = HASHdigest;
3082 digest.bv_len = sizeof(HASHdigest);
3084 /* we should have at least one value at this point */
3085 assert( values != NULL && values[0] != NULL );
3087 for( i=0; values[i] != NULL; i++ ) {
3088 /* just count them */
3091 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
3093 slen = strlen( syntax->ssyn_oid );
3094 mlen = strlen( mr->smr_oid );
3096 for( i=0; values[i] != NULL; i++ ) {
3097 struct berval *value = ber_bvdup( values[i] );
3098 ldap_pvt_str2upper( value->bv_val );
3100 HASH_Init( &HASHcontext );
3101 if( prefix != NULL && prefix->bv_len > 0 ) {
3102 HASH_Update( &HASHcontext,
3103 prefix->bv_val, prefix->bv_len );
3105 HASH_Update( &HASHcontext,
3106 syntax->ssyn_oid, slen );
3107 HASH_Update( &HASHcontext,
3108 mr->smr_oid, mlen );
3109 HASH_Update( &HASHcontext,
3110 value->bv_val, value->bv_len );
3111 HASH_Final( HASHdigest, &HASHcontext );
3113 ber_bvfree( value );
3115 keys[i] = ber_bvdup( &digest );
3120 return LDAP_SUCCESS;
3123 /* Index generation function */
3124 int caseIgnoreIA5Filter(
3129 struct berval *prefix,
3131 struct berval ***keysp )
3134 struct berval **keys;
3135 HASH_CONTEXT HASHcontext;
3136 unsigned char HASHdigest[HASH_BYTES];
3137 struct berval *value;
3138 struct berval digest;
3139 digest.bv_val = HASHdigest;
3140 digest.bv_len = sizeof(HASHdigest);
3142 slen = strlen( syntax->ssyn_oid );
3143 mlen = strlen( mr->smr_oid );
3145 value = ber_bvdup( (struct berval *) assertValue );
3146 ldap_pvt_str2upper( value->bv_val );
3148 keys = ch_malloc( sizeof( struct berval * ) * 2 );
3150 HASH_Init( &HASHcontext );
3151 if( prefix != NULL && prefix->bv_len > 0 ) {
3152 HASH_Update( &HASHcontext,
3153 prefix->bv_val, prefix->bv_len );
3155 HASH_Update( &HASHcontext,
3156 syntax->ssyn_oid, slen );
3157 HASH_Update( &HASHcontext,
3158 mr->smr_oid, mlen );
3159 HASH_Update( &HASHcontext,
3160 value->bv_val, value->bv_len );
3161 HASH_Final( HASHdigest, &HASHcontext );
3163 keys[0] = ber_bvdup( &digest );
3166 ber_bvfree( value );
3170 return LDAP_SUCCESS;
3173 /* Substrings Index generation function */
3174 int caseIgnoreIA5SubstringsIndexer(
3179 struct berval *prefix,
3180 struct berval **values,
3181 struct berval ***keysp )
3185 struct berval **keys;
3186 HASH_CONTEXT HASHcontext;
3187 unsigned char HASHdigest[HASH_BYTES];
3188 struct berval digest;
3189 digest.bv_val = HASHdigest;
3190 digest.bv_len = sizeof(HASHdigest);
3192 /* we should have at least one value at this point */
3193 assert( values != NULL && values[0] != NULL );
3196 for( i=0; values[i] != NULL; i++ ) {
3197 /* count number of indices to generate */
3198 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3202 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3203 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3204 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3205 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3207 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3211 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3212 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3213 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3217 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3218 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3219 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3220 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3222 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3228 /* no keys to generate */
3230 return LDAP_SUCCESS;
3233 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
3235 slen = strlen( syntax->ssyn_oid );
3236 mlen = strlen( mr->smr_oid );
3239 for( i=0; values[i] != NULL; i++ ) {
3241 struct berval *value;
3243 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3245 value = ber_bvdup( values[i] );
3246 ldap_pvt_str2upper( value->bv_val );
3248 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3249 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3251 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3252 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3254 for( j=0; j<max; j++ ) {
3255 HASH_Init( &HASHcontext );
3256 if( prefix != NULL && prefix->bv_len > 0 ) {
3257 HASH_Update( &HASHcontext,
3258 prefix->bv_val, prefix->bv_len );
3261 HASH_Update( &HASHcontext,
3262 &pre, sizeof( pre ) );
3263 HASH_Update( &HASHcontext,
3264 syntax->ssyn_oid, slen );
3265 HASH_Update( &HASHcontext,
3266 mr->smr_oid, mlen );
3267 HASH_Update( &HASHcontext,
3269 SLAP_INDEX_SUBSTR_MAXLEN );
3270 HASH_Final( HASHdigest, &HASHcontext );
3272 keys[nkeys++] = ber_bvdup( &digest );
3276 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3277 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3279 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3282 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3283 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3284 HASH_Init( &HASHcontext );
3285 if( prefix != NULL && prefix->bv_len > 0 ) {
3286 HASH_Update( &HASHcontext,
3287 prefix->bv_val, prefix->bv_len );
3289 HASH_Update( &HASHcontext,
3290 &pre, sizeof( pre ) );
3291 HASH_Update( &HASHcontext,
3292 syntax->ssyn_oid, slen );
3293 HASH_Update( &HASHcontext,
3294 mr->smr_oid, mlen );
3295 HASH_Update( &HASHcontext,
3297 HASH_Final( HASHdigest, &HASHcontext );
3299 keys[nkeys++] = ber_bvdup( &digest );
3302 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3303 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3304 HASH_Init( &HASHcontext );
3305 if( prefix != NULL && prefix->bv_len > 0 ) {
3306 HASH_Update( &HASHcontext,
3307 prefix->bv_val, prefix->bv_len );
3309 HASH_Update( &HASHcontext,
3310 &pre, sizeof( pre ) );
3311 HASH_Update( &HASHcontext,
3312 syntax->ssyn_oid, slen );
3313 HASH_Update( &HASHcontext,
3314 mr->smr_oid, mlen );
3315 HASH_Update( &HASHcontext,
3316 &value->bv_val[value->bv_len-j], j );
3317 HASH_Final( HASHdigest, &HASHcontext );
3319 keys[nkeys++] = ber_bvdup( &digest );
3324 ber_bvfree( value );
3335 return LDAP_SUCCESS;
3338 int caseIgnoreIA5SubstringsFilter(
3343 struct berval *prefix,
3345 struct berval ***keysp )
3347 SubstringsAssertion *sa = assertValue;
3349 ber_len_t nkeys = 0;
3350 size_t slen, mlen, klen;
3351 struct berval **keys;
3352 HASH_CONTEXT HASHcontext;
3353 unsigned char HASHdigest[HASH_BYTES];
3354 struct berval *value;
3355 struct berval digest;
3357 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3358 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3363 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3365 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3366 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3367 /* don't bother accounting for stepping */
3368 nkeys += sa->sa_any[i]->bv_len -
3369 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3374 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3375 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3382 return LDAP_SUCCESS;
3385 digest.bv_val = HASHdigest;
3386 digest.bv_len = sizeof(HASHdigest);
3388 slen = strlen( syntax->ssyn_oid );
3389 mlen = strlen( mr->smr_oid );
3391 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
3394 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3395 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3397 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3398 value = ber_bvdup( sa->sa_initial );
3399 ldap_pvt_str2upper( value->bv_val );
3401 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3402 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3404 HASH_Init( &HASHcontext );
3405 if( prefix != NULL && prefix->bv_len > 0 ) {
3406 HASH_Update( &HASHcontext,
3407 prefix->bv_val, prefix->bv_len );
3409 HASH_Update( &HASHcontext,
3410 &pre, sizeof( pre ) );
3411 HASH_Update( &HASHcontext,
3412 syntax->ssyn_oid, slen );
3413 HASH_Update( &HASHcontext,
3414 mr->smr_oid, mlen );
3415 HASH_Update( &HASHcontext,
3416 value->bv_val, klen );
3417 HASH_Final( HASHdigest, &HASHcontext );
3419 ber_bvfree( value );
3420 keys[nkeys++] = ber_bvdup( &digest );
3423 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3425 pre = SLAP_INDEX_SUBSTR_PREFIX;
3426 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3428 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3429 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3433 value = ber_bvdup( sa->sa_any[i] );
3434 ldap_pvt_str2upper( value->bv_val );
3437 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3438 j += SLAP_INDEX_SUBSTR_STEP )
3440 HASH_Init( &HASHcontext );
3441 if( prefix != NULL && prefix->bv_len > 0 ) {
3442 HASH_Update( &HASHcontext,
3443 prefix->bv_val, prefix->bv_len );
3445 HASH_Update( &HASHcontext,
3446 &pre, sizeof( pre ) );
3447 HASH_Update( &HASHcontext,
3448 syntax->ssyn_oid, slen );
3449 HASH_Update( &HASHcontext,
3450 mr->smr_oid, mlen );
3451 HASH_Update( &HASHcontext,
3452 &value->bv_val[j], klen );
3453 HASH_Final( HASHdigest, &HASHcontext );
3455 keys[nkeys++] = ber_bvdup( &digest );
3458 ber_bvfree( value );
3462 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3463 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3465 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3466 value = ber_bvdup( sa->sa_final );
3467 ldap_pvt_str2upper( value->bv_val );
3469 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3470 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3472 HASH_Init( &HASHcontext );
3473 if( prefix != NULL && prefix->bv_len > 0 ) {
3474 HASH_Update( &HASHcontext,
3475 prefix->bv_val, prefix->bv_len );
3477 HASH_Update( &HASHcontext,
3478 &pre, sizeof( pre ) );
3479 HASH_Update( &HASHcontext,
3480 syntax->ssyn_oid, slen );
3481 HASH_Update( &HASHcontext,
3482 mr->smr_oid, mlen );
3483 HASH_Update( &HASHcontext,
3484 &value->bv_val[value->bv_len-klen], klen );
3485 HASH_Final( HASHdigest, &HASHcontext );
3487 ber_bvfree( value );
3488 keys[nkeys++] = ber_bvdup( &digest );
3499 return LDAP_SUCCESS;
3503 numericStringValidate(
3509 for(i=0; i < in->bv_len; i++) {
3510 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3511 return LDAP_INVALID_SYNTAX;
3515 return LDAP_SUCCESS;
3519 numericStringNormalize(
3522 struct berval **normalized )
3524 /* removal all spaces */
3525 struct berval *newval;
3528 newval = ch_malloc( sizeof( struct berval ) );
3529 newval->bv_val = ch_malloc( val->bv_len + 1 );
3535 if ( ASCII_SPACE( *p ) ) {
3536 /* Ignore whitespace */
3543 /* we should have copied no more then is in val */
3544 assert( (q - newval->bv_val) <= (p - val->bv_val) );
3546 /* null terminate */
3549 newval->bv_len = q - newval->bv_val;
3550 *normalized = newval;
3552 return LDAP_SUCCESS;
3556 objectIdentifierFirstComponentMatch(
3561 struct berval *value,
3562 void *assertedValue )
3564 int rc = LDAP_SUCCESS;
3566 struct berval *asserted = (struct berval *) assertedValue;
3570 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3571 return LDAP_INVALID_SYNTAX;
3574 /* trim leading white space */
3575 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3579 /* grab next word */
3580 oid.bv_val = &value->bv_val[i];
3581 oid.bv_len = value->bv_len - i;
3582 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3587 /* insert attributeTypes, objectclass check here */
3588 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3589 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3592 char *stored = ch_malloc( oid.bv_len + 1 );
3593 AC_MEMCPY( stored, oid.bv_val, oid.bv_len );
3594 stored[oid.bv_len] = '\0';
3596 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3597 MatchingRule *asserted_mr = mr_find( asserted->bv_val );
3598 MatchingRule *stored_mr = mr_find( stored );
3600 if( asserted_mr == NULL ) {
3601 rc = SLAPD_COMPARE_UNDEFINED;
3603 match = asserted_mr != stored_mr;
3606 } else if ( !strcmp( syntax->ssyn_oid,
3607 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3609 AttributeType *asserted_at = at_find( asserted->bv_val );
3610 AttributeType *stored_at = at_find( stored );
3612 if( asserted_at == NULL ) {
3613 rc = SLAPD_COMPARE_UNDEFINED;
3615 match = asserted_at != stored_at;
3618 } else if ( !strcmp( syntax->ssyn_oid,
3619 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3621 ObjectClass *asserted_oc = oc_find( asserted->bv_val );
3622 ObjectClass *stored_oc = oc_find( stored );
3624 if( asserted_oc == NULL ) {
3625 rc = SLAPD_COMPARE_UNDEFINED;
3627 match = asserted_oc != stored_oc;
3635 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3636 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3637 match, value->bv_val, asserted->bv_val ));
3639 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3640 "%d\n\t\"%s\"\n\t\"%s\"\n",
3641 match, value->bv_val, asserted->bv_val );
3645 if( rc == LDAP_SUCCESS ) *matchp = match;
3655 struct berval *value,
3656 void *assertedValue )
3658 long lValue, lAssertedValue;
3660 /* safe to assume integers are NUL terminated? */
3661 lValue = strtoul(value->bv_val, NULL, 10);
3662 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3663 return LDAP_CONSTRAINT_VIOLATION;
3665 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3666 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3667 return LDAP_CONSTRAINT_VIOLATION;
3669 *matchp = (lValue & lAssertedValue);
3670 return LDAP_SUCCESS;
3679 struct berval *value,
3680 void *assertedValue )
3682 long lValue, lAssertedValue;
3684 /* safe to assume integers are NUL terminated? */
3685 lValue = strtoul(value->bv_val, NULL, 10);
3686 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3687 return LDAP_CONSTRAINT_VIOLATION;
3689 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3690 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3691 return LDAP_CONSTRAINT_VIOLATION;
3693 *matchp = (lValue | lAssertedValue);
3694 return LDAP_SUCCESS;
3698 #include <openssl/x509.h>
3699 #include <openssl/err.h>
3700 char digit[] = "0123456789";
3703 * Next function returns a string representation of a ASN1_INTEGER.
3704 * It works for unlimited lengths.
3707 static struct berval *
3708 asn1_integer2str(ASN1_INTEGER *a)
3713 /* We work backwards, make it fill from the end of buf */
3714 p = buf + sizeof(buf) - 1;
3717 if ( a == NULL || a->length == 0 ) {
3725 /* We want to preserve the original */
3726 copy = ch_malloc(n*sizeof(unsigned int));
3727 for (i = 0; i<n; i++) {
3728 copy[i] = a->data[i];
3732 * base indicates the index of the most significant
3733 * byte that might be nonzero. When it goes off the
3734 * end, we now there is nothing left to do.
3740 for (i = base; i<n; i++ ) {
3741 copy[i] += carry*256;
3742 carry = copy[i] % 10;
3747 * Way too large, we need to leave
3748 * room for sign if negative
3753 *--p = digit[carry];
3754 if (copy[base] == 0)
3760 if ( a->type == V_ASN1_NEG_INTEGER ) {
3764 return ber_bvstrdup(p);
3767 /* Get a DN in RFC2253 format from a X509_NAME internal struct */
3768 static struct berval *
3769 dn_openssl2ldap(X509_NAME *name)
3771 char issuer_dn[1024];
3774 bio = BIO_new(BIO_s_mem());
3777 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3778 "dn_openssl2ldap: error creating BIO_s_mem: %s\n",
3779 ERR_error_string(ERR_get_error(),NULL)));
3781 Debug( LDAP_DEBUG_ARGS, "dn_openssl2ldap: "
3782 "error creating BIO: %s\n",
3783 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3787 X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253);
3789 BIO_gets(bio, issuer_dn, 1024);
3792 return ber_bvstrdup(issuer_dn);
3796 * Given a certificate in DER format, extract the corresponding
3797 * assertion value for certificateExactMatch
3800 certificateExactConvert(
3802 struct berval ** out )
3805 unsigned char *p = in->bv_val;
3806 struct berval *serial;
3807 struct berval *issuer_dn;
3808 struct berval *bv_tmp;
3810 xcert = d2i_X509(NULL, &p, in->bv_len);
3813 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3814 "certificateExactConvert: error parsing cert: %s\n",
3815 ERR_error_string(ERR_get_error(),NULL)));
3817 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3818 "error parsing cert: %s\n",
3819 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3821 return LDAP_INVALID_SYNTAX;
3824 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3827 return LDAP_INVALID_SYNTAX;
3829 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
3833 return LDAP_INVALID_SYNTAX;
3835 /* Actually, dn_openssl2ldap returns in a normalized format, but
3836 it is different from our normalized format */
3838 if ( dnNormalize(NULL, bv_tmp, &issuer_dn) != LDAP_SUCCESS ) {
3842 return LDAP_INVALID_SYNTAX;
3848 *out = ch_malloc(sizeof(struct berval));
3849 (*out)->bv_len = serial->bv_len + 3 + issuer_dn->bv_len + 1;
3850 (*out)->bv_val = ch_malloc((*out)->bv_len);
3852 AC_MEMCPY(p, serial->bv_val, serial->bv_len);
3853 p += serial->bv_len;
3854 AC_MEMCPY(p, " $ ", 3);
3856 AC_MEMCPY(p, issuer_dn->bv_val, issuer_dn->bv_len);
3857 p += issuer_dn->bv_len;
3861 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3862 "certificateExactConvert: \n %s\n",
3865 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3867 (*out)->bv_val, NULL, NULL );
3871 ber_bvfree(issuer_dn);
3873 return LDAP_SUCCESS;
3877 serial_and_issuer_parse(
3878 struct berval *assertion,
3879 struct berval **serial,
3880 struct berval **issuer_dn
3888 begin = assertion->bv_val;
3889 end = assertion->bv_val+assertion->bv_len-1;
3890 for (p=begin; p<=end && *p != '$'; p++)
3893 return LDAP_INVALID_SYNTAX;
3895 /* p now points at the $ sign, now use begin and end to delimit the
3897 while (ASCII_SPACE(*begin))
3900 while (ASCII_SPACE(*end))
3903 q = ch_malloc( (end-begin+1)+1 );
3904 AC_MEMCPY( q, begin, end-begin+1 );
3905 q[end-begin+1] = '\0';
3906 *serial = ber_bvstr(q);
3908 /* now extract the issuer, remember p was at the dollar sign */
3910 end = assertion->bv_val+assertion->bv_len-1;
3911 while (ASCII_SPACE(*begin))
3913 /* should we trim spaces at the end too? is it safe always? */
3915 q = ch_malloc( (end-begin+1)+1 );
3916 AC_MEMCPY( q, begin, end-begin+1 );
3917 q[end-begin+1] = '\0';
3918 *issuer_dn = ber_bvstr(dn_normalize(q));
3920 return LDAP_SUCCESS;
3924 certificateExactMatch(
3929 struct berval *value,
3930 void *assertedValue )
3933 unsigned char *p = value->bv_val;
3934 struct berval *serial;
3935 struct berval *issuer_dn;
3936 struct berval *asserted_serial;
3937 struct berval *asserted_issuer_dn;
3940 xcert = d2i_X509(NULL, &p, value->bv_len);
3943 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3944 "certificateExactMatch: error parsing cert: %s\n",
3945 ERR_error_string(ERR_get_error(),NULL)));
3947 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
3948 "error parsing cert: %s\n",
3949 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3951 return LDAP_INVALID_SYNTAX;
3954 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3955 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
3959 serial_and_issuer_parse(assertedValue,
3961 &asserted_issuer_dn);
3966 slap_schema.si_syn_integer,
3967 slap_schema.si_mr_integerMatch,
3970 if ( ret == LDAP_SUCCESS ) {
3971 if ( *matchp == 0 ) {
3972 /* We need to normalize everything for dnMatch */
3976 slap_schema.si_syn_distinguishedName,
3977 slap_schema.si_mr_distinguishedNameMatch,
3979 asserted_issuer_dn);
3984 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3985 "certificateExactMatch: %d\n %s $ %s\n %s $ %s\n",
3986 *matchp, serial->bv_val, issuer_dn->bv_val,
3987 asserted->serial->bv_val, asserted_issuer_dn->bv_val));
3989 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
3990 "%d\n\t\"%s $ %s\"\n",
3991 *matchp, serial->bv_val, issuer_dn->bv_val );
3992 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
3993 asserted_serial->bv_val, asserted_issuer_dn->bv_val,
3998 ber_bvfree(issuer_dn);
3999 ber_bvfree(asserted_serial);
4000 ber_bvfree(asserted_issuer_dn);
4006 * Index generation function
4007 * We just index the serials, in most scenarios the issuer DN is one of
4008 * a very small set of values.
4010 int certificateExactIndexer(
4015 struct berval *prefix,
4016 struct berval **values,
4017 struct berval ***keysp )
4020 struct berval **keys;
4023 struct berval * serial;
4025 /* we should have at least one value at this point */
4026 assert( values != NULL && values[0] != NULL );
4028 for( i=0; values[i] != NULL; i++ ) {
4029 /* empty -- just count them */
4032 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
4034 for( i=0; values[i] != NULL; i++ ) {
4035 p = values[i]->bv_val;
4036 xcert = d2i_X509(NULL, &p, values[i]->bv_len);
4039 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
4040 "certificateExactIndexer: error parsing cert: %s\n",
4041 ERR_error_string(ERR_get_error(),NULL)));
4043 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4044 "error parsing cert: %s\n",
4045 ERR_error_string(ERR_get_error(),NULL),
4048 /* Do we leak keys on error? */
4049 return LDAP_INVALID_SYNTAX;
4052 serial = asn1_integer2str(xcert->cert_info->serialNumber);
4054 integerNormalize( slap_schema.si_syn_integer,
4059 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
4060 "certificateExactIndexer: returning: %s\n",
4063 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4072 return LDAP_SUCCESS;
4075 /* Index generation function */
4076 /* We think this is always called with a value in matching rule syntax */
4077 int certificateExactFilter(
4082 struct berval *prefix,
4084 struct berval ***keysp )
4086 struct berval **keys;
4087 struct berval *asserted_serial;
4088 struct berval *asserted_issuer_dn;
4090 serial_and_issuer_parse(assertValue,
4092 &asserted_issuer_dn);
4094 keys = ch_malloc( sizeof( struct berval * ) * 2 );
4095 integerNormalize( syntax, asserted_serial, &keys[0] );
4099 ber_bvfree(asserted_serial);
4100 ber_bvfree(asserted_issuer_dn);
4101 return LDAP_SUCCESS;
4106 check_time_syntax (struct berval *val,
4110 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4111 static int mdays[2][12] = {
4112 /* non-leap years */
4113 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4115 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4118 int part, c, tzoffset, leapyear = 0 ;
4120 if( val->bv_len == 0 ) {
4121 return LDAP_INVALID_SYNTAX;
4124 p = (char *)val->bv_val;
4125 e = p + val->bv_len;
4127 /* Ignore initial whitespace */
4128 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4132 if (e - p < 13 - (2 * start)) {
4133 return LDAP_INVALID_SYNTAX;
4136 for (part = 0; part < 9; part++) {
4140 for (part = start; part < 7; part++) {
4142 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4149 return LDAP_INVALID_SYNTAX;
4151 if (c < 0 || c > 9) {
4152 return LDAP_INVALID_SYNTAX;
4158 return LDAP_INVALID_SYNTAX;
4160 if (c < 0 || c > 9) {
4161 return LDAP_INVALID_SYNTAX;
4166 if (part == 2 || part == 3) {
4169 if (parts[part] < 0) {
4170 return LDAP_INVALID_SYNTAX;
4172 if (parts[part] > ceiling[part]) {
4173 return LDAP_INVALID_SYNTAX;
4177 /* leapyear check for the Gregorian calendar (year>1581) */
4178 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4179 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4184 if (parts[3] > mdays[leapyear][parts[2]]) {
4185 return LDAP_INVALID_SYNTAX;
4190 tzoffset = 0; /* UTC */
4191 } else if (c != '+' && c != '-') {
4192 return LDAP_INVALID_SYNTAX;
4196 } else /* c == '+' */ {
4201 return LDAP_INVALID_SYNTAX;
4204 for (part = 7; part < 9; part++) {
4206 if (c < 0 || c > 9) {
4207 return LDAP_INVALID_SYNTAX;
4212 if (c < 0 || c > 9) {
4213 return LDAP_INVALID_SYNTAX;
4217 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4218 return LDAP_INVALID_SYNTAX;
4223 /* Ignore trailing whitespace */
4224 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4228 return LDAP_INVALID_SYNTAX;
4231 switch ( tzoffset ) {
4232 case -1: /* negativ offset to UTC, ie west of Greenwich */
4233 parts[4] += parts[7];
4234 parts[5] += parts[8];
4235 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4239 c = mdays[leapyear][parts[2]];
4241 if (parts[part] > c) {
4242 parts[part] -= c + 1;
4247 case 1: /* positive offset to UTC, ie east of Greenwich */
4248 parts[4] -= parts[7];
4249 parts[5] -= parts[8];
4250 for (part = 6; --part > 0; ) {
4254 /* first arg to % needs to be non negativ */
4255 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4257 if (parts[part] < 0) {
4258 parts[part] += c + 1;
4263 case 0: /* already UTC */
4267 return LDAP_SUCCESS;
4274 struct berval **normalized )
4279 rc = check_time_syntax(val, 1, parts);
4280 if (rc != LDAP_SUCCESS) {
4285 out = ch_malloc( sizeof(struct berval) );
4287 return LBER_ERROR_MEMORY;
4290 out->bv_val = ch_malloc( 14 );
4291 if ( out->bv_val == NULL ) {
4293 return LBER_ERROR_MEMORY;
4296 sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4297 parts[1], parts[2] + 1, parts[3] + 1,
4298 parts[4], parts[5], parts[6] );
4302 return LDAP_SUCCESS;
4312 return check_time_syntax(in, 1, parts);
4316 generalizedTimeValidate(
4322 return check_time_syntax(in, 0, parts);
4326 generalizedTimeNormalize(
4329 struct berval **normalized )
4334 rc = check_time_syntax(val, 0, parts);
4335 if (rc != LDAP_SUCCESS) {
4340 out = ch_malloc( sizeof(struct berval) );
4342 return LBER_ERROR_MEMORY;
4345 out->bv_val = ch_malloc( 16 );
4346 if ( out->bv_val == NULL ) {
4348 return LBER_ERROR_MEMORY;
4351 sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4352 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4353 parts[4], parts[5], parts[6] );
4357 return LDAP_SUCCESS;
4361 nisNetgroupTripleValidate(
4363 struct berval *val )
4368 if ( val->bv_len == 0 ) {
4369 return LDAP_INVALID_SYNTAX;
4372 p = (char *)val->bv_val;
4373 e = p + val->bv_len;
4375 if ( *p != '(' /*')'*/ ) {
4376 return LDAP_INVALID_SYNTAX;
4379 for ( p++; ( p < e ) && ( *p != ')' ); p++ ) {
4383 return LDAP_INVALID_SYNTAX;
4386 } else if ( !ATTR_CHAR( *p ) ) {
4387 return LDAP_INVALID_SYNTAX;
4391 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4392 return LDAP_INVALID_SYNTAX;
4398 return LDAP_INVALID_SYNTAX;
4401 return LDAP_SUCCESS;
4405 bootParameterValidate(
4407 struct berval *val )
4411 if ( val->bv_len == 0 ) {
4412 return LDAP_INVALID_SYNTAX;
4415 p = (char *)val->bv_val;
4416 e = p + val->bv_len;
4419 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4420 if ( !ATTR_CHAR( *p ) ) {
4421 return LDAP_INVALID_SYNTAX;
4426 return LDAP_INVALID_SYNTAX;
4430 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4431 if ( !ATTR_CHAR( *p ) ) {
4432 return LDAP_INVALID_SYNTAX;
4437 return LDAP_INVALID_SYNTAX;
4441 for ( p++; p < e; p++ ) {
4442 if ( !ATTR_CHAR( *p ) ) {
4443 return LDAP_INVALID_SYNTAX;
4447 return LDAP_SUCCESS;
4450 struct syntax_defs_rec {
4453 slap_syntax_validate_func *sd_validate;
4454 slap_syntax_transform_func *sd_normalize;
4455 slap_syntax_transform_func *sd_pretty;
4456 #ifdef SLAPD_BINARY_CONVERSION
4457 slap_syntax_transform_func *sd_ber2str;
4458 slap_syntax_transform_func *sd_str2ber;
4462 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4463 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4465 struct syntax_defs_rec syntax_defs[] = {
4466 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
4467 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4468 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4469 0, NULL, NULL, NULL},
4470 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4471 0, NULL, NULL, NULL},
4472 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
4473 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4474 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_NOT_H_R ")",
4475 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4476 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4477 0, bitStringValidate, bitStringNormalize, NULL },
4478 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4479 0, booleanValidate, NULL, NULL},
4480 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4481 X_BINARY X_NOT_H_R ")",
4482 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4483 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4484 X_BINARY X_NOT_H_R ")",
4485 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4486 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4487 X_BINARY X_NOT_H_R ")",
4488 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4489 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4490 0, countryStringValidate, IA5StringNormalize, NULL},
4491 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4492 0, dnValidate, dnNormalize, dnPretty},
4493 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4494 0, NULL, NULL, NULL},
4495 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4496 0, NULL, NULL, NULL},
4497 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4498 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4499 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4500 0, NULL, NULL, NULL},
4501 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4502 0, NULL, NULL, NULL},
4503 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4504 0, NULL, NULL, NULL},
4505 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4506 0, NULL, NULL, NULL},
4507 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4508 0, NULL, NULL, NULL},
4509 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4510 0, printablesStringValidate, IA5StringNormalize, NULL},
4511 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4512 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4513 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4514 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4515 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4516 0, NULL, NULL, NULL},
4517 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4518 0, IA5StringValidate, IA5StringNormalize, NULL},
4519 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4520 0, integerValidate, integerNormalize, NULL},
4521 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4522 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4523 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4524 0, NULL, NULL, NULL},
4525 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4526 0, NULL, NULL, NULL},
4527 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4528 0, NULL, NULL, NULL},
4529 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4530 0, NULL, NULL, NULL},
4531 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4532 0, NULL, NULL, NULL},
4533 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4534 0, nameUIDValidate, nameUIDNormalize, NULL},
4535 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4536 0, NULL, NULL, NULL},
4537 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4538 0, numericStringValidate, numericStringNormalize, NULL},
4539 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4540 0, NULL, NULL, NULL},
4541 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4542 0, oidValidate, NULL, NULL},
4543 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4544 0, IA5StringValidate, IA5StringNormalize, NULL},
4545 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4546 0, blobValidate, NULL, NULL},
4547 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4548 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4549 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4550 0, NULL, NULL, NULL},
4551 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4552 0, NULL, NULL, NULL},
4553 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4554 0, printableStringValidate, IA5StringNormalize, NULL},
4555 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4556 X_BINARY X_NOT_H_R ")",
4557 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4558 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4559 0, printableStringValidate, IA5StringNormalize, NULL},
4560 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4561 0, NULL, NULL, NULL},
4562 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4563 0, printablesStringValidate, IA5StringNormalize, NULL},
4564 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4565 0, utcTimeValidate, utcTimeNormalize, NULL},
4566 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4567 0, NULL, NULL, NULL},
4568 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4569 0, NULL, NULL, NULL},
4570 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4571 0, NULL, NULL, NULL},
4572 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4573 0, NULL, NULL, NULL},
4574 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4575 0, NULL, NULL, NULL},
4577 /* RFC 2307 NIS Syntaxes */
4578 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4579 0, nisNetgroupTripleValidate, NULL, NULL},
4580 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4581 0, bootParameterValidate, NULL, NULL},
4585 /* These OIDs are not published yet, but will be in the next
4586 * I-D for PKIX LDAPv3 schema as have been advanced by David
4587 * Chadwick in private mail.
4589 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4590 0, NULL, NULL, NULL},
4593 /* OpenLDAP Experimental Syntaxes */
4594 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4596 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4599 /* needs updating */
4600 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4601 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4603 /* OpenLDAP Void Syntax */
4604 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4605 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4606 {NULL, 0, NULL, NULL, NULL}
4609 struct mrule_defs_rec {
4611 slap_mask_t mrd_usage;
4612 slap_mr_convert_func * mrd_convert;
4613 slap_mr_normalize_func * mrd_normalize;
4614 slap_mr_match_func * mrd_match;
4615 slap_mr_indexer_func * mrd_indexer;
4616 slap_mr_filter_func * mrd_filter;
4618 char * mrd_associated;
4622 * Other matching rules in X.520 that we do not use (yet):
4624 * 2.5.13.9 numericStringOrderingMatch
4625 * 2.5.13.15 integerOrderingMatch
4626 * 2.5.13.18 octetStringOrderingMatch
4627 * 2.5.13.19 octetStringSubstringsMatch
4628 * 2.5.13.25 uTCTimeMatch
4629 * 2.5.13.26 uTCTimeOrderingMatch
4630 * 2.5.13.31 directoryStringFirstComponentMatch
4631 * 2.5.13.32 wordMatch
4632 * 2.5.13.33 keywordMatch
4633 * 2.5.13.35 certificateMatch
4634 * 2.5.13.36 certificatePairExactMatch
4635 * 2.5.13.37 certificatePairMatch
4636 * 2.5.13.38 certificateListExactMatch
4637 * 2.5.13.39 certificateListMatch
4638 * 2.5.13.40 algorithmIdentifierMatch
4639 * 2.5.13.41 storedPrefixMatch
4640 * 2.5.13.42 attributeCertificateMatch
4641 * 2.5.13.43 readerAndKeyIDMatch
4642 * 2.5.13.44 attributeIntegrityMatch
4645 struct mrule_defs_rec mrule_defs[] = {
4647 * EQUALITY matching rules must be listed after associated APPROX
4648 * matching rules. So, we list all APPROX matching rules first.
4650 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4651 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4652 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4654 directoryStringApproxMatch,
4655 directoryStringApproxIndexer,
4656 directoryStringApproxFilter,
4659 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4660 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4661 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4663 IA5StringApproxMatch,
4664 IA5StringApproxIndexer,
4665 IA5StringApproxFilter,
4669 * Other matching rules
4672 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4673 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4674 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4676 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4679 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4680 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4681 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4683 dnMatch, dnIndexer, dnFilter,
4686 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4687 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4688 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4690 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4691 directoryStringApproxMatchOID },
4693 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4694 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4697 caseIgnoreOrderingMatch, NULL, NULL,
4700 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4701 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4702 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4704 caseExactIgnoreSubstringsMatch,
4705 caseExactIgnoreSubstringsIndexer,
4706 caseExactIgnoreSubstringsFilter,
4709 {"( 2.5.13.5 NAME 'caseExactMatch' "
4710 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4711 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4713 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4714 directoryStringApproxMatchOID },
4716 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4717 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4720 caseExactOrderingMatch, NULL, NULL,
4723 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4724 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4725 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4727 caseExactIgnoreSubstringsMatch,
4728 caseExactIgnoreSubstringsIndexer,
4729 caseExactIgnoreSubstringsFilter,
4732 {"( 2.5.13.8 NAME 'numericStringMatch' "
4733 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4734 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4737 caseIgnoreIA5Indexer,
4738 caseIgnoreIA5Filter,
4741 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4742 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4743 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4745 caseIgnoreIA5SubstringsMatch,
4746 caseIgnoreIA5SubstringsIndexer,
4747 caseIgnoreIA5SubstringsFilter,
4750 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4751 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4752 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4754 caseIgnoreListMatch, NULL, NULL,
4757 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4758 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4759 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4761 caseIgnoreListSubstringsMatch, NULL, NULL,
4764 {"( 2.5.13.13 NAME 'booleanMatch' "
4765 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4766 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4768 booleanMatch, NULL, NULL,
4771 {"( 2.5.13.14 NAME 'integerMatch' "
4772 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4773 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4775 integerMatch, integerIndexer, integerFilter,
4778 {"( 2.5.13.16 NAME 'bitStringMatch' "
4779 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4780 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4782 bitStringMatch, bitStringIndexer, bitStringFilter,
4785 {"( 2.5.13.17 NAME 'octetStringMatch' "
4786 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4787 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4789 octetStringMatch, octetStringIndexer, octetStringFilter,
4792 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4793 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4794 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4796 telephoneNumberMatch,
4797 telephoneNumberIndexer,
4798 telephoneNumberFilter,
4801 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4802 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4803 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4805 telephoneNumberSubstringsMatch,
4806 telephoneNumberSubstringsIndexer,
4807 telephoneNumberSubstringsFilter,
4810 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4811 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4812 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4817 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4818 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4819 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4821 uniqueMemberMatch, NULL, NULL,
4824 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4825 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4826 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4828 protocolInformationMatch, NULL, NULL,
4831 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4832 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4833 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4835 generalizedTimeMatch, NULL, NULL,
4838 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4839 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4842 generalizedTimeOrderingMatch, NULL, NULL,
4845 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4846 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4847 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4849 integerFirstComponentMatch, NULL, NULL,
4852 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4853 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4854 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4856 objectIdentifierFirstComponentMatch, NULL, NULL,
4860 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4861 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4862 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4863 certificateExactConvert, NULL,
4864 certificateExactMatch,
4865 certificateExactIndexer, certificateExactFilter,
4869 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4870 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4871 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4873 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4874 IA5StringApproxMatchOID },
4876 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4877 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4878 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4880 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4881 IA5StringApproxMatchOID },
4883 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4884 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4887 caseIgnoreIA5SubstringsMatch,
4888 caseIgnoreIA5SubstringsIndexer,
4889 caseIgnoreIA5SubstringsFilter,
4892 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4893 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4896 caseExactIA5SubstringsMatch,
4897 caseExactIA5SubstringsIndexer,
4898 caseExactIA5SubstringsFilter,
4901 /* needs updating */
4902 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
4903 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4906 authPasswordMatch, NULL, NULL,
4909 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
4910 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
4913 OpenLDAPaciMatch, NULL, NULL,
4916 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
4917 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4920 integerBitAndMatch, NULL, NULL,
4923 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
4924 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4927 integerBitOrMatch, NULL, NULL,
4930 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
4939 /* we should only be called once (from main) */
4940 assert( schema_init_done == 0 );
4942 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
4943 res = register_syntax( syntax_defs[i].sd_desc,
4944 syntax_defs[i].sd_flags,
4945 syntax_defs[i].sd_validate,
4946 syntax_defs[i].sd_normalize,
4947 syntax_defs[i].sd_pretty
4948 #ifdef SLAPD_BINARY_CONVERSION
4950 syntax_defs[i].sd_ber2str,
4951 syntax_defs[i].sd_str2ber
4956 fprintf( stderr, "schema_init: Error registering syntax %s\n",
4957 syntax_defs[i].sd_desc );
4962 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
4963 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
4965 "schema_init: Ingoring unusable matching rule %s\n",
4966 mrule_defs[i].mrd_desc );
4970 res = register_matching_rule(
4971 mrule_defs[i].mrd_desc,
4972 mrule_defs[i].mrd_usage,
4973 mrule_defs[i].mrd_convert,
4974 mrule_defs[i].mrd_normalize,
4975 mrule_defs[i].mrd_match,
4976 mrule_defs[i].mrd_indexer,
4977 mrule_defs[i].mrd_filter,
4978 mrule_defs[i].mrd_associated );
4982 "schema_init: Error registering matching rule %s\n",
4983 mrule_defs[i].mrd_desc );
4987 schema_init_done = 1;
4988 return LDAP_SUCCESS;
4992 schema_destroy( void )