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 );
247 AVA_Sort( LDAPRDN *rdn, int iAVA )
250 LDAPAVA *ava_in = rdn[ iAVA ][ 0 ];
252 for ( i = 0; i < iAVA; i++ ) {
253 LDAPAVA *ava = rdn[ i ][ 0 ];
256 a = strcmp( ava_in->la_attr->bv_val, ava->la_attr->bv_val );
265 d = ava_in->la_value->bv_len - ava->la_value->bv_len;
267 v = memcmp( ava_in->la_value->bv_val,
268 ava->la_value->bv_val,
269 d <= 0 ? ava_in->la_value->bv_len
270 : ava->la_value->bv_len );
272 if ( v == 0 && d != 0 ) {
291 a = strcmp( ava_in->la_value->bv_val,
292 ava->la_value->bv_val );
298 for ( j = iAVA; j > i; j-- ) {
299 rdn[ j ][ 0 ] = rdn[ j - 1 ][ 0 ];
301 rdn[ i ][ 0 ] = ava_in;
308 * In-place normalization of the structural representation
309 * of a distinguished name
312 DN_Normalize( LDAPDN *dn )
319 for ( iRDN = 0; dn[ iRDN ]; iRDN++ ) {
320 LDAPRDN *rdn = dn[ iRDN ][ 0 ];
323 for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) {
324 LDAPAVA *ava = rdn[ iAVA ][ 0 ];
325 AttributeDescription *ad = NULL;
326 const char *text = NULL;
327 slap_syntax_transform_func *nf = NULL;
328 struct berval *bv = NULL;
330 rc = slap_bv2ad( ava->la_attr, &ad, &text );
331 if ( rc != LDAP_SUCCESS ) {
332 return( LDAP_INVALID_SYNTAX );
336 * FIXME: is this required?
338 ber_bvfree( ava->la_attr );
339 ava->la_attr = ber_bvdup( &ad->ad_cname );
342 * FIXME: What is this intended for?
344 nf = ad->ad_type->sat_syntax->ssyn_normalize;
349 rc = ( *nf )( ad->ad_type->sat_syntax,
350 ava->la_value, &bv );
352 if ( rc != LDAP_SUCCESS ) {
353 return( LDAP_INVALID_SYNTAX );
357 * FIXME: shouldn't this happen inside
358 * ssyn_normalize if the syntax is case
361 if ( !( ava->la_flags & LDAP_AVA_BINARY ) ) {
362 struct berval *s = bv;
364 bv = ber_bvstr( UTF8normalize( bv,
369 ber_bvfree( ava->la_value );
372 AVA_Sort( rdn, iAVA );
376 return( LDAP_SUCCESS );
383 struct berval **normalized )
385 struct berval *out = NULL;
387 Debug( LDAP_DEBUG_TRACE, ">>> dnNormalize: %s\n", val->bv_val, 0, 0 );
389 if ( val->bv_len != 0 ) {
395 * Go to structural representation
397 rc = ldap_str2dn( val->bv_val, &dn, LDAP_DN_FORMAT_LDAPV3 );
398 if ( rc != LDAP_SUCCESS ) {
399 return( LDAP_INVALID_SYNTAX );
403 * Add schema-aware normalization stuff
405 if ( DN_Normalize( dn ) != LDAP_SUCCESS ) {
410 * Back to string representation
412 rc = ldap_dn2str( dn, &dn_out, LDAP_DN_FORMAT_LDAPV3 );
414 if ( rc != LDAP_SUCCESS ) {
416 ldapava_free_dn( dn );
417 return( LDAP_INVALID_SYNTAX );
420 ldapava_free_dn( dn );
422 out = ber_bvstr( dn_out );
425 out = ber_bvdup( val );
428 Debug( LDAP_DEBUG_TRACE, "<<< dnNormalize: %s\n", out->bv_val, 0, 0 );
432 return( LDAP_SUCCESS );
439 struct berval **pretty)
441 struct berval *out = NULL;
443 if ( val->bv_len != 0 ) {
448 /* FIXME: should be liberal in what we accept */
449 rc = ldap_str2dn( val->bv_val, &dn, LDAP_DN_FORMAT_LDAPV3 );
450 if ( rc != LDAP_SUCCESS ) {
451 return( LDAP_INVALID_SYNTAX );
454 /* Add LDAPDN pretty code here
455 * pretty'ing MUST preserve values
456 * but MAY use alternative representation of value.
458 * That is, in addition to changes made by the
459 * str->LDAPDN->str processing, this code can
460 * convert values from BER to LDAP string representation
461 * (or other direction if appropriate)
463 * normalize attribute descriptions
464 * reorder AVAs in RDNs
467 /* FIXME: not sure why the default isn't pretty */
468 rc = ldap_dn2str( dn, &dn_out,
469 LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY );
470 ldapava_free_dn( dn );
472 if ( rc != LDAP_SUCCESS ) {
473 return( LDAP_INVALID_SYNTAX );
476 out = ber_bvstr( dn_out );
479 out = ber_bvdup( val );
484 return( LDAP_SUCCESS );
493 struct berval *value,
494 void *assertedValue )
497 struct berval *asserted = (struct berval *) assertedValue;
499 match = value->bv_len - asserted->bv_len;
502 #ifdef USE_DN_NORMALIZE
503 match = strcmp( value->bv_val, asserted->bv_val );
504 fprintf(stderr, "USE_DN_NORMALIZE :(\n");
506 match = strcasecmp( value->bv_val, asserted->bv_val );
507 fprintf(stderr, "!USE_DN_NORMALIZE :)\n");
512 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
513 "dnMatch: %d\n %s\n %s\n", match,
514 value->bv_val, asserted->bv_val ));
516 Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
517 match, value->bv_val, asserted->bv_val );
521 return( LDAP_SUCCESS );
524 #else /* !USE_LDAP_DN_PARSING */
534 if( in->bv_len == 0 ) return LDAP_SUCCESS;
536 dn = ch_strdup( in->bv_val );
539 return LDAP_INVALID_SYNTAX;
541 } else if ( strlen( in->bv_val ) != in->bv_len ) {
542 rc = LDAP_INVALID_SYNTAX;
544 } else if ( dn_validate( dn ) == NULL ) {
545 rc = LDAP_INVALID_SYNTAX;
559 struct berval **normalized )
563 if ( val->bv_len != 0 ) {
565 out = ber_bvstr( UTF8normalize( val, UTF8_CASEFOLD ) );
567 dn = dn_validate( out->bv_val );
571 return LDAP_INVALID_SYNTAX;
575 out->bv_len = strlen( dn );
577 out = ber_bvdup( val );
590 struct berval *value,
591 void *assertedValue )
594 struct berval *asserted = (struct berval *) assertedValue;
596 match = value->bv_len - asserted->bv_len;
599 #ifdef USE_DN_NORMALIZE
600 match = strcmp( value->bv_val, asserted->bv_val );
602 match = strcasecmp( value->bv_val, asserted->bv_val );
607 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
608 "dnMatch: %d\n %s\n %s\n", match,
609 value->bv_val, asserted->bv_val ));
611 Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
612 match, value->bv_val, asserted->bv_val );
620 #endif /* !USE_LDAP_DN_PARSING */
630 if( in->bv_len == 0 ) return LDAP_SUCCESS;
632 dn = ber_bvdup( in );
634 if( dn->bv_val[dn->bv_len-1] == '\'' ) {
635 /* assume presence of optional UID */
638 for(i=dn->bv_len-2; i>2; i--) {
639 if( dn->bv_val[i] != '0' && dn->bv_val[i] != '1' ) {
643 if( dn->bv_val[i] != '\'' ||
644 dn->bv_val[i-1] != 'B' ||
645 dn->bv_val[i-2] != '#' ) {
647 return LDAP_INVALID_SYNTAX;
650 /* trim the UID to allow use of dn_validate */
651 dn->bv_val[i-2] = '\0';
654 rc = dn_validate( dn->bv_val ) == NULL
655 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
665 struct berval **normalized )
667 struct berval *out = ber_bvdup( val );
669 if( out->bv_len != 0 ) {
673 ber_len_t uidlen = 0;
675 if( out->bv_val[out->bv_len-1] == '\'' ) {
676 /* assume presence of optional UID */
677 uid = strrchr( out->bv_val, '#' );
681 return LDAP_INVALID_SYNTAX;
684 uidlen = out->bv_len - (out->bv_val - uid);
685 /* temporarily trim the UID */
689 #ifdef USE_DN_NORMALIZE
690 dn = dn_normalize( out->bv_val );
692 dn = dn_validate( out->bv_val );
697 return LDAP_INVALID_SYNTAX;
703 /* restore the separator */
706 SAFEMEMCPY( &dn[dnlen], uid, uidlen );
710 out->bv_len = dnlen + uidlen;
722 /* any value allowed */
731 /* any value allowed */
742 /* very unforgiving validation, requires no normalization
743 * before simplistic matching
745 if( in->bv_len < 3 ) {
746 return LDAP_INVALID_SYNTAX;
750 * rfc 2252 section 6.3 Bit String
751 * bitstring = "'" *binary-digit "'"
752 * binary-digit = "0" / "1"
753 * example: '0101111101'B
756 if( in->bv_val[0] != '\'' ||
757 in->bv_val[in->bv_len-2] != '\'' ||
758 in->bv_val[in->bv_len-1] != 'B' )
760 return LDAP_INVALID_SYNTAX;
763 for( i=in->bv_len-3; i>0; i-- ) {
764 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
765 return LDAP_INVALID_SYNTAX;
776 struct berval **normalized )
779 * A normalized bitString is has no extaneous (leading) zero bits.
780 * That is, '00010'B is normalized to '10'B
781 * However, as a special case, '0'B requires no normalization.
783 struct berval *newval;
786 /* start at the first bit */
789 /* Find the first non-zero bit */
790 while ( *p == '0' ) p++;
792 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
795 /* no non-zero bits */
796 newval->bv_val = ch_strdup("\'0\'B");
797 newval->bv_len = sizeof("\'0\'B") - 1;
801 newval->bv_val = ch_malloc( val->bv_len + 1 );
803 newval->bv_val[0] = '\'';
806 for( ; *p != '\0'; p++ ) {
807 newval->bv_val[newval->bv_len++] = *p;
810 newval->bv_val[newval->bv_len] = '\0';
813 *normalized = newval;
818 * Handling boolean syntax and matching is quite rigid.
819 * A more flexible approach would be to allow a variety
820 * of strings to be normalized and prettied into TRUE
828 /* very unforgiving validation, requires no normalization
829 * before simplistic matching
832 if( in->bv_len == 4 ) {
833 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
836 } else if( in->bv_len == 5 ) {
837 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
842 return LDAP_INVALID_SYNTAX;
851 struct berval *value,
852 void *assertedValue )
854 /* simplistic matching allowed by rigid validation */
855 struct berval *asserted = (struct berval *) assertedValue;
856 *matchp = value->bv_len != asserted->bv_len;
867 unsigned char *u = in->bv_val;
869 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
871 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
872 /* get the length indicated by the first byte */
873 len = LDAP_UTF8_CHARLEN( u );
875 /* should not be zero */
876 if( len == 0 ) return LDAP_INVALID_SYNTAX;
878 /* make sure len corresponds with the offset
879 to the next character */
880 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
883 if( count != 0 ) return LDAP_INVALID_SYNTAX;
892 struct berval **normalized )
894 struct berval *newval;
897 newval = ch_malloc( sizeof( struct berval ) );
901 /* Ignore initial whitespace */
902 while ( ldap_utf8_isspace( p ) ) {
908 return LDAP_INVALID_SYNTAX;
911 newval->bv_val = ch_strdup( p );
912 p = q = newval->bv_val;
918 if ( ldap_utf8_isspace( p ) ) {
919 len = LDAP_UTF8_COPY(q,p);
924 /* Ignore the extra whitespace */
925 while ( ldap_utf8_isspace( p ) ) {
929 len = LDAP_UTF8_COPY(q,p);
936 assert( *newval->bv_val );
937 assert( newval->bv_val < p );
940 /* cannot start with a space */
941 assert( !ldap_utf8_isspace(newval->bv_val) );
944 * If the string ended in space, backup the pointer one
945 * position. One is enough because the above loop collapsed
946 * all whitespace to a single space.
953 /* cannot end with a space */
954 assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
959 newval->bv_len = q - newval->bv_val;
960 *normalized = newval;
965 /* Returns Unicode cannonically normalized copy of a substring assertion
966 * Skipping attribute description */
967 SubstringsAssertion *
968 UTF8SubstringsassertionNormalize(
969 SubstringsAssertion *sa,
972 SubstringsAssertion *nsa;
975 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
980 if( sa->sa_initial != NULL ) {
981 nsa->sa_initial = ber_bvstr( UTF8normalize( sa->sa_initial, casefold ) );
982 if( nsa->sa_initial == NULL ) {
987 if( sa->sa_any != NULL ) {
988 for( i=0; sa->sa_any[i] != NULL; i++ ) {
991 nsa->sa_any = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
992 for( i=0; sa->sa_any[i] != NULL; i++ ) {
993 nsa->sa_any[i] = ber_bvstr( UTF8normalize( sa->sa_any[i], casefold ) );
994 if( nsa->sa_any[i] == NULL ) {
998 nsa->sa_any[i] = NULL;
1001 if( sa->sa_final != NULL ) {
1002 nsa->sa_final = ber_bvstr( UTF8normalize( sa->sa_final, casefold ) );
1003 if( nsa->sa_final == NULL ) {
1011 ber_bvfree( nsa->sa_final );
1012 ber_bvecfree( nsa->sa_any );
1013 ber_bvfree( nsa->sa_initial );
1018 /* Strip characters with the 8th bit set */
1031 while( *++q & 0x80 ) {
1034 p = memmove(p, q, strlen(q) + 1);
1042 #ifndef SLAPD_APPROX_OLDSINGLESTRING
1044 #if defined(SLAPD_APPROX_INITIALS)
1045 #define SLAPD_APPROX_DELIMITER "._ "
1046 #define SLAPD_APPROX_WORDLEN 2
1048 #define SLAPD_APPROX_DELIMITER " "
1049 #define SLAPD_APPROX_WORDLEN 1
1058 struct berval *value,
1059 void *assertedValue )
1061 char *val, *nval, *assertv, **values, **words, *c;
1062 int i, count, len, nextchunk=0, nextavail=0;
1065 /* Yes, this is necessary */
1066 nval = UTF8normalize( value, UTF8_NOCASEFOLD );
1067 if( nval == NULL ) {
1069 return LDAP_SUCCESS;
1071 strip8bitChars( nval );
1073 /* Yes, this is necessary */
1074 assertv = UTF8normalize( ((struct berval *)assertedValue),
1076 if( assertv == NULL ) {
1079 return LDAP_SUCCESS;
1081 strip8bitChars( assertv );
1082 avlen = strlen( assertv );
1084 /* Isolate how many words there are */
1085 for( c=nval,count=1; *c; c++ ) {
1086 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
1087 if ( c == NULL ) break;
1092 /* Get a phonetic copy of each word */
1093 words = (char **)ch_malloc( count * sizeof(char *) );
1094 values = (char **)ch_malloc( count * sizeof(char *) );
1095 for( c=nval,i=0; i<count; i++,c+=strlen(c)+1 ) {
1097 values[i] = phonetic(c);
1100 /* Work through the asserted value's words, to see if at least some
1101 of the words are there, in the same order. */
1103 while ( nextchunk < avlen ) {
1104 len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER);
1109 #if defined(SLAPD_APPROX_INITIALS)
1110 else if( len == 1 ) {
1111 /* Single letter words need to at least match one word's initial */
1112 for( i=nextavail; i<count; i++ )
1113 if( !strncasecmp( assertv+nextchunk, words[i], 1 )) {
1120 /* Isolate the next word in the asserted value and phonetic it */
1121 assertv[nextchunk+len] = '\0';
1122 val = phonetic( assertv + nextchunk );
1124 /* See if this phonetic chunk is in the remaining words of *value */
1125 for( i=nextavail; i<count; i++ ){
1126 if( !strcmp( val, values[i] ) ){
1134 /* This chunk in the asserted value was NOT within the *value. */
1140 /* Go on to the next word in the asserted value */
1144 /* If some of the words were seen, call it a match */
1145 if( nextavail > 0 ) {
1152 /* Cleanup allocs */
1154 for( i=0; i<count; i++ ) {
1155 ch_free( values[i] );
1161 return LDAP_SUCCESS;
1170 struct berval *prefix,
1171 struct berval **values,
1172 struct berval ***keysp )
1175 int i,j, len, wordcount, keycount=0;
1176 struct berval **newkeys, **keys=NULL;
1178 for( j=0; values[j] != NULL; j++ ) {
1179 /* Yes, this is necessary */
1180 val = UTF8normalize( values[j], UTF8_NOCASEFOLD );
1181 strip8bitChars( val );
1183 /* Isolate how many words there are. There will be a key for each */
1184 for( wordcount=0,c=val; *c; c++) {
1185 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1186 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1188 if (*c == '\0') break;
1192 /* Allocate/increase storage to account for new keys */
1193 newkeys = (struct berval **)ch_malloc( (keycount + wordcount + 1)
1194 * sizeof(struct berval *) );
1195 memcpy( newkeys, keys, keycount * sizeof(struct berval *) );
1196 if( keys ) ch_free( keys );
1199 /* Get a phonetic copy of each word */
1200 for( c=val,i=0; i<wordcount; c+=len+1 ) {
1202 if( len < SLAPD_APPROX_WORDLEN ) continue;
1203 keys[keycount] = (struct berval *)ch_malloc( sizeof(struct berval) );
1204 keys[keycount]->bv_val = phonetic( c );
1205 keys[keycount]->bv_len = strlen( keys[keycount]->bv_val );
1212 keys[keycount] = NULL;
1215 return LDAP_SUCCESS;
1224 struct berval *prefix,
1226 struct berval ***keysp )
1230 struct berval **keys;
1232 /* Yes, this is necessary */
1233 val = UTF8normalize( ((struct berval *)assertValue),
1236 keys = (struct berval **)ch_malloc( sizeof(struct berval *) );
1239 return LDAP_SUCCESS;
1241 strip8bitChars( val );
1243 /* Isolate how many words there are. There will be a key for each */
1244 for( count=0,c=val; *c; c++) {
1245 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1246 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1248 if (*c == '\0') break;
1252 /* Allocate storage for new keys */
1253 keys = (struct berval **)ch_malloc( (count + 1) * sizeof(struct berval *) );
1255 /* Get a phonetic copy of each word */
1256 for( c=val,i=0; i<count; c+=len+1 ) {
1258 if( len < SLAPD_APPROX_WORDLEN ) continue;
1259 keys[i] = ber_bvstr( phonetic( c ) );
1268 return LDAP_SUCCESS;
1273 /* No other form of Approximate Matching is defined */
1281 struct berval *value,
1282 void *assertedValue )
1284 char *vapprox, *avapprox;
1287 /* Yes, this is necessary */
1288 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1291 return LDAP_SUCCESS;
1294 /* Yes, this is necessary */
1295 t = UTF8normalize( ((struct berval *)assertedValue),
1300 return LDAP_SUCCESS;
1303 vapprox = phonetic( strip8bitChars( s ) );
1304 avapprox = phonetic( strip8bitChars( t ) );
1309 *matchp = strcmp( vapprox, avapprox );
1312 ch_free( avapprox );
1314 return LDAP_SUCCESS;
1323 struct berval *prefix,
1324 struct berval **values,
1325 struct berval ***keysp )
1328 struct berval **keys;
1331 for( i=0; values[i] != NULL; i++ ) {
1332 /* empty - just count them */
1335 /* we should have at least one value at this point */
1338 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * (i+1) );
1340 /* Copy each value and run it through phonetic() */
1341 for( i=0; values[i] != NULL; i++ ) {
1342 /* Yes, this is necessary */
1343 s = UTF8normalize( values[i], UTF8_NOCASEFOLD );
1345 /* strip 8-bit chars and run through phonetic() */
1346 keys[i] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1352 return LDAP_SUCCESS;
1362 struct berval *prefix,
1364 struct berval ***keysp )
1366 struct berval **keys;
1369 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * 2 );
1371 /* Yes, this is necessary */
1372 s = UTF8normalize( ((struct berval *)assertValue),
1377 /* strip 8-bit chars and run through phonetic() */
1378 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1384 return LDAP_SUCCESS;
1395 struct berval *value,
1396 void *assertedValue )
1398 *matchp = UTF8normcmp( value->bv_val,
1399 ((struct berval *) assertedValue)->bv_val,
1401 return LDAP_SUCCESS;
1405 caseExactIgnoreSubstringsMatch(
1410 struct berval *value,
1411 void *assertedValue )
1414 SubstringsAssertion *sub = NULL;
1418 char *nav, casefold;
1420 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1421 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1423 nav = UTF8normalize( value, casefold );
1429 left.bv_len = strlen( nav );
1431 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1437 /* Add up asserted input length */
1438 if( sub->sa_initial ) {
1439 inlen += sub->sa_initial->bv_len;
1442 for(i=0; sub->sa_any[i] != NULL; i++) {
1443 inlen += sub->sa_any[i]->bv_len;
1446 if( sub->sa_final ) {
1447 inlen += sub->sa_final->bv_len;
1450 if( sub->sa_initial ) {
1451 if( inlen > left.bv_len ) {
1456 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
1457 sub->sa_initial->bv_len );
1463 left.bv_val += sub->sa_initial->bv_len;
1464 left.bv_len -= sub->sa_initial->bv_len;
1465 inlen -= sub->sa_initial->bv_len;
1468 if( sub->sa_final ) {
1469 if( inlen > left.bv_len ) {
1474 match = strncmp( sub->sa_final->bv_val,
1475 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
1476 sub->sa_final->bv_len );
1482 left.bv_len -= sub->sa_final->bv_len;
1483 inlen -= sub->sa_final->bv_len;
1487 for(i=0; sub->sa_any[i]; i++) {
1492 if( inlen > left.bv_len ) {
1493 /* not enough length */
1498 if( sub->sa_any[i]->bv_len == 0 ) {
1502 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
1509 idx = p - left.bv_val;
1510 assert( idx < left.bv_len );
1512 if( idx >= left.bv_len ) {
1513 /* this shouldn't happen */
1515 ch_free( sub->sa_final );
1516 ber_bvecfree( sub->sa_any );
1517 ch_free( sub->sa_initial );
1525 if( sub->sa_any[i]->bv_len > left.bv_len ) {
1526 /* not enough left */
1531 match = strncmp( left.bv_val,
1532 sub->sa_any[i]->bv_val,
1533 sub->sa_any[i]->bv_len );
1541 left.bv_val += sub->sa_any[i]->bv_len;
1542 left.bv_len -= sub->sa_any[i]->bv_len;
1543 inlen -= sub->sa_any[i]->bv_len;
1550 ber_bvfree( sub->sa_final );
1551 ber_bvecfree( sub->sa_any );
1552 ber_bvfree( sub->sa_initial );
1556 return LDAP_SUCCESS;
1559 /* Index generation function */
1560 int caseExactIgnoreIndexer(
1565 struct berval *prefix,
1566 struct berval **values,
1567 struct berval ***keysp )
1572 struct berval **keys;
1573 HASH_CONTEXT HASHcontext;
1574 unsigned char HASHdigest[HASH_BYTES];
1575 struct berval digest;
1576 digest.bv_val = HASHdigest;
1577 digest.bv_len = sizeof(HASHdigest);
1579 for( i=0; values[i] != NULL; i++ ) {
1580 /* empty - just count them */
1583 /* we should have at least one value at this point */
1586 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
1588 slen = strlen( syntax->ssyn_oid );
1589 mlen = strlen( mr->smr_oid );
1591 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1592 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1594 for( i=0; values[i] != NULL; i++ ) {
1595 struct berval *value;
1596 value = ber_bvstr( UTF8normalize( values[i],
1599 HASH_Init( &HASHcontext );
1600 if( prefix != NULL && prefix->bv_len > 0 ) {
1601 HASH_Update( &HASHcontext,
1602 prefix->bv_val, prefix->bv_len );
1604 HASH_Update( &HASHcontext,
1605 syntax->ssyn_oid, slen );
1606 HASH_Update( &HASHcontext,
1607 mr->smr_oid, mlen );
1608 HASH_Update( &HASHcontext,
1609 value->bv_val, value->bv_len );
1610 HASH_Final( HASHdigest, &HASHcontext );
1612 ber_bvfree( value );
1614 keys[i] = ber_bvdup( &digest );
1619 return LDAP_SUCCESS;
1622 /* Index generation function */
1623 int caseExactIgnoreFilter(
1628 struct berval *prefix,
1630 struct berval ***keysp )
1634 struct berval **keys;
1635 HASH_CONTEXT HASHcontext;
1636 unsigned char HASHdigest[HASH_BYTES];
1637 struct berval *value;
1638 struct berval digest;
1639 digest.bv_val = HASHdigest;
1640 digest.bv_len = sizeof(HASHdigest);
1642 slen = strlen( syntax->ssyn_oid );
1643 mlen = strlen( mr->smr_oid );
1645 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1646 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1648 value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue),
1650 /* This usually happens if filter contains bad UTF8 */
1651 if( value == NULL ) {
1652 keys = ch_malloc( sizeof( struct berval * ) );
1654 return LDAP_SUCCESS;
1657 keys = ch_malloc( sizeof( struct berval * ) * 2 );
1659 HASH_Init( &HASHcontext );
1660 if( prefix != NULL && prefix->bv_len > 0 ) {
1661 HASH_Update( &HASHcontext,
1662 prefix->bv_val, prefix->bv_len );
1664 HASH_Update( &HASHcontext,
1665 syntax->ssyn_oid, slen );
1666 HASH_Update( &HASHcontext,
1667 mr->smr_oid, mlen );
1668 HASH_Update( &HASHcontext,
1669 value->bv_val, value->bv_len );
1670 HASH_Final( HASHdigest, &HASHcontext );
1672 keys[0] = ber_bvdup( &digest );
1675 ber_bvfree( value );
1678 return LDAP_SUCCESS;
1681 /* Substrings Index generation function */
1682 int caseExactIgnoreSubstringsIndexer(
1687 struct berval *prefix,
1688 struct berval **values,
1689 struct berval ***keysp )
1694 struct berval **keys;
1695 struct berval **nvalues;
1697 HASH_CONTEXT HASHcontext;
1698 unsigned char HASHdigest[HASH_BYTES];
1699 struct berval digest;
1700 digest.bv_val = HASHdigest;
1701 digest.bv_len = sizeof(HASHdigest);
1705 for( i=0; values[i] != NULL; i++ ) {
1706 /* empty - just count them */
1709 /* we should have at least one value at this point */
1712 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1713 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1715 nvalues = ch_malloc( sizeof( struct berval * ) * (i+1) );
1716 for( i=0; values[i] != NULL; i++ ) {
1717 nvalues[i] = ber_bvstr( UTF8normalize( values[i],
1723 for( i=0; values[i] != NULL; i++ ) {
1724 /* count number of indices to generate */
1725 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1729 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1730 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1731 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1732 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1734 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1738 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1739 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1740 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1744 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1745 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1746 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1747 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1749 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1755 /* no keys to generate */
1757 ber_bvecfree( nvalues );
1758 return LDAP_SUCCESS;
1761 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1763 slen = strlen( syntax->ssyn_oid );
1764 mlen = strlen( mr->smr_oid );
1767 for( i=0; values[i] != NULL; i++ ) {
1769 struct berval *value;
1771 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1775 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1776 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1778 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1779 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1781 for( j=0; j<max; j++ ) {
1782 HASH_Init( &HASHcontext );
1783 if( prefix != NULL && prefix->bv_len > 0 ) {
1784 HASH_Update( &HASHcontext,
1785 prefix->bv_val, prefix->bv_len );
1788 HASH_Update( &HASHcontext,
1789 &pre, sizeof( pre ) );
1790 HASH_Update( &HASHcontext,
1791 syntax->ssyn_oid, slen );
1792 HASH_Update( &HASHcontext,
1793 mr->smr_oid, mlen );
1794 HASH_Update( &HASHcontext,
1796 SLAP_INDEX_SUBSTR_MAXLEN );
1797 HASH_Final( HASHdigest, &HASHcontext );
1799 keys[nkeys++] = ber_bvdup( &digest );
1803 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1804 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1806 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1809 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1810 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1811 HASH_Init( &HASHcontext );
1812 if( prefix != NULL && prefix->bv_len > 0 ) {
1813 HASH_Update( &HASHcontext,
1814 prefix->bv_val, prefix->bv_len );
1816 HASH_Update( &HASHcontext,
1817 &pre, sizeof( pre ) );
1818 HASH_Update( &HASHcontext,
1819 syntax->ssyn_oid, slen );
1820 HASH_Update( &HASHcontext,
1821 mr->smr_oid, mlen );
1822 HASH_Update( &HASHcontext,
1824 HASH_Final( HASHdigest, &HASHcontext );
1826 keys[nkeys++] = ber_bvdup( &digest );
1829 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1830 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1831 HASH_Init( &HASHcontext );
1832 if( prefix != NULL && prefix->bv_len > 0 ) {
1833 HASH_Update( &HASHcontext,
1834 prefix->bv_val, prefix->bv_len );
1836 HASH_Update( &HASHcontext,
1837 &pre, sizeof( pre ) );
1838 HASH_Update( &HASHcontext,
1839 syntax->ssyn_oid, slen );
1840 HASH_Update( &HASHcontext,
1841 mr->smr_oid, mlen );
1842 HASH_Update( &HASHcontext,
1843 &value->bv_val[value->bv_len-j], j );
1844 HASH_Final( HASHdigest, &HASHcontext );
1846 keys[nkeys++] = ber_bvdup( &digest );
1861 ber_bvecfree( nvalues );
1863 return LDAP_SUCCESS;
1866 int caseExactIgnoreSubstringsFilter(
1871 struct berval *prefix,
1873 struct berval ***keysp )
1875 SubstringsAssertion *sa;
1877 ber_len_t nkeys = 0;
1878 size_t slen, mlen, klen;
1879 struct berval **keys;
1880 HASH_CONTEXT HASHcontext;
1881 unsigned char HASHdigest[HASH_BYTES];
1882 struct berval *value;
1883 struct berval digest;
1885 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1886 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1888 sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
1891 return LDAP_SUCCESS;
1894 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1895 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1900 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1902 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1903 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1904 /* don't bother accounting for stepping */
1905 nkeys += sa->sa_any[i]->bv_len -
1906 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1911 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1912 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1918 ber_bvfree( sa->sa_final );
1919 ber_bvecfree( sa->sa_any );
1920 ber_bvfree( sa->sa_initial );
1923 return LDAP_SUCCESS;
1926 digest.bv_val = HASHdigest;
1927 digest.bv_len = sizeof(HASHdigest);
1929 slen = strlen( syntax->ssyn_oid );
1930 mlen = strlen( mr->smr_oid );
1932 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1935 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1936 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1938 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1939 value = sa->sa_initial;
1941 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1942 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1944 HASH_Init( &HASHcontext );
1945 if( prefix != NULL && prefix->bv_len > 0 ) {
1946 HASH_Update( &HASHcontext,
1947 prefix->bv_val, prefix->bv_len );
1949 HASH_Update( &HASHcontext,
1950 &pre, sizeof( pre ) );
1951 HASH_Update( &HASHcontext,
1952 syntax->ssyn_oid, slen );
1953 HASH_Update( &HASHcontext,
1954 mr->smr_oid, mlen );
1955 HASH_Update( &HASHcontext,
1956 value->bv_val, klen );
1957 HASH_Final( HASHdigest, &HASHcontext );
1959 keys[nkeys++] = ber_bvdup( &digest );
1962 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1964 pre = SLAP_INDEX_SUBSTR_PREFIX;
1965 klen = SLAP_INDEX_SUBSTR_MAXLEN;
1967 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1968 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
1972 value = sa->sa_any[i];
1975 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
1976 j += SLAP_INDEX_SUBSTR_STEP )
1978 HASH_Init( &HASHcontext );
1979 if( prefix != NULL && prefix->bv_len > 0 ) {
1980 HASH_Update( &HASHcontext,
1981 prefix->bv_val, prefix->bv_len );
1983 HASH_Update( &HASHcontext,
1984 &pre, sizeof( pre ) );
1985 HASH_Update( &HASHcontext,
1986 syntax->ssyn_oid, slen );
1987 HASH_Update( &HASHcontext,
1988 mr->smr_oid, mlen );
1989 HASH_Update( &HASHcontext,
1990 &value->bv_val[j], klen );
1991 HASH_Final( HASHdigest, &HASHcontext );
1993 keys[nkeys++] = ber_bvdup( &digest );
1999 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2000 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2002 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2003 value = sa->sa_final;
2005 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2006 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2008 HASH_Init( &HASHcontext );
2009 if( prefix != NULL && prefix->bv_len > 0 ) {
2010 HASH_Update( &HASHcontext,
2011 prefix->bv_val, prefix->bv_len );
2013 HASH_Update( &HASHcontext,
2014 &pre, sizeof( pre ) );
2015 HASH_Update( &HASHcontext,
2016 syntax->ssyn_oid, slen );
2017 HASH_Update( &HASHcontext,
2018 mr->smr_oid, mlen );
2019 HASH_Update( &HASHcontext,
2020 &value->bv_val[value->bv_len-klen], klen );
2021 HASH_Final( HASHdigest, &HASHcontext );
2023 keys[nkeys++] = ber_bvdup( &digest );
2033 ber_bvfree( sa->sa_final );
2034 ber_bvecfree( sa->sa_any );
2035 ber_bvfree( sa->sa_initial );
2038 return LDAP_SUCCESS;
2047 struct berval *value,
2048 void *assertedValue )
2050 *matchp = UTF8normcmp( value->bv_val,
2051 ((struct berval *) assertedValue)->bv_val,
2053 return LDAP_SUCCESS;
2059 struct berval *val )
2063 if( val->bv_len == 0 ) {
2064 /* disallow empty strings */
2065 return LDAP_INVALID_SYNTAX;
2068 if( OID_LEADCHAR(val->bv_val[0]) ) {
2070 for(i=1; i < val->bv_len; i++) {
2071 if( OID_SEPARATOR( val->bv_val[i] ) ) {
2072 if( dot++ ) return 1;
2073 } else if ( OID_CHAR( val->bv_val[i] ) ) {
2076 return LDAP_INVALID_SYNTAX;
2080 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
2082 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
2083 for(i=1; i < val->bv_len; i++) {
2084 if( !DESC_CHAR(val->bv_val[i] ) ) {
2085 return LDAP_INVALID_SYNTAX;
2089 return LDAP_SUCCESS;
2092 return LDAP_INVALID_SYNTAX;
2101 struct berval *value,
2102 void *assertedValue )
2105 int vsign=0, avsign=0;
2106 struct berval *asserted;
2107 ber_len_t vlen, avlen;
2110 /* Start off pessimistic */
2113 /* Skip past leading spaces/zeros, and get the sign of the *value number */
2115 vlen = value->bv_len;
2117 if( ASCII_SPACE(*v) || ( *v == '0' )) {
2118 /* empty -- skip spaces */
2120 else if ( *v == '+' ) {
2123 else if ( *v == '-' ) {
2126 else if ( ASCII_DIGIT(*v) ) {
2127 if ( vsign == 0 ) vsign = 1;
2135 /* Skip past leading spaces/zeros, and get the sign of the *assertedValue
2137 asserted = (struct berval *) assertedValue;
2138 av = asserted->bv_val;
2139 avlen = asserted->bv_len;
2141 if( ASCII_SPACE(*av) || ( *av == '0' )) {
2142 /* empty -- skip spaces */
2144 else if ( *av == '+' ) {
2147 else if ( *av == '-' ) {
2150 else if ( ASCII_DIGIT(*av) ) {
2151 if ( avsign == 0 ) avsign = 1;
2159 /* The two ?sign vars are now one of :
2160 -2 negative non-zero number
2162 0 0 collapse these three to 0
2164 +2 positive non-zero number
2166 if ( abs( vsign ) == 1 ) vsign = 0;
2167 if ( abs( avsign ) == 1 ) avsign = 0;
2169 if( vsign != avsign ) return LDAP_SUCCESS;
2171 /* Check the significant digits */
2172 while( vlen && avlen ) {
2173 if( *v != *av ) break;
2180 /* If all digits compared equal, the numbers are equal */
2181 if(( vlen == 0 ) && ( avlen == 0 )) {
2184 return LDAP_SUCCESS;
2190 struct berval *val )
2194 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2196 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2197 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2198 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2199 return LDAP_INVALID_SYNTAX;
2202 for( i=1; i < val->bv_len; i++ ) {
2203 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2206 return LDAP_SUCCESS;
2213 struct berval **normalized )
2217 struct berval *newval;
2224 /* Ignore leading spaces */
2225 while ( len && ( *p == ' ' )) {
2232 negative = ( *p == '-' );
2233 if(( *p == '-' ) || ( *p == '+' )) {
2239 /* Ignore leading zeros */
2240 while ( len && ( *p == '0' )) {
2245 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
2247 /* If there are no non-zero digits left, the number is zero, otherwise
2248 allocate space for the number and copy it into the buffer */
2250 newval->bv_val = ch_strdup("0");
2254 newval->bv_len = len+negative;
2255 newval->bv_val = ch_malloc( newval->bv_len );
2257 newval->bv_val[0] = '-';
2259 memcpy( newval->bv_val + negative, p, len );
2262 *normalized = newval;
2263 return LDAP_SUCCESS;
2266 /* Index generation function */
2272 struct berval *prefix,
2273 struct berval **values,
2274 struct berval ***keysp )
2277 struct berval **keys;
2279 /* we should have at least one value at this point */
2280 assert( values != NULL && values[0] != NULL );
2282 for( i=0; values[i] != NULL; i++ ) {
2283 /* empty -- just count them */
2286 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2288 for( i=0; values[i] != NULL; i++ ) {
2289 integerNormalize( syntax, values[i], &keys[i] );
2294 return LDAP_SUCCESS;
2297 /* Index generation function */
2303 struct berval *prefix,
2305 struct berval ***keysp )
2307 struct berval **keys;
2309 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2310 integerNormalize( syntax, assertValue, &keys[0] );
2314 return LDAP_SUCCESS;
2319 countryStringValidate(
2321 struct berval *val )
2323 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2325 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2326 return LDAP_INVALID_SYNTAX;
2328 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2329 return LDAP_INVALID_SYNTAX;
2332 return LDAP_SUCCESS;
2336 printableStringValidate(
2338 struct berval *val )
2342 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2344 for(i=0; i < val->bv_len; i++) {
2345 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2346 return LDAP_INVALID_SYNTAX;
2350 return LDAP_SUCCESS;
2354 printablesStringValidate(
2356 struct berval *val )
2360 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2362 for(i=0; i < val->bv_len; i++) {
2363 if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
2364 return LDAP_INVALID_SYNTAX;
2368 return LDAP_SUCCESS;
2374 struct berval *val )
2378 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2380 for(i=0; i < val->bv_len; i++) {
2381 if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2384 return LDAP_SUCCESS;
2391 struct berval **normalized )
2393 struct berval *newval;
2396 newval = ch_malloc( sizeof( struct berval ) );
2400 /* Ignore initial whitespace */
2401 while ( ASCII_SPACE( *p ) ) {
2407 return LDAP_INVALID_SYNTAX;
2410 newval->bv_val = ch_strdup( p );
2411 p = q = newval->bv_val;
2414 if ( ASCII_SPACE( *p ) ) {
2417 /* Ignore the extra whitespace */
2418 while ( ASCII_SPACE( *p ) ) {
2426 assert( *newval->bv_val );
2427 assert( newval->bv_val < p );
2430 /* cannot start with a space */
2431 assert( !ASCII_SPACE(*newval->bv_val) );
2434 * If the string ended in space, backup the pointer one
2435 * position. One is enough because the above loop collapsed
2436 * all whitespace to a single space.
2439 if ( ASCII_SPACE( q[-1] ) ) {
2443 /* cannot end with a space */
2444 assert( !ASCII_SPACE( q[-1] ) );
2446 /* null terminate */
2449 newval->bv_len = q - newval->bv_val;
2450 *normalized = newval;
2452 return LDAP_SUCCESS;
2461 struct berval *value,
2462 void *assertedValue )
2464 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2467 match = strncmp( value->bv_val,
2468 ((struct berval *) assertedValue)->bv_val,
2473 return LDAP_SUCCESS;
2477 caseExactIA5SubstringsMatch(
2482 struct berval *value,
2483 void *assertedValue )
2486 SubstringsAssertion *sub = assertedValue;
2487 struct berval left = *value;
2491 /* Add up asserted input length */
2492 if( sub->sa_initial ) {
2493 inlen += sub->sa_initial->bv_len;
2496 for(i=0; sub->sa_any[i] != NULL; i++) {
2497 inlen += sub->sa_any[i]->bv_len;
2500 if( sub->sa_final ) {
2501 inlen += sub->sa_final->bv_len;
2504 if( sub->sa_initial ) {
2505 if( inlen > left.bv_len ) {
2510 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
2511 sub->sa_initial->bv_len );
2517 left.bv_val += sub->sa_initial->bv_len;
2518 left.bv_len -= sub->sa_initial->bv_len;
2519 inlen -= sub->sa_initial->bv_len;
2522 if( sub->sa_final ) {
2523 if( inlen > left.bv_len ) {
2528 match = strncmp( sub->sa_final->bv_val,
2529 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2530 sub->sa_final->bv_len );
2536 left.bv_len -= sub->sa_final->bv_len;
2537 inlen -= sub->sa_final->bv_len;
2541 for(i=0; sub->sa_any[i]; i++) {
2546 if( inlen > left.bv_len ) {
2547 /* not enough length */
2552 if( sub->sa_any[i]->bv_len == 0 ) {
2556 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
2563 idx = p - left.bv_val;
2564 assert( idx < left.bv_len );
2566 if( idx >= left.bv_len ) {
2567 /* this shouldn't happen */
2574 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2575 /* not enough left */
2580 match = strncmp( left.bv_val,
2581 sub->sa_any[i]->bv_val,
2582 sub->sa_any[i]->bv_len );
2590 left.bv_val += sub->sa_any[i]->bv_len;
2591 left.bv_len -= sub->sa_any[i]->bv_len;
2592 inlen -= sub->sa_any[i]->bv_len;
2598 return LDAP_SUCCESS;
2601 /* Index generation function */
2602 int caseExactIA5Indexer(
2607 struct berval *prefix,
2608 struct berval **values,
2609 struct berval ***keysp )
2613 struct berval **keys;
2614 HASH_CONTEXT HASHcontext;
2615 unsigned char HASHdigest[HASH_BYTES];
2616 struct berval digest;
2617 digest.bv_val = HASHdigest;
2618 digest.bv_len = sizeof(HASHdigest);
2620 for( i=0; values[i] != NULL; i++ ) {
2621 /* empty - just count them */
2624 /* we should have at least one value at this point */
2627 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2629 slen = strlen( syntax->ssyn_oid );
2630 mlen = strlen( mr->smr_oid );
2632 for( i=0; values[i] != NULL; i++ ) {
2633 struct berval *value = values[i];
2635 HASH_Init( &HASHcontext );
2636 if( prefix != NULL && prefix->bv_len > 0 ) {
2637 HASH_Update( &HASHcontext,
2638 prefix->bv_val, prefix->bv_len );
2640 HASH_Update( &HASHcontext,
2641 syntax->ssyn_oid, slen );
2642 HASH_Update( &HASHcontext,
2643 mr->smr_oid, mlen );
2644 HASH_Update( &HASHcontext,
2645 value->bv_val, value->bv_len );
2646 HASH_Final( HASHdigest, &HASHcontext );
2648 keys[i] = ber_bvdup( &digest );
2653 return LDAP_SUCCESS;
2656 /* Index generation function */
2657 int caseExactIA5Filter(
2662 struct berval *prefix,
2664 struct berval ***keysp )
2667 struct berval **keys;
2668 HASH_CONTEXT HASHcontext;
2669 unsigned char HASHdigest[HASH_BYTES];
2670 struct berval *value;
2671 struct berval digest;
2672 digest.bv_val = HASHdigest;
2673 digest.bv_len = sizeof(HASHdigest);
2675 slen = strlen( syntax->ssyn_oid );
2676 mlen = strlen( mr->smr_oid );
2678 value = (struct berval *) assertValue;
2680 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2682 HASH_Init( &HASHcontext );
2683 if( prefix != NULL && prefix->bv_len > 0 ) {
2684 HASH_Update( &HASHcontext,
2685 prefix->bv_val, prefix->bv_len );
2687 HASH_Update( &HASHcontext,
2688 syntax->ssyn_oid, slen );
2689 HASH_Update( &HASHcontext,
2690 mr->smr_oid, mlen );
2691 HASH_Update( &HASHcontext,
2692 value->bv_val, value->bv_len );
2693 HASH_Final( HASHdigest, &HASHcontext );
2695 keys[0] = ber_bvdup( &digest );
2699 return LDAP_SUCCESS;
2702 /* Substrings Index generation function */
2703 int caseExactIA5SubstringsIndexer(
2708 struct berval *prefix,
2709 struct berval **values,
2710 struct berval ***keysp )
2714 struct berval **keys;
2715 HASH_CONTEXT HASHcontext;
2716 unsigned char HASHdigest[HASH_BYTES];
2717 struct berval digest;
2718 digest.bv_val = HASHdigest;
2719 digest.bv_len = sizeof(HASHdigest);
2721 /* we should have at least one value at this point */
2722 assert( values != NULL && values[0] != NULL );
2725 for( i=0; values[i] != NULL; i++ ) {
2726 /* count number of indices to generate */
2727 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2731 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2732 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2733 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2734 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2736 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2740 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2741 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2742 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2746 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2747 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2748 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2749 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2751 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2757 /* no keys to generate */
2759 return LDAP_SUCCESS;
2762 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2764 slen = strlen( syntax->ssyn_oid );
2765 mlen = strlen( mr->smr_oid );
2768 for( i=0; values[i] != NULL; i++ ) {
2770 struct berval *value;
2773 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2775 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2776 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2778 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2779 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2781 for( j=0; j<max; j++ ) {
2782 HASH_Init( &HASHcontext );
2783 if( prefix != NULL && prefix->bv_len > 0 ) {
2784 HASH_Update( &HASHcontext,
2785 prefix->bv_val, prefix->bv_len );
2788 HASH_Update( &HASHcontext,
2789 &pre, sizeof( pre ) );
2790 HASH_Update( &HASHcontext,
2791 syntax->ssyn_oid, slen );
2792 HASH_Update( &HASHcontext,
2793 mr->smr_oid, mlen );
2794 HASH_Update( &HASHcontext,
2796 SLAP_INDEX_SUBSTR_MAXLEN );
2797 HASH_Final( HASHdigest, &HASHcontext );
2799 keys[nkeys++] = ber_bvdup( &digest );
2803 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2804 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2806 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2809 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2810 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2811 HASH_Init( &HASHcontext );
2812 if( prefix != NULL && prefix->bv_len > 0 ) {
2813 HASH_Update( &HASHcontext,
2814 prefix->bv_val, prefix->bv_len );
2816 HASH_Update( &HASHcontext,
2817 &pre, sizeof( pre ) );
2818 HASH_Update( &HASHcontext,
2819 syntax->ssyn_oid, slen );
2820 HASH_Update( &HASHcontext,
2821 mr->smr_oid, mlen );
2822 HASH_Update( &HASHcontext,
2824 HASH_Final( HASHdigest, &HASHcontext );
2826 keys[nkeys++] = ber_bvdup( &digest );
2829 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2830 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2831 HASH_Init( &HASHcontext );
2832 if( prefix != NULL && prefix->bv_len > 0 ) {
2833 HASH_Update( &HASHcontext,
2834 prefix->bv_val, prefix->bv_len );
2836 HASH_Update( &HASHcontext,
2837 &pre, sizeof( pre ) );
2838 HASH_Update( &HASHcontext,
2839 syntax->ssyn_oid, slen );
2840 HASH_Update( &HASHcontext,
2841 mr->smr_oid, mlen );
2842 HASH_Update( &HASHcontext,
2843 &value->bv_val[value->bv_len-j], j );
2844 HASH_Final( HASHdigest, &HASHcontext );
2846 keys[nkeys++] = ber_bvdup( &digest );
2860 return LDAP_SUCCESS;
2863 int caseExactIA5SubstringsFilter(
2868 struct berval *prefix,
2870 struct berval ***keysp )
2872 SubstringsAssertion *sa = assertValue;
2874 ber_len_t nkeys = 0;
2875 size_t slen, mlen, klen;
2876 struct berval **keys;
2877 HASH_CONTEXT HASHcontext;
2878 unsigned char HASHdigest[HASH_BYTES];
2879 struct berval *value;
2880 struct berval digest;
2882 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2883 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2888 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2890 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2891 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2892 /* don't bother accounting for stepping */
2893 nkeys += sa->sa_any[i]->bv_len -
2894 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2899 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2900 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2907 return LDAP_SUCCESS;
2910 digest.bv_val = HASHdigest;
2911 digest.bv_len = sizeof(HASHdigest);
2913 slen = strlen( syntax->ssyn_oid );
2914 mlen = strlen( mr->smr_oid );
2916 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2919 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2920 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2922 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2923 value = sa->sa_initial;
2925 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2926 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2928 HASH_Init( &HASHcontext );
2929 if( prefix != NULL && prefix->bv_len > 0 ) {
2930 HASH_Update( &HASHcontext,
2931 prefix->bv_val, prefix->bv_len );
2933 HASH_Update( &HASHcontext,
2934 &pre, sizeof( pre ) );
2935 HASH_Update( &HASHcontext,
2936 syntax->ssyn_oid, slen );
2937 HASH_Update( &HASHcontext,
2938 mr->smr_oid, mlen );
2939 HASH_Update( &HASHcontext,
2940 value->bv_val, klen );
2941 HASH_Final( HASHdigest, &HASHcontext );
2943 keys[nkeys++] = ber_bvdup( &digest );
2946 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2948 pre = SLAP_INDEX_SUBSTR_PREFIX;
2949 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2951 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2952 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2956 value = sa->sa_any[i];
2959 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2960 j += SLAP_INDEX_SUBSTR_STEP )
2962 HASH_Init( &HASHcontext );
2963 if( prefix != NULL && prefix->bv_len > 0 ) {
2964 HASH_Update( &HASHcontext,
2965 prefix->bv_val, prefix->bv_len );
2967 HASH_Update( &HASHcontext,
2968 &pre, sizeof( pre ) );
2969 HASH_Update( &HASHcontext,
2970 syntax->ssyn_oid, slen );
2971 HASH_Update( &HASHcontext,
2972 mr->smr_oid, mlen );
2973 HASH_Update( &HASHcontext,
2974 &value->bv_val[j], klen );
2975 HASH_Final( HASHdigest, &HASHcontext );
2977 keys[nkeys++] = ber_bvdup( &digest );
2982 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2983 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2985 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2986 value = sa->sa_final;
2988 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2989 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2991 HASH_Init( &HASHcontext );
2992 if( prefix != NULL && prefix->bv_len > 0 ) {
2993 HASH_Update( &HASHcontext,
2994 prefix->bv_val, prefix->bv_len );
2996 HASH_Update( &HASHcontext,
2997 &pre, sizeof( pre ) );
2998 HASH_Update( &HASHcontext,
2999 syntax->ssyn_oid, slen );
3000 HASH_Update( &HASHcontext,
3001 mr->smr_oid, mlen );
3002 HASH_Update( &HASHcontext,
3003 &value->bv_val[value->bv_len-klen], klen );
3004 HASH_Final( HASHdigest, &HASHcontext );
3006 keys[nkeys++] = ber_bvdup( &digest );
3017 return LDAP_SUCCESS;
3026 struct berval *value,
3027 void *assertedValue )
3029 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
3031 if( match == 0 && value->bv_len ) {
3032 match = strncasecmp( value->bv_val,
3033 ((struct berval *) assertedValue)->bv_val,
3038 return LDAP_SUCCESS;
3042 caseIgnoreIA5SubstringsMatch(
3047 struct berval *value,
3048 void *assertedValue )
3051 SubstringsAssertion *sub = assertedValue;
3052 struct berval left = *value;
3056 /* Add up asserted input length */
3057 if( sub->sa_initial ) {
3058 inlen += sub->sa_initial->bv_len;
3061 for(i=0; sub->sa_any[i] != NULL; i++) {
3062 inlen += sub->sa_any[i]->bv_len;
3065 if( sub->sa_final ) {
3066 inlen += sub->sa_final->bv_len;
3069 if( sub->sa_initial ) {
3070 if( inlen > left.bv_len ) {
3075 match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
3076 sub->sa_initial->bv_len );
3082 left.bv_val += sub->sa_initial->bv_len;
3083 left.bv_len -= sub->sa_initial->bv_len;
3084 inlen -= sub->sa_initial->bv_len;
3087 if( sub->sa_final ) {
3088 if( inlen > left.bv_len ) {
3093 match = strncasecmp( sub->sa_final->bv_val,
3094 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
3095 sub->sa_final->bv_len );
3101 left.bv_len -= sub->sa_final->bv_len;
3102 inlen -= sub->sa_final->bv_len;
3106 for(i=0; sub->sa_any[i]; i++) {
3111 if( inlen > left.bv_len ) {
3112 /* not enough length */
3117 if( sub->sa_any[i]->bv_len == 0 ) {
3121 p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
3128 idx = p - left.bv_val;
3129 assert( idx < left.bv_len );
3131 if( idx >= left.bv_len ) {
3132 /* this shouldn't happen */
3139 if( sub->sa_any[i]->bv_len > left.bv_len ) {
3140 /* not enough left */
3145 match = strncasecmp( left.bv_val,
3146 sub->sa_any[i]->bv_val,
3147 sub->sa_any[i]->bv_len );
3156 left.bv_val += sub->sa_any[i]->bv_len;
3157 left.bv_len -= sub->sa_any[i]->bv_len;
3158 inlen -= sub->sa_any[i]->bv_len;
3164 return LDAP_SUCCESS;
3167 /* Index generation function */
3168 int caseIgnoreIA5Indexer(
3173 struct berval *prefix,
3174 struct berval **values,
3175 struct berval ***keysp )
3179 struct berval **keys;
3180 HASH_CONTEXT HASHcontext;
3181 unsigned char HASHdigest[HASH_BYTES];
3182 struct berval digest;
3183 digest.bv_val = HASHdigest;
3184 digest.bv_len = sizeof(HASHdigest);
3186 /* we should have at least one value at this point */
3187 assert( values != NULL && values[0] != NULL );
3189 for( i=0; values[i] != NULL; i++ ) {
3190 /* just count them */
3193 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
3195 slen = strlen( syntax->ssyn_oid );
3196 mlen = strlen( mr->smr_oid );
3198 for( i=0; values[i] != NULL; i++ ) {
3199 struct berval *value = ber_bvdup( values[i] );
3200 ldap_pvt_str2upper( value->bv_val );
3202 HASH_Init( &HASHcontext );
3203 if( prefix != NULL && prefix->bv_len > 0 ) {
3204 HASH_Update( &HASHcontext,
3205 prefix->bv_val, prefix->bv_len );
3207 HASH_Update( &HASHcontext,
3208 syntax->ssyn_oid, slen );
3209 HASH_Update( &HASHcontext,
3210 mr->smr_oid, mlen );
3211 HASH_Update( &HASHcontext,
3212 value->bv_val, value->bv_len );
3213 HASH_Final( HASHdigest, &HASHcontext );
3215 ber_bvfree( value );
3217 keys[i] = ber_bvdup( &digest );
3222 return LDAP_SUCCESS;
3225 /* Index generation function */
3226 int caseIgnoreIA5Filter(
3231 struct berval *prefix,
3233 struct berval ***keysp )
3236 struct berval **keys;
3237 HASH_CONTEXT HASHcontext;
3238 unsigned char HASHdigest[HASH_BYTES];
3239 struct berval *value;
3240 struct berval digest;
3241 digest.bv_val = HASHdigest;
3242 digest.bv_len = sizeof(HASHdigest);
3244 slen = strlen( syntax->ssyn_oid );
3245 mlen = strlen( mr->smr_oid );
3247 value = ber_bvdup( (struct berval *) assertValue );
3248 ldap_pvt_str2upper( value->bv_val );
3250 keys = ch_malloc( sizeof( struct berval * ) * 2 );
3252 HASH_Init( &HASHcontext );
3253 if( prefix != NULL && prefix->bv_len > 0 ) {
3254 HASH_Update( &HASHcontext,
3255 prefix->bv_val, prefix->bv_len );
3257 HASH_Update( &HASHcontext,
3258 syntax->ssyn_oid, slen );
3259 HASH_Update( &HASHcontext,
3260 mr->smr_oid, mlen );
3261 HASH_Update( &HASHcontext,
3262 value->bv_val, value->bv_len );
3263 HASH_Final( HASHdigest, &HASHcontext );
3265 keys[0] = ber_bvdup( &digest );
3268 ber_bvfree( value );
3272 return LDAP_SUCCESS;
3275 /* Substrings Index generation function */
3276 int caseIgnoreIA5SubstringsIndexer(
3281 struct berval *prefix,
3282 struct berval **values,
3283 struct berval ***keysp )
3287 struct berval **keys;
3288 HASH_CONTEXT HASHcontext;
3289 unsigned char HASHdigest[HASH_BYTES];
3290 struct berval digest;
3291 digest.bv_val = HASHdigest;
3292 digest.bv_len = sizeof(HASHdigest);
3294 /* we should have at least one value at this point */
3295 assert( values != NULL && values[0] != NULL );
3298 for( i=0; values[i] != NULL; i++ ) {
3299 /* count number of indices to generate */
3300 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3304 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3305 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3306 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3307 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3309 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3313 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3314 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3315 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3319 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3320 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3321 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3322 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3324 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3330 /* no keys to generate */
3332 return LDAP_SUCCESS;
3335 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
3337 slen = strlen( syntax->ssyn_oid );
3338 mlen = strlen( mr->smr_oid );
3341 for( i=0; values[i] != NULL; i++ ) {
3343 struct berval *value;
3345 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3347 value = ber_bvdup( values[i] );
3348 ldap_pvt_str2upper( value->bv_val );
3350 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3351 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3353 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3354 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3356 for( j=0; j<max; j++ ) {
3357 HASH_Init( &HASHcontext );
3358 if( prefix != NULL && prefix->bv_len > 0 ) {
3359 HASH_Update( &HASHcontext,
3360 prefix->bv_val, prefix->bv_len );
3363 HASH_Update( &HASHcontext,
3364 &pre, sizeof( pre ) );
3365 HASH_Update( &HASHcontext,
3366 syntax->ssyn_oid, slen );
3367 HASH_Update( &HASHcontext,
3368 mr->smr_oid, mlen );
3369 HASH_Update( &HASHcontext,
3371 SLAP_INDEX_SUBSTR_MAXLEN );
3372 HASH_Final( HASHdigest, &HASHcontext );
3374 keys[nkeys++] = ber_bvdup( &digest );
3378 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3379 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3381 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3384 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3385 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3386 HASH_Init( &HASHcontext );
3387 if( prefix != NULL && prefix->bv_len > 0 ) {
3388 HASH_Update( &HASHcontext,
3389 prefix->bv_val, prefix->bv_len );
3391 HASH_Update( &HASHcontext,
3392 &pre, sizeof( pre ) );
3393 HASH_Update( &HASHcontext,
3394 syntax->ssyn_oid, slen );
3395 HASH_Update( &HASHcontext,
3396 mr->smr_oid, mlen );
3397 HASH_Update( &HASHcontext,
3399 HASH_Final( HASHdigest, &HASHcontext );
3401 keys[nkeys++] = ber_bvdup( &digest );
3404 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3405 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3406 HASH_Init( &HASHcontext );
3407 if( prefix != NULL && prefix->bv_len > 0 ) {
3408 HASH_Update( &HASHcontext,
3409 prefix->bv_val, prefix->bv_len );
3411 HASH_Update( &HASHcontext,
3412 &pre, sizeof( pre ) );
3413 HASH_Update( &HASHcontext,
3414 syntax->ssyn_oid, slen );
3415 HASH_Update( &HASHcontext,
3416 mr->smr_oid, mlen );
3417 HASH_Update( &HASHcontext,
3418 &value->bv_val[value->bv_len-j], j );
3419 HASH_Final( HASHdigest, &HASHcontext );
3421 keys[nkeys++] = ber_bvdup( &digest );
3426 ber_bvfree( value );
3437 return LDAP_SUCCESS;
3440 int caseIgnoreIA5SubstringsFilter(
3445 struct berval *prefix,
3447 struct berval ***keysp )
3449 SubstringsAssertion *sa = assertValue;
3451 ber_len_t nkeys = 0;
3452 size_t slen, mlen, klen;
3453 struct berval **keys;
3454 HASH_CONTEXT HASHcontext;
3455 unsigned char HASHdigest[HASH_BYTES];
3456 struct berval *value;
3457 struct berval digest;
3459 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3460 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3465 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3467 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3468 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3469 /* don't bother accounting for stepping */
3470 nkeys += sa->sa_any[i]->bv_len -
3471 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3476 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3477 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3484 return LDAP_SUCCESS;
3487 digest.bv_val = HASHdigest;
3488 digest.bv_len = sizeof(HASHdigest);
3490 slen = strlen( syntax->ssyn_oid );
3491 mlen = strlen( mr->smr_oid );
3493 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
3496 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3497 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3499 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3500 value = ber_bvdup( sa->sa_initial );
3501 ldap_pvt_str2upper( value->bv_val );
3503 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3504 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3506 HASH_Init( &HASHcontext );
3507 if( prefix != NULL && prefix->bv_len > 0 ) {
3508 HASH_Update( &HASHcontext,
3509 prefix->bv_val, prefix->bv_len );
3511 HASH_Update( &HASHcontext,
3512 &pre, sizeof( pre ) );
3513 HASH_Update( &HASHcontext,
3514 syntax->ssyn_oid, slen );
3515 HASH_Update( &HASHcontext,
3516 mr->smr_oid, mlen );
3517 HASH_Update( &HASHcontext,
3518 value->bv_val, klen );
3519 HASH_Final( HASHdigest, &HASHcontext );
3521 ber_bvfree( value );
3522 keys[nkeys++] = ber_bvdup( &digest );
3525 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3527 pre = SLAP_INDEX_SUBSTR_PREFIX;
3528 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3530 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3531 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3535 value = ber_bvdup( sa->sa_any[i] );
3536 ldap_pvt_str2upper( value->bv_val );
3539 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3540 j += SLAP_INDEX_SUBSTR_STEP )
3542 HASH_Init( &HASHcontext );
3543 if( prefix != NULL && prefix->bv_len > 0 ) {
3544 HASH_Update( &HASHcontext,
3545 prefix->bv_val, prefix->bv_len );
3547 HASH_Update( &HASHcontext,
3548 &pre, sizeof( pre ) );
3549 HASH_Update( &HASHcontext,
3550 syntax->ssyn_oid, slen );
3551 HASH_Update( &HASHcontext,
3552 mr->smr_oid, mlen );
3553 HASH_Update( &HASHcontext,
3554 &value->bv_val[j], klen );
3555 HASH_Final( HASHdigest, &HASHcontext );
3557 keys[nkeys++] = ber_bvdup( &digest );
3560 ber_bvfree( value );
3564 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3565 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3567 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3568 value = ber_bvdup( sa->sa_final );
3569 ldap_pvt_str2upper( value->bv_val );
3571 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3572 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3574 HASH_Init( &HASHcontext );
3575 if( prefix != NULL && prefix->bv_len > 0 ) {
3576 HASH_Update( &HASHcontext,
3577 prefix->bv_val, prefix->bv_len );
3579 HASH_Update( &HASHcontext,
3580 &pre, sizeof( pre ) );
3581 HASH_Update( &HASHcontext,
3582 syntax->ssyn_oid, slen );
3583 HASH_Update( &HASHcontext,
3584 mr->smr_oid, mlen );
3585 HASH_Update( &HASHcontext,
3586 &value->bv_val[value->bv_len-klen], klen );
3587 HASH_Final( HASHdigest, &HASHcontext );
3589 ber_bvfree( value );
3590 keys[nkeys++] = ber_bvdup( &digest );
3601 return LDAP_SUCCESS;
3605 numericStringValidate(
3611 for(i=0; i < in->bv_len; i++) {
3612 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3613 return LDAP_INVALID_SYNTAX;
3617 return LDAP_SUCCESS;
3621 numericStringNormalize(
3624 struct berval **normalized )
3626 /* removal all spaces */
3627 struct berval *newval;
3630 newval = ch_malloc( sizeof( struct berval ) );
3631 newval->bv_val = ch_malloc( val->bv_len + 1 );
3637 if ( ASCII_SPACE( *p ) ) {
3638 /* Ignore whitespace */
3645 /* we should have copied no more then is in val */
3646 assert( (q - newval->bv_val) <= (p - val->bv_val) );
3648 /* null terminate */
3651 newval->bv_len = q - newval->bv_val;
3652 *normalized = newval;
3654 return LDAP_SUCCESS;
3658 objectIdentifierFirstComponentMatch(
3663 struct berval *value,
3664 void *assertedValue )
3666 int rc = LDAP_SUCCESS;
3668 struct berval *asserted = (struct berval *) assertedValue;
3672 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3673 return LDAP_INVALID_SYNTAX;
3676 /* trim leading white space */
3677 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3681 /* grab next word */
3682 oid.bv_val = &value->bv_val[i];
3683 oid.bv_len = value->bv_len - i;
3684 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3689 /* insert attributeTypes, objectclass check here */
3690 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3691 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3694 char *stored = ch_malloc( oid.bv_len + 1 );
3695 AC_MEMCPY( stored, oid.bv_val, oid.bv_len );
3696 stored[oid.bv_len] = '\0';
3698 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3699 MatchingRule *asserted_mr = mr_find( asserted->bv_val );
3700 MatchingRule *stored_mr = mr_find( stored );
3702 if( asserted_mr == NULL ) {
3703 rc = SLAPD_COMPARE_UNDEFINED;
3705 match = asserted_mr != stored_mr;
3708 } else if ( !strcmp( syntax->ssyn_oid,
3709 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3711 AttributeType *asserted_at = at_find( asserted->bv_val );
3712 AttributeType *stored_at = at_find( stored );
3714 if( asserted_at == NULL ) {
3715 rc = SLAPD_COMPARE_UNDEFINED;
3717 match = asserted_at != stored_at;
3720 } else if ( !strcmp( syntax->ssyn_oid,
3721 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3723 ObjectClass *asserted_oc = oc_find( asserted->bv_val );
3724 ObjectClass *stored_oc = oc_find( stored );
3726 if( asserted_oc == NULL ) {
3727 rc = SLAPD_COMPARE_UNDEFINED;
3729 match = asserted_oc != stored_oc;
3737 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3738 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3739 match, value->bv_val, asserted->bv_val ));
3741 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3742 "%d\n\t\"%s\"\n\t\"%s\"\n",
3743 match, value->bv_val, asserted->bv_val );
3747 if( rc == LDAP_SUCCESS ) *matchp = match;
3757 struct berval *value,
3758 void *assertedValue )
3760 long lValue, lAssertedValue;
3762 /* safe to assume integers are NUL terminated? */
3763 lValue = strtoul(value->bv_val, NULL, 10);
3764 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3765 return LDAP_CONSTRAINT_VIOLATION;
3767 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3768 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3769 return LDAP_CONSTRAINT_VIOLATION;
3771 *matchp = (lValue & lAssertedValue);
3772 return LDAP_SUCCESS;
3781 struct berval *value,
3782 void *assertedValue )
3784 long lValue, lAssertedValue;
3786 /* safe to assume integers are NUL terminated? */
3787 lValue = strtoul(value->bv_val, NULL, 10);
3788 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3789 return LDAP_CONSTRAINT_VIOLATION;
3791 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3792 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3793 return LDAP_CONSTRAINT_VIOLATION;
3795 *matchp = (lValue | lAssertedValue);
3796 return LDAP_SUCCESS;
3800 #include <openssl/x509.h>
3801 #include <openssl/err.h>
3802 char digit[] = "0123456789";
3805 * Next function returns a string representation of a ASN1_INTEGER.
3806 * It works for unlimited lengths.
3809 static struct berval *
3810 asn1_integer2str(ASN1_INTEGER *a)
3815 /* We work backwards, make it fill from the end of buf */
3816 p = buf + sizeof(buf) - 1;
3819 if ( a == NULL || a->length == 0 ) {
3827 /* We want to preserve the original */
3828 copy = ch_malloc(n*sizeof(unsigned int));
3829 for (i = 0; i<n; i++) {
3830 copy[i] = a->data[i];
3834 * base indicates the index of the most significant
3835 * byte that might be nonzero. When it goes off the
3836 * end, we now there is nothing left to do.
3842 for (i = base; i<n; i++ ) {
3843 copy[i] += carry*256;
3844 carry = copy[i] % 10;
3849 * Way too large, we need to leave
3850 * room for sign if negative
3855 *--p = digit[carry];
3856 if (copy[base] == 0)
3862 if ( a->type == V_ASN1_NEG_INTEGER ) {
3866 return ber_bvstrdup(p);
3869 /* Get a DN in RFC2253 format from a X509_NAME internal struct */
3870 static struct berval *
3871 dn_openssl2ldap(X509_NAME *name)
3873 char issuer_dn[1024];
3876 bio = BIO_new(BIO_s_mem());
3879 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3880 "dn_openssl2ldap: error creating BIO_s_mem: %s\n",
3881 ERR_error_string(ERR_get_error(),NULL)));
3883 Debug( LDAP_DEBUG_ARGS, "dn_openssl2ldap: "
3884 "error creating BIO: %s\n",
3885 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3889 X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253);
3891 BIO_gets(bio, issuer_dn, 1024);
3894 return ber_bvstrdup(issuer_dn);
3898 * Given a certificate in DER format, extract the corresponding
3899 * assertion value for certificateExactMatch
3902 certificateExactConvert(
3904 struct berval ** out )
3907 unsigned char *p = in->bv_val;
3908 struct berval *serial;
3909 struct berval *issuer_dn;
3910 struct berval *bv_tmp;
3912 xcert = d2i_X509(NULL, &p, in->bv_len);
3915 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3916 "certificateExactConvert: error parsing cert: %s\n",
3917 ERR_error_string(ERR_get_error(),NULL)));
3919 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3920 "error parsing cert: %s\n",
3921 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3923 return LDAP_INVALID_SYNTAX;
3926 serial = asn1_integer2str(xcert->cert_info->serialNumber);
3929 return LDAP_INVALID_SYNTAX;
3931 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
3935 return LDAP_INVALID_SYNTAX;
3937 /* Actually, dn_openssl2ldap returns in a normalized format, but
3938 it is different from our normalized format */
3940 if ( dnNormalize(NULL, bv_tmp, &issuer_dn) != LDAP_SUCCESS ) {
3944 return LDAP_INVALID_SYNTAX;
3950 *out = ch_malloc(sizeof(struct berval));
3951 (*out)->bv_len = serial->bv_len + 3 + issuer_dn->bv_len + 1;
3952 (*out)->bv_val = ch_malloc((*out)->bv_len);
3954 AC_MEMCPY(p, serial->bv_val, serial->bv_len);
3955 p += serial->bv_len;
3956 AC_MEMCPY(p, " $ ", 3);
3958 AC_MEMCPY(p, issuer_dn->bv_val, issuer_dn->bv_len);
3959 p += issuer_dn->bv_len;
3963 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3964 "certificateExactConvert: \n %s\n",
3967 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
3969 (*out)->bv_val, NULL, NULL );
3973 ber_bvfree(issuer_dn);
3975 return LDAP_SUCCESS;
3979 serial_and_issuer_parse(
3980 struct berval *assertion,
3981 struct berval **serial,
3982 struct berval **issuer_dn
3990 begin = assertion->bv_val;
3991 end = assertion->bv_val+assertion->bv_len-1;
3992 for (p=begin; p<=end && *p != '$'; p++)
3995 return LDAP_INVALID_SYNTAX;
3997 /* p now points at the $ sign, now use begin and end to delimit the
3999 while (ASCII_SPACE(*begin))
4002 while (ASCII_SPACE(*end))
4005 q = ch_malloc( (end-begin+1)+1 );
4006 AC_MEMCPY( q, begin, end-begin+1 );
4007 q[end-begin+1] = '\0';
4008 *serial = ber_bvstr(q);
4010 /* now extract the issuer, remember p was at the dollar sign */
4012 end = assertion->bv_val+assertion->bv_len-1;
4013 while (ASCII_SPACE(*begin))
4015 /* should we trim spaces at the end too? is it safe always? */
4017 q = ch_malloc( (end-begin+1)+1 );
4018 AC_MEMCPY( q, begin, end-begin+1 );
4019 q[end-begin+1] = '\0';
4020 *issuer_dn = ber_bvstr(dn_normalize(q));
4022 return LDAP_SUCCESS;
4026 certificateExactMatch(
4031 struct berval *value,
4032 void *assertedValue )
4035 unsigned char *p = value->bv_val;
4036 struct berval *serial;
4037 struct berval *issuer_dn;
4038 struct berval *asserted_serial;
4039 struct berval *asserted_issuer_dn;
4042 xcert = d2i_X509(NULL, &p, value->bv_len);
4045 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
4046 "certificateExactMatch: error parsing cert: %s\n",
4047 ERR_error_string(ERR_get_error(),NULL)));
4049 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
4050 "error parsing cert: %s\n",
4051 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4053 return LDAP_INVALID_SYNTAX;
4056 serial = asn1_integer2str(xcert->cert_info->serialNumber);
4057 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
4061 serial_and_issuer_parse(assertedValue,
4063 &asserted_issuer_dn);
4068 slap_schema.si_syn_integer,
4069 slap_schema.si_mr_integerMatch,
4072 if ( ret == LDAP_SUCCESS ) {
4073 if ( *matchp == 0 ) {
4074 /* We need to normalize everything for dnMatch */
4078 slap_schema.si_syn_distinguishedName,
4079 slap_schema.si_mr_distinguishedNameMatch,
4081 asserted_issuer_dn);
4086 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
4087 "certificateExactMatch: %d\n %s $ %s\n %s $ %s\n",
4088 *matchp, serial->bv_val, issuer_dn->bv_val,
4089 asserted->serial->bv_val, asserted_issuer_dn->bv_val));
4091 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
4092 "%d\n\t\"%s $ %s\"\n",
4093 *matchp, serial->bv_val, issuer_dn->bv_val );
4094 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
4095 asserted_serial->bv_val, asserted_issuer_dn->bv_val,
4100 ber_bvfree(issuer_dn);
4101 ber_bvfree(asserted_serial);
4102 ber_bvfree(asserted_issuer_dn);
4108 * Index generation function
4109 * We just index the serials, in most scenarios the issuer DN is one of
4110 * a very small set of values.
4112 int certificateExactIndexer(
4117 struct berval *prefix,
4118 struct berval **values,
4119 struct berval ***keysp )
4122 struct berval **keys;
4125 struct berval * serial;
4127 /* we should have at least one value at this point */
4128 assert( values != NULL && values[0] != NULL );
4130 for( i=0; values[i] != NULL; i++ ) {
4131 /* empty -- just count them */
4134 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
4136 for( i=0; values[i] != NULL; i++ ) {
4137 p = values[i]->bv_val;
4138 xcert = d2i_X509(NULL, &p, values[i]->bv_len);
4141 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
4142 "certificateExactIndexer: error parsing cert: %s\n",
4143 ERR_error_string(ERR_get_error(),NULL)));
4145 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4146 "error parsing cert: %s\n",
4147 ERR_error_string(ERR_get_error(),NULL),
4150 /* Do we leak keys on error? */
4151 return LDAP_INVALID_SYNTAX;
4154 serial = asn1_integer2str(xcert->cert_info->serialNumber);
4156 integerNormalize( slap_schema.si_syn_integer,
4161 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
4162 "certificateExactIndexer: returning: %s\n",
4165 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4174 return LDAP_SUCCESS;
4177 /* Index generation function */
4178 /* We think this is always called with a value in matching rule syntax */
4179 int certificateExactFilter(
4184 struct berval *prefix,
4186 struct berval ***keysp )
4188 struct berval **keys;
4189 struct berval *asserted_serial;
4190 struct berval *asserted_issuer_dn;
4192 serial_and_issuer_parse(assertValue,
4194 &asserted_issuer_dn);
4196 keys = ch_malloc( sizeof( struct berval * ) * 2 );
4197 integerNormalize( syntax, asserted_serial, &keys[0] );
4201 ber_bvfree(asserted_serial);
4202 ber_bvfree(asserted_issuer_dn);
4203 return LDAP_SUCCESS;
4208 check_time_syntax (struct berval *val,
4212 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4213 static int mdays[2][12] = {
4214 /* non-leap years */
4215 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4217 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4220 int part, c, tzoffset, leapyear = 0 ;
4222 if( val->bv_len == 0 ) {
4223 return LDAP_INVALID_SYNTAX;
4226 p = (char *)val->bv_val;
4227 e = p + val->bv_len;
4229 /* Ignore initial whitespace */
4230 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4234 if (e - p < 13 - (2 * start)) {
4235 return LDAP_INVALID_SYNTAX;
4238 for (part = 0; part < 9; part++) {
4242 for (part = start; part < 7; part++) {
4244 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4251 return LDAP_INVALID_SYNTAX;
4253 if (c < 0 || c > 9) {
4254 return LDAP_INVALID_SYNTAX;
4260 return LDAP_INVALID_SYNTAX;
4262 if (c < 0 || c > 9) {
4263 return LDAP_INVALID_SYNTAX;
4268 if (part == 2 || part == 3) {
4271 if (parts[part] < 0) {
4272 return LDAP_INVALID_SYNTAX;
4274 if (parts[part] > ceiling[part]) {
4275 return LDAP_INVALID_SYNTAX;
4279 /* leapyear check for the Gregorian calendar (year>1581) */
4280 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4281 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4286 if (parts[3] > mdays[leapyear][parts[2]]) {
4287 return LDAP_INVALID_SYNTAX;
4292 tzoffset = 0; /* UTC */
4293 } else if (c != '+' && c != '-') {
4294 return LDAP_INVALID_SYNTAX;
4298 } else /* c == '+' */ {
4303 return LDAP_INVALID_SYNTAX;
4306 for (part = 7; part < 9; part++) {
4308 if (c < 0 || c > 9) {
4309 return LDAP_INVALID_SYNTAX;
4314 if (c < 0 || c > 9) {
4315 return LDAP_INVALID_SYNTAX;
4319 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4320 return LDAP_INVALID_SYNTAX;
4325 /* Ignore trailing whitespace */
4326 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4330 return LDAP_INVALID_SYNTAX;
4333 switch ( tzoffset ) {
4334 case -1: /* negativ offset to UTC, ie west of Greenwich */
4335 parts[4] += parts[7];
4336 parts[5] += parts[8];
4337 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4341 c = mdays[leapyear][parts[2]];
4343 if (parts[part] > c) {
4344 parts[part] -= c + 1;
4349 case 1: /* positive offset to UTC, ie east of Greenwich */
4350 parts[4] -= parts[7];
4351 parts[5] -= parts[8];
4352 for (part = 6; --part > 0; ) {
4356 /* first arg to % needs to be non negativ */
4357 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4359 if (parts[part] < 0) {
4360 parts[part] += c + 1;
4365 case 0: /* already UTC */
4369 return LDAP_SUCCESS;
4376 struct berval **normalized )
4381 rc = check_time_syntax(val, 1, parts);
4382 if (rc != LDAP_SUCCESS) {
4387 out = ch_malloc( sizeof(struct berval) );
4389 return LBER_ERROR_MEMORY;
4392 out->bv_val = ch_malloc( 14 );
4393 if ( out->bv_val == NULL ) {
4395 return LBER_ERROR_MEMORY;
4398 sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4399 parts[1], parts[2] + 1, parts[3] + 1,
4400 parts[4], parts[5], parts[6] );
4404 return LDAP_SUCCESS;
4414 return check_time_syntax(in, 1, parts);
4418 generalizedTimeValidate(
4424 return check_time_syntax(in, 0, parts);
4428 generalizedTimeNormalize(
4431 struct berval **normalized )
4436 rc = check_time_syntax(val, 0, parts);
4437 if (rc != LDAP_SUCCESS) {
4442 out = ch_malloc( sizeof(struct berval) );
4444 return LBER_ERROR_MEMORY;
4447 out->bv_val = ch_malloc( 16 );
4448 if ( out->bv_val == NULL ) {
4450 return LBER_ERROR_MEMORY;
4453 sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4454 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4455 parts[4], parts[5], parts[6] );
4459 return LDAP_SUCCESS;
4463 nisNetgroupTripleValidate(
4465 struct berval *val )
4470 if ( val->bv_len == 0 ) {
4471 return LDAP_INVALID_SYNTAX;
4474 p = (char *)val->bv_val;
4475 e = p + val->bv_len;
4477 if ( *p != '(' /*')'*/ ) {
4478 return LDAP_INVALID_SYNTAX;
4481 for ( p++; ( p < e ) && ( *p != ')' ); p++ ) {
4485 return LDAP_INVALID_SYNTAX;
4488 } else if ( !ATTR_CHAR( *p ) ) {
4489 return LDAP_INVALID_SYNTAX;
4493 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4494 return LDAP_INVALID_SYNTAX;
4500 return LDAP_INVALID_SYNTAX;
4503 return LDAP_SUCCESS;
4507 bootParameterValidate(
4509 struct berval *val )
4513 if ( val->bv_len == 0 ) {
4514 return LDAP_INVALID_SYNTAX;
4517 p = (char *)val->bv_val;
4518 e = p + val->bv_len;
4521 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4522 if ( !ATTR_CHAR( *p ) ) {
4523 return LDAP_INVALID_SYNTAX;
4528 return LDAP_INVALID_SYNTAX;
4532 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4533 if ( !ATTR_CHAR( *p ) ) {
4534 return LDAP_INVALID_SYNTAX;
4539 return LDAP_INVALID_SYNTAX;
4543 for ( p++; p < e; p++ ) {
4544 if ( !ATTR_CHAR( *p ) ) {
4545 return LDAP_INVALID_SYNTAX;
4549 return LDAP_SUCCESS;
4552 struct syntax_defs_rec {
4555 slap_syntax_validate_func *sd_validate;
4556 slap_syntax_transform_func *sd_normalize;
4557 slap_syntax_transform_func *sd_pretty;
4558 #ifdef SLAPD_BINARY_CONVERSION
4559 slap_syntax_transform_func *sd_ber2str;
4560 slap_syntax_transform_func *sd_str2ber;
4564 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4565 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4567 struct syntax_defs_rec syntax_defs[] = {
4568 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
4569 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4570 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4571 0, NULL, NULL, NULL},
4572 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4573 0, NULL, NULL, NULL},
4574 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
4575 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4576 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_NOT_H_R ")",
4577 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4578 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4579 0, bitStringValidate, bitStringNormalize, NULL },
4580 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4581 0, booleanValidate, NULL, NULL},
4582 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4583 X_BINARY X_NOT_H_R ")",
4584 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4585 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
4586 X_BINARY X_NOT_H_R ")",
4587 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4588 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
4589 X_BINARY X_NOT_H_R ")",
4590 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4591 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4592 0, countryStringValidate, IA5StringNormalize, NULL},
4593 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4594 0, dnValidate, dnNormalize, dnPretty},
4595 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4596 0, NULL, NULL, NULL},
4597 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4598 0, NULL, NULL, NULL},
4599 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4600 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4601 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4602 0, NULL, NULL, NULL},
4603 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4604 0, NULL, NULL, NULL},
4605 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4606 0, NULL, NULL, NULL},
4607 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4608 0, NULL, NULL, NULL},
4609 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4610 0, NULL, NULL, NULL},
4611 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4612 0, printablesStringValidate, IA5StringNormalize, NULL},
4613 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4614 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4615 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4616 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4617 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4618 0, NULL, NULL, NULL},
4619 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4620 0, IA5StringValidate, IA5StringNormalize, NULL},
4621 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4622 0, integerValidate, integerNormalize, NULL},
4623 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4624 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4625 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4626 0, NULL, NULL, NULL},
4627 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4628 0, NULL, NULL, NULL},
4629 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4630 0, NULL, NULL, NULL},
4631 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4632 0, NULL, NULL, NULL},
4633 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4634 0, NULL, NULL, NULL},
4635 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4636 0, nameUIDValidate, nameUIDNormalize, NULL},
4637 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4638 0, NULL, NULL, NULL},
4639 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4640 0, numericStringValidate, numericStringNormalize, NULL},
4641 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4642 0, NULL, NULL, NULL},
4643 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4644 0, oidValidate, NULL, NULL},
4645 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4646 0, IA5StringValidate, IA5StringNormalize, NULL},
4647 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4648 0, blobValidate, NULL, NULL},
4649 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4650 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4651 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4652 0, NULL, NULL, NULL},
4653 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4654 0, NULL, NULL, NULL},
4655 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4656 0, printableStringValidate, IA5StringNormalize, NULL},
4657 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4658 X_BINARY X_NOT_H_R ")",
4659 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4660 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4661 0, printableStringValidate, IA5StringNormalize, NULL},
4662 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4663 0, NULL, NULL, NULL},
4664 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4665 0, printablesStringValidate, IA5StringNormalize, NULL},
4666 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4667 0, utcTimeValidate, utcTimeNormalize, NULL},
4668 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4669 0, NULL, NULL, NULL},
4670 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4671 0, NULL, NULL, NULL},
4672 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4673 0, NULL, NULL, NULL},
4674 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4675 0, NULL, NULL, NULL},
4676 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4677 0, NULL, NULL, NULL},
4679 /* RFC 2307 NIS Syntaxes */
4680 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4681 0, nisNetgroupTripleValidate, NULL, NULL},
4682 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4683 0, bootParameterValidate, NULL, NULL},
4687 /* These OIDs are not published yet, but will be in the next
4688 * I-D for PKIX LDAPv3 schema as have been advanced by David
4689 * Chadwick in private mail.
4691 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4692 0, NULL, NULL, NULL},
4695 /* OpenLDAP Experimental Syntaxes */
4696 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4698 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4701 /* needs updating */
4702 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4703 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4705 /* OpenLDAP Void Syntax */
4706 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4707 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4708 {NULL, 0, NULL, NULL, NULL}
4711 struct mrule_defs_rec {
4713 slap_mask_t mrd_usage;
4714 slap_mr_convert_func * mrd_convert;
4715 slap_mr_normalize_func * mrd_normalize;
4716 slap_mr_match_func * mrd_match;
4717 slap_mr_indexer_func * mrd_indexer;
4718 slap_mr_filter_func * mrd_filter;
4720 char * mrd_associated;
4724 * Other matching rules in X.520 that we do not use (yet):
4726 * 2.5.13.9 numericStringOrderingMatch
4727 * 2.5.13.15 integerOrderingMatch
4728 * 2.5.13.18 octetStringOrderingMatch
4729 * 2.5.13.19 octetStringSubstringsMatch
4730 * 2.5.13.25 uTCTimeMatch
4731 * 2.5.13.26 uTCTimeOrderingMatch
4732 * 2.5.13.31 directoryStringFirstComponentMatch
4733 * 2.5.13.32 wordMatch
4734 * 2.5.13.33 keywordMatch
4735 * 2.5.13.35 certificateMatch
4736 * 2.5.13.36 certificatePairExactMatch
4737 * 2.5.13.37 certificatePairMatch
4738 * 2.5.13.38 certificateListExactMatch
4739 * 2.5.13.39 certificateListMatch
4740 * 2.5.13.40 algorithmIdentifierMatch
4741 * 2.5.13.41 storedPrefixMatch
4742 * 2.5.13.42 attributeCertificateMatch
4743 * 2.5.13.43 readerAndKeyIDMatch
4744 * 2.5.13.44 attributeIntegrityMatch
4747 struct mrule_defs_rec mrule_defs[] = {
4749 * EQUALITY matching rules must be listed after associated APPROX
4750 * matching rules. So, we list all APPROX matching rules first.
4752 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4753 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4754 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4756 directoryStringApproxMatch,
4757 directoryStringApproxIndexer,
4758 directoryStringApproxFilter,
4761 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4762 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4763 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4765 IA5StringApproxMatch,
4766 IA5StringApproxIndexer,
4767 IA5StringApproxFilter,
4771 * Other matching rules
4774 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4775 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4776 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4778 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4781 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4782 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4783 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4785 dnMatch, dnIndexer, dnFilter,
4788 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4789 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4790 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4792 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4793 directoryStringApproxMatchOID },
4795 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4796 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4799 caseIgnoreOrderingMatch, NULL, NULL,
4802 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4803 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4804 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4806 caseExactIgnoreSubstringsMatch,
4807 caseExactIgnoreSubstringsIndexer,
4808 caseExactIgnoreSubstringsFilter,
4811 {"( 2.5.13.5 NAME 'caseExactMatch' "
4812 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4813 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4815 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4816 directoryStringApproxMatchOID },
4818 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4819 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4822 caseExactOrderingMatch, NULL, NULL,
4825 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4826 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4827 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4829 caseExactIgnoreSubstringsMatch,
4830 caseExactIgnoreSubstringsIndexer,
4831 caseExactIgnoreSubstringsFilter,
4834 {"( 2.5.13.8 NAME 'numericStringMatch' "
4835 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4836 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4839 caseIgnoreIA5Indexer,
4840 caseIgnoreIA5Filter,
4843 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4844 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4845 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4847 caseIgnoreIA5SubstringsMatch,
4848 caseIgnoreIA5SubstringsIndexer,
4849 caseIgnoreIA5SubstringsFilter,
4852 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4853 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4854 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4856 caseIgnoreListMatch, NULL, NULL,
4859 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4860 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4861 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4863 caseIgnoreListSubstringsMatch, NULL, NULL,
4866 {"( 2.5.13.13 NAME 'booleanMatch' "
4867 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4868 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4870 booleanMatch, NULL, NULL,
4873 {"( 2.5.13.14 NAME 'integerMatch' "
4874 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4875 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4877 integerMatch, integerIndexer, integerFilter,
4880 {"( 2.5.13.16 NAME 'bitStringMatch' "
4881 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4882 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4884 bitStringMatch, bitStringIndexer, bitStringFilter,
4887 {"( 2.5.13.17 NAME 'octetStringMatch' "
4888 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4889 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4891 octetStringMatch, octetStringIndexer, octetStringFilter,
4894 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4895 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4896 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4898 telephoneNumberMatch,
4899 telephoneNumberIndexer,
4900 telephoneNumberFilter,
4903 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4904 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4905 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4907 telephoneNumberSubstringsMatch,
4908 telephoneNumberSubstringsIndexer,
4909 telephoneNumberSubstringsFilter,
4912 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4913 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4914 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4919 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4920 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4921 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4923 uniqueMemberMatch, NULL, NULL,
4926 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4927 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
4928 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4930 protocolInformationMatch, NULL, NULL,
4933 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
4934 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4935 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4937 generalizedTimeMatch, NULL, NULL,
4940 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
4941 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
4944 generalizedTimeOrderingMatch, NULL, NULL,
4947 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
4948 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4949 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4951 integerFirstComponentMatch, NULL, NULL,
4954 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
4955 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4956 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4958 objectIdentifierFirstComponentMatch, NULL, NULL,
4962 {"( 2.5.13.34 NAME 'certificateExactMatch' "
4963 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
4964 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4965 certificateExactConvert, NULL,
4966 certificateExactMatch,
4967 certificateExactIndexer, certificateExactFilter,
4971 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
4972 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4973 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4975 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
4976 IA5StringApproxMatchOID },
4978 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
4979 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4980 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4982 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4983 IA5StringApproxMatchOID },
4985 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
4986 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4989 caseIgnoreIA5SubstringsMatch,
4990 caseIgnoreIA5SubstringsIndexer,
4991 caseIgnoreIA5SubstringsFilter,
4994 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
4995 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4998 caseExactIA5SubstringsMatch,
4999 caseExactIA5SubstringsIndexer,
5000 caseExactIA5SubstringsFilter,
5003 /* needs updating */
5004 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
5005 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
5008 authPasswordMatch, NULL, NULL,
5011 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
5012 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
5015 OpenLDAPaciMatch, NULL, NULL,
5018 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
5019 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5022 integerBitAndMatch, NULL, NULL,
5025 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
5026 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5029 integerBitOrMatch, NULL, NULL,
5032 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
5041 /* we should only be called once (from main) */
5042 assert( schema_init_done == 0 );
5044 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
5045 res = register_syntax( syntax_defs[i].sd_desc,
5046 syntax_defs[i].sd_flags,
5047 syntax_defs[i].sd_validate,
5048 syntax_defs[i].sd_normalize,
5049 syntax_defs[i].sd_pretty
5050 #ifdef SLAPD_BINARY_CONVERSION
5052 syntax_defs[i].sd_ber2str,
5053 syntax_defs[i].sd_str2ber
5058 fprintf( stderr, "schema_init: Error registering syntax %s\n",
5059 syntax_defs[i].sd_desc );
5064 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
5065 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
5067 "schema_init: Ingoring unusable matching rule %s\n",
5068 mrule_defs[i].mrd_desc );
5072 res = register_matching_rule(
5073 mrule_defs[i].mrd_desc,
5074 mrule_defs[i].mrd_usage,
5075 mrule_defs[i].mrd_convert,
5076 mrule_defs[i].mrd_normalize,
5077 mrule_defs[i].mrd_match,
5078 mrule_defs[i].mrd_indexer,
5079 mrule_defs[i].mrd_filter,
5080 mrule_defs[i].mrd_associated );
5084 "schema_init: Error registering matching rule %s\n",
5085 mrule_defs[i].mrd_desc );
5089 schema_init_done = 1;
5090 return LDAP_SUCCESS;
5094 schema_destroy( void )