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 #define integerPretty NULL
36 #ifndef USE_LDAP_DN_PARSING
37 # define dnPretty NULL
39 # define SLAP_LDAPDN_PRETTY 0x1
40 #endif /* !USE_LDAP_DN_PARSING */
42 /* recycled matching routines */
43 #define bitStringMatch octetStringMatch
44 #define numericStringMatch caseIgnoreIA5Match
45 #define objectIdentifierMatch caseIgnoreIA5Match
46 #define telephoneNumberMatch caseIgnoreIA5Match
47 #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
48 #define generalizedTimeMatch caseIgnoreIA5Match
49 #define generalizedTimeOrderingMatch caseIgnoreIA5Match
50 #define uniqueMemberMatch dnMatch
52 /* approx matching rules */
53 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
54 #define directoryStringApproxMatch approxMatch
55 #define directoryStringApproxIndexer approxIndexer
56 #define directoryStringApproxFilter approxFilter
57 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
58 #define IA5StringApproxMatch approxMatch
59 #define IA5StringApproxIndexer approxIndexer
60 #define IA5StringApproxFilter approxFilter
62 /* orderring matching rules */
63 #define caseIgnoreOrderingMatch caseIgnoreMatch
64 #define caseExactOrderingMatch caseExactMatch
66 /* unimplemented matching routines */
67 #define caseIgnoreListMatch NULL
68 #define caseIgnoreListSubstringsMatch NULL
69 #define protocolInformationMatch NULL
70 #define integerFirstComponentMatch NULL
72 #define OpenLDAPaciMatch NULL
73 #define authPasswordMatch NULL
75 /* recycled indexing/filtering routines */
76 #define dnIndexer caseExactIgnoreIndexer
77 #define dnFilter caseExactIgnoreFilter
78 #define bitStringFilter octetStringFilter
79 #define bitStringIndexer octetStringIndexer
81 #define telephoneNumberIndexer caseIgnoreIA5Indexer
82 #define telephoneNumberFilter caseIgnoreIA5Filter
83 #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
84 #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
86 /* must match OIDs below */
87 #define caseExactMatchOID "2.5.13.5"
88 #define caseExactSubstringsMatchOID "2.5.13.7"
90 static char *strcasechr( const char *str, int c )
92 char *lower = strchr( str, TOLOWER(c) );
93 char *upper = strchr( str, TOUPPER(c) );
95 if( lower && upper ) {
96 return lower < upper ? lower : upper;
110 struct berval *value,
111 void *assertedValue )
113 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
116 match = memcmp( value->bv_val,
117 ((struct berval *) assertedValue)->bv_val,
125 /* Index generation function */
126 int octetStringIndexer(
131 struct berval *prefix,
132 struct berval **values,
133 struct berval ***keysp )
137 struct berval **keys;
138 HASH_CONTEXT HASHcontext;
139 unsigned char HASHdigest[HASH_BYTES];
140 struct berval digest;
141 digest.bv_val = HASHdigest;
142 digest.bv_len = sizeof(HASHdigest);
144 for( i=0; values[i] != NULL; i++ ) {
145 /* just count them */
148 /* we should have at least one value at this point */
151 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
153 slen = strlen( syntax->ssyn_oid );
154 mlen = strlen( mr->smr_oid );
156 for( i=0; values[i] != NULL; i++ ) {
157 HASH_Init( &HASHcontext );
158 if( prefix != NULL && prefix->bv_len > 0 ) {
159 HASH_Update( &HASHcontext,
160 prefix->bv_val, prefix->bv_len );
162 HASH_Update( &HASHcontext,
163 syntax->ssyn_oid, slen );
164 HASH_Update( &HASHcontext,
166 HASH_Update( &HASHcontext,
167 values[i]->bv_val, values[i]->bv_len );
168 HASH_Final( HASHdigest, &HASHcontext );
170 keys[i] = ber_bvdup( &digest );
180 /* Index generation function */
181 int octetStringFilter(
186 struct berval *prefix,
188 struct berval ***keysp )
191 struct berval **keys;
192 HASH_CONTEXT HASHcontext;
193 unsigned char HASHdigest[HASH_BYTES];
194 struct berval *value = (struct berval *) assertValue;
195 struct berval digest;
196 digest.bv_val = HASHdigest;
197 digest.bv_len = sizeof(HASHdigest);
199 slen = strlen( syntax->ssyn_oid );
200 mlen = strlen( mr->smr_oid );
202 keys = ch_malloc( sizeof( struct berval * ) * 2 );
204 HASH_Init( &HASHcontext );
205 if( prefix != NULL && prefix->bv_len > 0 ) {
206 HASH_Update( &HASHcontext,
207 prefix->bv_val, prefix->bv_len );
209 HASH_Update( &HASHcontext,
210 syntax->ssyn_oid, slen );
211 HASH_Update( &HASHcontext,
213 HASH_Update( &HASHcontext,
214 value->bv_val, value->bv_len );
215 HASH_Final( HASHdigest, &HASHcontext );
217 keys[0] = ber_bvdup( &digest );
225 #ifdef USE_LDAP_DN_PARSING
227 #define AVA_PRIVATE( ava ) ( ( AttributeDescription * )(ava)->la_private )
230 * In-place, schema-aware validation of the
231 * structural representation of a distinguished name.
234 LDAPDN_validate( LDAPDN *dn )
241 for ( iRDN = 0; dn[ iRDN ]; iRDN++ ) {
242 LDAPRDN *rdn = dn[ iRDN ][ 0 ];
245 for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) {
246 LDAPAVA *ava = rdn[ iAVA ][ 0 ];
247 AttributeDescription *ad;
248 slap_syntax_validate_func *validate = NULL;
250 if ( ( ad = AVA_PRIVATE( ava ) ) == NULL ) {
251 const char *text = NULL;
253 rc = slap_bv2ad( ava->la_attr, &ad, &text );
254 if ( rc != LDAP_SUCCESS ) {
255 return LDAP_INVALID_SYNTAX;
258 ava->la_private = ( void * )ad;
262 * Replace attr oid/name with the canonical name
264 ber_bvfree( ava->la_attr );
265 ava->la_attr = ber_bvdup( &ad->ad_cname );
267 validate = ad->ad_type->sat_syntax->ssyn_validate;
271 * validate value by validate function
273 rc = ( *validate )( ad->ad_type->sat_syntax,
276 if ( rc != LDAP_SUCCESS ) {
277 return LDAP_INVALID_SYNTAX;
294 if ( in->bv_len == 0 ) {
295 return( LDAP_SUCCESS );
298 rc = ldap_str2dn( in->bv_val, &dn, LDAP_DN_FORMAT_LDAP );
301 * Schema-aware validate
303 if ( rc == LDAP_SUCCESS ) {
304 rc = LDAPDN_validate( dn );
307 ldapava_free_dn( dn );
309 if ( rc != LDAP_SUCCESS ) {
310 return( LDAP_INVALID_SYNTAX );
313 return( LDAP_SUCCESS );
317 AVA_Sort( LDAPRDN *rdn, int iAVA )
320 LDAPAVA *ava_in = rdn[ iAVA ][ 0 ];
322 for ( i = 0; i < iAVA; i++ ) {
323 LDAPAVA *ava = rdn[ i ][ 0 ];
326 a = strcmp( ava_in->la_attr->bv_val, ava->la_attr->bv_val );
335 d = ava_in->la_value->bv_len - ava->la_value->bv_len;
337 v = memcmp( ava_in->la_value->bv_val,
338 ava->la_value->bv_val,
339 d <= 0 ? ava_in->la_value->bv_len
340 : ava->la_value->bv_len );
342 if ( v == 0 && d != 0 ) {
361 a = strcmp( ava_in->la_value->bv_val,
362 ava->la_value->bv_val );
368 for ( j = iAVA; j > i; j-- ) {
369 rdn[ j ][ 0 ] = rdn[ j - 1 ][ 0 ];
371 rdn[ i ][ 0 ] = ava_in;
378 * In-place, schema-aware normalization / "pretty"ing of the
379 * structural representation of a distinguished name.
382 LDAPDN_rewrite( LDAPDN *dn, unsigned flags )
389 for ( iRDN = 0; dn[ iRDN ]; iRDN++ ) {
390 LDAPRDN *rdn = dn[ iRDN ][ 0 ];
393 for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) {
394 LDAPAVA *ava = rdn[ iAVA ][ 0 ];
395 AttributeDescription *ad;
396 slap_syntax_transform_func *transf = NULL;
398 struct berval *bv = NULL;
400 if ( ( ad = AVA_PRIVATE( ava ) ) == NULL ) {
401 const char *text = NULL;
403 rc = slap_bv2ad( ava->la_attr, &ad, &text );
404 if ( rc != LDAP_SUCCESS ) {
405 return LDAP_INVALID_SYNTAX;
408 ava->la_private = ( void * )ad;
412 * Replace attr oid/name with the canonical name
414 ber_bvfree( ava->la_attr );
415 ava->la_attr = ber_bvdup( &ad->ad_cname );
417 if( flags & SLAP_LDAPDN_PRETTY ) {
418 transf = ad->ad_type->sat_syntax->ssyn_pretty;
421 transf = ad->ad_type->sat_syntax->ssyn_normalize;
422 mr = ad->ad_type->sat_equality;
427 * transform value by normalize/pretty function
429 rc = ( *transf )( ad->ad_type->sat_syntax,
430 ava->la_value, &bv );
432 if ( rc != LDAP_SUCCESS ) {
433 return LDAP_INVALID_SYNTAX;
437 if( mr && ( mr->smr_usage & SLAP_MR_DN_FOLD ) ) {
438 struct berval *s = bv;
440 bv = ber_bvstr( UTF8normalize( bv ? bv : ava->la_value,
447 ber_bvfree( ava->la_value );
451 AVA_Sort( rdn, iAVA );
462 struct berval **normalized )
464 struct berval *out = NULL;
466 Debug( LDAP_DEBUG_TRACE, ">>> dnNormalize: <%s>\n", val->bv_val, 0, 0 );
468 if ( val->bv_len != 0 ) {
474 * Go to structural representation
476 rc = ldap_str2dn( val->bv_val, &dn, LDAP_DN_FORMAT_LDAP );
477 if ( rc != LDAP_SUCCESS ) {
478 return LDAP_INVALID_SYNTAX;
482 * Schema-aware rewrite
484 if ( LDAPDN_rewrite( dn, 0 ) != LDAP_SUCCESS ) {
485 ldapava_free_dn( dn );
486 return LDAP_INVALID_SYNTAX;
490 * Back to string representation
492 rc = ldap_dn2str( dn, &dn_out, LDAP_DN_FORMAT_LDAPV3 );
494 ldapava_free_dn( dn );
496 if ( rc != LDAP_SUCCESS ) {
497 return LDAP_INVALID_SYNTAX;
500 out = ber_bvstr( dn_out );
503 out = ber_bvdup( val );
506 Debug( LDAP_DEBUG_TRACE, "<<< dnNormalize: <%s>\n", out->bv_val, 0, 0 );
517 struct berval **pretty)
519 struct berval *out = NULL;
521 Debug( LDAP_DEBUG_TRACE, ">>> dnPretty: <%s>\n", val->bv_val, 0, 0 );
523 if ( val->bv_len != 0 ) {
528 /* FIXME: should be liberal in what we accept */
529 rc = ldap_str2dn( val->bv_val, &dn, LDAP_DN_FORMAT_LDAP );
530 if ( rc != LDAP_SUCCESS ) {
531 return LDAP_INVALID_SYNTAX;
535 * Schema-aware rewrite
537 if ( LDAPDN_rewrite( dn, SLAP_LDAPDN_PRETTY ) != LDAP_SUCCESS ) {
538 ldapava_free_dn( dn );
539 return LDAP_INVALID_SYNTAX;
542 /* FIXME: not sure why the default isn't pretty */
543 rc = ldap_dn2str( dn, &dn_out,
544 LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY );
546 ldapava_free_dn( dn );
548 if ( rc != LDAP_SUCCESS ) {
549 return LDAP_INVALID_SYNTAX;
552 out = ber_bvstr( dn_out );
555 out = ber_bvdup( val );
558 Debug( LDAP_DEBUG_TRACE, "<<< dnPretty: <%s>\n", out->bv_val, 0, 0 );
571 struct berval *value,
572 void *assertedValue )
575 struct berval *asserted = (struct berval *) assertedValue;
577 match = value->bv_len - asserted->bv_len;
580 match = strcmp( value->bv_val, asserted->bv_val );
584 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
585 "dnMatch: %d\n %s\n %s\n", match,
586 value->bv_val, asserted->bv_val ));
588 Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
589 match, value->bv_val, asserted->bv_val );
593 return( LDAP_SUCCESS );
596 #else /* !USE_LDAP_DN_PARSING */
606 if( in->bv_len == 0 ) return LDAP_SUCCESS;
608 dn = ch_strdup( in->bv_val );
611 return LDAP_INVALID_SYNTAX;
613 } else if ( strlen( in->bv_val ) != in->bv_len ) {
614 rc = LDAP_INVALID_SYNTAX;
616 } else if ( dn_validate( dn ) == NULL ) {
617 rc = LDAP_INVALID_SYNTAX;
631 struct berval **normalized )
635 if ( val->bv_len != 0 ) {
637 out = ber_bvstr( UTF8normalize( val, UTF8_CASEFOLD ) );
639 dn = dn_validate( out->bv_val );
643 return LDAP_INVALID_SYNTAX;
647 out->bv_len = strlen( dn );
649 out = ber_bvdup( val );
662 struct berval *value,
663 void *assertedValue )
666 struct berval *asserted = (struct berval *) assertedValue;
668 match = value->bv_len - asserted->bv_len;
671 #ifdef USE_DN_NORMALIZE
672 match = strcmp( value->bv_val, asserted->bv_val );
674 match = strcasecmp( value->bv_val, asserted->bv_val );
679 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
680 "dnMatch: %d\n %s\n %s\n", match,
681 value->bv_val, asserted->bv_val ));
683 Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
684 match, value->bv_val, asserted->bv_val );
692 #endif /* !USE_LDAP_DN_PARSING */
702 if( in->bv_len == 0 ) return LDAP_SUCCESS;
704 dn = ber_bvdup( in );
706 if( dn->bv_val[dn->bv_len-1] == '\'' ) {
707 /* assume presence of optional UID */
710 for(i=dn->bv_len-2; i>2; i--) {
711 if( dn->bv_val[i] != '0' && dn->bv_val[i] != '1' ) {
715 if( dn->bv_val[i] != '\'' ||
716 dn->bv_val[i-1] != 'B' ||
717 dn->bv_val[i-2] != '#' ) {
719 return LDAP_INVALID_SYNTAX;
722 /* trim the UID to allow use of dn_validate */
723 dn->bv_val[i-2] = '\0';
726 rc = dn_validate( dn->bv_val ) == NULL
727 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
737 struct berval **normalized )
739 struct berval *out = ber_bvdup( val );
741 if( out->bv_len != 0 ) {
745 ber_len_t uidlen = 0;
747 if( out->bv_val[out->bv_len-1] == '\'' ) {
748 /* assume presence of optional UID */
749 uid = strrchr( out->bv_val, '#' );
753 return LDAP_INVALID_SYNTAX;
756 uidlen = out->bv_len - (out->bv_val - uid);
757 /* temporarily trim the UID */
761 #ifdef USE_DN_NORMALIZE
762 dn = dn_normalize( out->bv_val );
764 dn = dn_validate( out->bv_val );
769 return LDAP_INVALID_SYNTAX;
775 /* restore the separator */
778 SAFEMEMCPY( &dn[dnlen], uid, uidlen );
782 out->bv_len = dnlen + uidlen;
794 /* any value allowed */
803 /* any value allowed */
814 /* very unforgiving validation, requires no normalization
815 * before simplistic matching
817 if( in->bv_len < 3 ) {
818 return LDAP_INVALID_SYNTAX;
822 * rfc 2252 section 6.3 Bit String
823 * bitstring = "'" *binary-digit "'"
824 * binary-digit = "0" / "1"
825 * example: '0101111101'B
828 if( in->bv_val[0] != '\'' ||
829 in->bv_val[in->bv_len-2] != '\'' ||
830 in->bv_val[in->bv_len-1] != 'B' )
832 return LDAP_INVALID_SYNTAX;
835 for( i=in->bv_len-3; i>0; i-- ) {
836 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
837 return LDAP_INVALID_SYNTAX;
848 struct berval **normalized )
851 * A normalized bitString is has no extaneous (leading) zero bits.
852 * That is, '00010'B is normalized to '10'B
853 * However, as a special case, '0'B requires no normalization.
855 struct berval *newval;
858 /* start at the first bit */
861 /* Find the first non-zero bit */
862 while ( *p == '0' ) p++;
864 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
867 /* no non-zero bits */
868 newval->bv_val = ch_strdup("\'0\'B");
869 newval->bv_len = sizeof("\'0\'B") - 1;
873 newval->bv_val = ch_malloc( val->bv_len + 1 );
875 newval->bv_val[0] = '\'';
878 for( ; *p != '\0'; p++ ) {
879 newval->bv_val[newval->bv_len++] = *p;
882 newval->bv_val[newval->bv_len] = '\0';
885 *normalized = newval;
890 * Handling boolean syntax and matching is quite rigid.
891 * A more flexible approach would be to allow a variety
892 * of strings to be normalized and prettied into TRUE
900 /* very unforgiving validation, requires no normalization
901 * before simplistic matching
904 if( in->bv_len == 4 ) {
905 if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
908 } else if( in->bv_len == 5 ) {
909 if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
914 return LDAP_INVALID_SYNTAX;
923 struct berval *value,
924 void *assertedValue )
926 /* simplistic matching allowed by rigid validation */
927 struct berval *asserted = (struct berval *) assertedValue;
928 *matchp = value->bv_len != asserted->bv_len;
939 unsigned char *u = in->bv_val;
941 if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
943 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
944 /* get the length indicated by the first byte */
945 len = LDAP_UTF8_CHARLEN( u );
947 /* should not be zero */
948 if( len == 0 ) return LDAP_INVALID_SYNTAX;
950 /* make sure len corresponds with the offset
951 to the next character */
952 if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
955 if( count != 0 ) return LDAP_INVALID_SYNTAX;
964 struct berval **normalized )
966 struct berval *newval;
969 newval = ch_malloc( sizeof( struct berval ) );
973 /* Ignore initial whitespace */
974 while ( ldap_utf8_isspace( p ) ) {
980 return LDAP_INVALID_SYNTAX;
983 newval->bv_val = ch_strdup( p );
984 p = q = newval->bv_val;
990 if ( ldap_utf8_isspace( p ) ) {
991 len = LDAP_UTF8_COPY(q,p);
996 /* Ignore the extra whitespace */
997 while ( ldap_utf8_isspace( p ) ) {
1001 len = LDAP_UTF8_COPY(q,p);
1008 assert( *newval->bv_val );
1009 assert( newval->bv_val < p );
1012 /* cannot start with a space */
1013 assert( !ldap_utf8_isspace(newval->bv_val) );
1016 * If the string ended in space, backup the pointer one
1017 * position. One is enough because the above loop collapsed
1018 * all whitespace to a single space.
1025 /* cannot end with a space */
1026 assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
1028 /* null terminate */
1031 newval->bv_len = q - newval->bv_val;
1032 *normalized = newval;
1034 return LDAP_SUCCESS;
1037 /* Returns Unicode cannonically normalized copy of a substring assertion
1038 * Skipping attribute description */
1039 SubstringsAssertion *
1040 UTF8SubstringsassertionNormalize(
1041 SubstringsAssertion *sa,
1044 SubstringsAssertion *nsa;
1047 nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
1052 if( sa->sa_initial != NULL ) {
1053 nsa->sa_initial = ber_bvstr( UTF8normalize( sa->sa_initial, casefold ) );
1054 if( nsa->sa_initial == NULL ) {
1059 if( sa->sa_any != NULL ) {
1060 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1063 nsa->sa_any = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
1064 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1065 nsa->sa_any[i] = ber_bvstr( UTF8normalize( sa->sa_any[i], casefold ) );
1066 if( nsa->sa_any[i] == NULL ) {
1070 nsa->sa_any[i] = NULL;
1073 if( sa->sa_final != NULL ) {
1074 nsa->sa_final = ber_bvstr( UTF8normalize( sa->sa_final, casefold ) );
1075 if( nsa->sa_final == NULL ) {
1083 ber_bvfree( nsa->sa_final );
1084 ber_bvecfree( nsa->sa_any );
1085 ber_bvfree( nsa->sa_initial );
1090 /* Strip characters with the 8th bit set */
1103 while( *++q & 0x80 ) {
1106 p = memmove(p, q, strlen(q) + 1);
1114 #ifndef SLAPD_APPROX_OLDSINGLESTRING
1116 #if defined(SLAPD_APPROX_INITIALS)
1117 #define SLAPD_APPROX_DELIMITER "._ "
1118 #define SLAPD_APPROX_WORDLEN 2
1120 #define SLAPD_APPROX_DELIMITER " "
1121 #define SLAPD_APPROX_WORDLEN 1
1130 struct berval *value,
1131 void *assertedValue )
1133 char *val, *nval, *assertv, **values, **words, *c;
1134 int i, count, len, nextchunk=0, nextavail=0;
1137 /* Yes, this is necessary */
1138 nval = UTF8normalize( value, UTF8_NOCASEFOLD );
1139 if( nval == NULL ) {
1141 return LDAP_SUCCESS;
1143 strip8bitChars( nval );
1145 /* Yes, this is necessary */
1146 assertv = UTF8normalize( ((struct berval *)assertedValue),
1148 if( assertv == NULL ) {
1151 return LDAP_SUCCESS;
1153 strip8bitChars( assertv );
1154 avlen = strlen( assertv );
1156 /* Isolate how many words there are */
1157 for( c=nval,count=1; *c; c++ ) {
1158 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
1159 if ( c == NULL ) break;
1164 /* Get a phonetic copy of each word */
1165 words = (char **)ch_malloc( count * sizeof(char *) );
1166 values = (char **)ch_malloc( count * sizeof(char *) );
1167 for( c=nval,i=0; i<count; i++,c+=strlen(c)+1 ) {
1169 values[i] = phonetic(c);
1172 /* Work through the asserted value's words, to see if at least some
1173 of the words are there, in the same order. */
1175 while ( nextchunk < avlen ) {
1176 len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER);
1181 #if defined(SLAPD_APPROX_INITIALS)
1182 else if( len == 1 ) {
1183 /* Single letter words need to at least match one word's initial */
1184 for( i=nextavail; i<count; i++ )
1185 if( !strncasecmp( assertv+nextchunk, words[i], 1 )) {
1192 /* Isolate the next word in the asserted value and phonetic it */
1193 assertv[nextchunk+len] = '\0';
1194 val = phonetic( assertv + nextchunk );
1196 /* See if this phonetic chunk is in the remaining words of *value */
1197 for( i=nextavail; i<count; i++ ){
1198 if( !strcmp( val, values[i] ) ){
1206 /* This chunk in the asserted value was NOT within the *value. */
1212 /* Go on to the next word in the asserted value */
1216 /* If some of the words were seen, call it a match */
1217 if( nextavail > 0 ) {
1224 /* Cleanup allocs */
1226 for( i=0; i<count; i++ ) {
1227 ch_free( values[i] );
1233 return LDAP_SUCCESS;
1242 struct berval *prefix,
1243 struct berval **values,
1244 struct berval ***keysp )
1247 int i,j, len, wordcount, keycount=0;
1248 struct berval **newkeys, **keys=NULL;
1250 for( j=0; values[j] != NULL; j++ ) {
1251 /* Yes, this is necessary */
1252 val = UTF8normalize( values[j], UTF8_NOCASEFOLD );
1253 strip8bitChars( val );
1255 /* Isolate how many words there are. There will be a key for each */
1256 for( wordcount=0,c=val; *c; c++) {
1257 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1258 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1260 if (*c == '\0') break;
1264 /* Allocate/increase storage to account for new keys */
1265 newkeys = (struct berval **)ch_malloc( (keycount + wordcount + 1)
1266 * sizeof(struct berval *) );
1267 memcpy( newkeys, keys, keycount * sizeof(struct berval *) );
1268 if( keys ) ch_free( keys );
1271 /* Get a phonetic copy of each word */
1272 for( c=val,i=0; i<wordcount; c+=len+1 ) {
1274 if( len < SLAPD_APPROX_WORDLEN ) continue;
1275 keys[keycount] = (struct berval *)ch_malloc( sizeof(struct berval) );
1276 keys[keycount]->bv_val = phonetic( c );
1277 keys[keycount]->bv_len = strlen( keys[keycount]->bv_val );
1284 keys[keycount] = NULL;
1287 return LDAP_SUCCESS;
1296 struct berval *prefix,
1298 struct berval ***keysp )
1302 struct berval **keys;
1304 /* Yes, this is necessary */
1305 val = UTF8normalize( ((struct berval *)assertValue),
1308 keys = (struct berval **)ch_malloc( sizeof(struct berval *) );
1311 return LDAP_SUCCESS;
1313 strip8bitChars( val );
1315 /* Isolate how many words there are. There will be a key for each */
1316 for( count=0,c=val; *c; c++) {
1317 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1318 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1320 if (*c == '\0') break;
1324 /* Allocate storage for new keys */
1325 keys = (struct berval **)ch_malloc( (count + 1) * sizeof(struct berval *) );
1327 /* Get a phonetic copy of each word */
1328 for( c=val,i=0; i<count; c+=len+1 ) {
1330 if( len < SLAPD_APPROX_WORDLEN ) continue;
1331 keys[i] = ber_bvstr( phonetic( c ) );
1340 return LDAP_SUCCESS;
1345 /* No other form of Approximate Matching is defined */
1353 struct berval *value,
1354 void *assertedValue )
1356 char *vapprox, *avapprox;
1359 /* Yes, this is necessary */
1360 s = UTF8normalize( value, UTF8_NOCASEFOLD );
1363 return LDAP_SUCCESS;
1366 /* Yes, this is necessary */
1367 t = UTF8normalize( ((struct berval *)assertedValue),
1372 return LDAP_SUCCESS;
1375 vapprox = phonetic( strip8bitChars( s ) );
1376 avapprox = phonetic( strip8bitChars( t ) );
1381 *matchp = strcmp( vapprox, avapprox );
1384 ch_free( avapprox );
1386 return LDAP_SUCCESS;
1395 struct berval *prefix,
1396 struct berval **values,
1397 struct berval ***keysp )
1400 struct berval **keys;
1403 for( i=0; values[i] != NULL; i++ ) {
1404 /* empty - just count them */
1407 /* we should have at least one value at this point */
1410 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * (i+1) );
1412 /* Copy each value and run it through phonetic() */
1413 for( i=0; values[i] != NULL; i++ ) {
1414 /* Yes, this is necessary */
1415 s = UTF8normalize( values[i], UTF8_NOCASEFOLD );
1417 /* strip 8-bit chars and run through phonetic() */
1418 keys[i] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1424 return LDAP_SUCCESS;
1434 struct berval *prefix,
1436 struct berval ***keysp )
1438 struct berval **keys;
1441 keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * 2 );
1443 /* Yes, this is necessary */
1444 s = UTF8normalize( ((struct berval *)assertValue),
1449 /* strip 8-bit chars and run through phonetic() */
1450 keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
1456 return LDAP_SUCCESS;
1467 struct berval *value,
1468 void *assertedValue )
1470 *matchp = UTF8normcmp( value->bv_val,
1471 ((struct berval *) assertedValue)->bv_val,
1473 return LDAP_SUCCESS;
1477 caseExactIgnoreSubstringsMatch(
1482 struct berval *value,
1483 void *assertedValue )
1486 SubstringsAssertion *sub = NULL;
1490 char *nav, casefold;
1492 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1493 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1495 nav = UTF8normalize( value, casefold );
1501 left.bv_len = strlen( nav );
1503 sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
1509 /* Add up asserted input length */
1510 if( sub->sa_initial ) {
1511 inlen += sub->sa_initial->bv_len;
1514 for(i=0; sub->sa_any[i] != NULL; i++) {
1515 inlen += sub->sa_any[i]->bv_len;
1518 if( sub->sa_final ) {
1519 inlen += sub->sa_final->bv_len;
1522 if( sub->sa_initial ) {
1523 if( inlen > left.bv_len ) {
1528 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
1529 sub->sa_initial->bv_len );
1535 left.bv_val += sub->sa_initial->bv_len;
1536 left.bv_len -= sub->sa_initial->bv_len;
1537 inlen -= sub->sa_initial->bv_len;
1540 if( sub->sa_final ) {
1541 if( inlen > left.bv_len ) {
1546 match = strncmp( sub->sa_final->bv_val,
1547 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
1548 sub->sa_final->bv_len );
1554 left.bv_len -= sub->sa_final->bv_len;
1555 inlen -= sub->sa_final->bv_len;
1559 for(i=0; sub->sa_any[i]; i++) {
1564 if( inlen > left.bv_len ) {
1565 /* not enough length */
1570 if( sub->sa_any[i]->bv_len == 0 ) {
1574 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
1581 idx = p - left.bv_val;
1582 assert( idx < left.bv_len );
1584 if( idx >= left.bv_len ) {
1585 /* this shouldn't happen */
1587 ch_free( sub->sa_final );
1588 ber_bvecfree( sub->sa_any );
1589 ch_free( sub->sa_initial );
1597 if( sub->sa_any[i]->bv_len > left.bv_len ) {
1598 /* not enough left */
1603 match = strncmp( left.bv_val,
1604 sub->sa_any[i]->bv_val,
1605 sub->sa_any[i]->bv_len );
1613 left.bv_val += sub->sa_any[i]->bv_len;
1614 left.bv_len -= sub->sa_any[i]->bv_len;
1615 inlen -= sub->sa_any[i]->bv_len;
1622 ber_bvfree( sub->sa_final );
1623 ber_bvecfree( sub->sa_any );
1624 ber_bvfree( sub->sa_initial );
1628 return LDAP_SUCCESS;
1631 /* Index generation function */
1632 int caseExactIgnoreIndexer(
1637 struct berval *prefix,
1638 struct berval **values,
1639 struct berval ***keysp )
1644 struct berval **keys;
1645 HASH_CONTEXT HASHcontext;
1646 unsigned char HASHdigest[HASH_BYTES];
1647 struct berval digest;
1648 digest.bv_val = HASHdigest;
1649 digest.bv_len = sizeof(HASHdigest);
1651 for( i=0; values[i] != NULL; i++ ) {
1652 /* empty - just count them */
1655 /* we should have at least one value at this point */
1658 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
1660 slen = strlen( syntax->ssyn_oid );
1661 mlen = strlen( mr->smr_oid );
1663 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1664 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1666 for( i=0; values[i] != NULL; i++ ) {
1667 struct berval *value;
1668 value = ber_bvstr( UTF8normalize( values[i],
1671 HASH_Init( &HASHcontext );
1672 if( prefix != NULL && prefix->bv_len > 0 ) {
1673 HASH_Update( &HASHcontext,
1674 prefix->bv_val, prefix->bv_len );
1676 HASH_Update( &HASHcontext,
1677 syntax->ssyn_oid, slen );
1678 HASH_Update( &HASHcontext,
1679 mr->smr_oid, mlen );
1680 HASH_Update( &HASHcontext,
1681 value->bv_val, value->bv_len );
1682 HASH_Final( HASHdigest, &HASHcontext );
1684 ber_bvfree( value );
1686 keys[i] = ber_bvdup( &digest );
1691 return LDAP_SUCCESS;
1694 /* Index generation function */
1695 int caseExactIgnoreFilter(
1700 struct berval *prefix,
1702 struct berval ***keysp )
1706 struct berval **keys;
1707 HASH_CONTEXT HASHcontext;
1708 unsigned char HASHdigest[HASH_BYTES];
1709 struct berval *value;
1710 struct berval digest;
1711 digest.bv_val = HASHdigest;
1712 digest.bv_len = sizeof(HASHdigest);
1714 slen = strlen( syntax->ssyn_oid );
1715 mlen = strlen( mr->smr_oid );
1717 casefold = strcmp( mr->smr_oid, caseExactMatchOID )
1718 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1720 value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue),
1722 /* This usually happens if filter contains bad UTF8 */
1723 if( value == NULL ) {
1724 keys = ch_malloc( sizeof( struct berval * ) );
1726 return LDAP_SUCCESS;
1729 keys = ch_malloc( sizeof( struct berval * ) * 2 );
1731 HASH_Init( &HASHcontext );
1732 if( prefix != NULL && prefix->bv_len > 0 ) {
1733 HASH_Update( &HASHcontext,
1734 prefix->bv_val, prefix->bv_len );
1736 HASH_Update( &HASHcontext,
1737 syntax->ssyn_oid, slen );
1738 HASH_Update( &HASHcontext,
1739 mr->smr_oid, mlen );
1740 HASH_Update( &HASHcontext,
1741 value->bv_val, value->bv_len );
1742 HASH_Final( HASHdigest, &HASHcontext );
1744 keys[0] = ber_bvdup( &digest );
1747 ber_bvfree( value );
1750 return LDAP_SUCCESS;
1753 /* Substrings Index generation function */
1754 int caseExactIgnoreSubstringsIndexer(
1759 struct berval *prefix,
1760 struct berval **values,
1761 struct berval ***keysp )
1766 struct berval **keys;
1767 struct berval **nvalues;
1769 HASH_CONTEXT HASHcontext;
1770 unsigned char HASHdigest[HASH_BYTES];
1771 struct berval digest;
1772 digest.bv_val = HASHdigest;
1773 digest.bv_len = sizeof(HASHdigest);
1777 for( i=0; values[i] != NULL; i++ ) {
1778 /* empty - just count them */
1781 /* we should have at least one value at this point */
1784 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1785 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1787 nvalues = ch_malloc( sizeof( struct berval * ) * (i+1) );
1788 for( i=0; values[i] != NULL; i++ ) {
1789 nvalues[i] = ber_bvstr( UTF8normalize( values[i],
1795 for( i=0; values[i] != NULL; i++ ) {
1796 /* count number of indices to generate */
1797 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
1801 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1802 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1803 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1804 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1806 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1810 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
1811 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1812 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1816 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1817 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1818 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
1819 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
1821 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
1827 /* no keys to generate */
1829 ber_bvecfree( nvalues );
1830 return LDAP_SUCCESS;
1833 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
1835 slen = strlen( syntax->ssyn_oid );
1836 mlen = strlen( mr->smr_oid );
1839 for( i=0; values[i] != NULL; i++ ) {
1841 struct berval *value;
1843 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
1847 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
1848 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
1850 char pre = SLAP_INDEX_SUBSTR_PREFIX;
1851 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
1853 for( j=0; j<max; j++ ) {
1854 HASH_Init( &HASHcontext );
1855 if( prefix != NULL && prefix->bv_len > 0 ) {
1856 HASH_Update( &HASHcontext,
1857 prefix->bv_val, prefix->bv_len );
1860 HASH_Update( &HASHcontext,
1861 &pre, sizeof( pre ) );
1862 HASH_Update( &HASHcontext,
1863 syntax->ssyn_oid, slen );
1864 HASH_Update( &HASHcontext,
1865 mr->smr_oid, mlen );
1866 HASH_Update( &HASHcontext,
1868 SLAP_INDEX_SUBSTR_MAXLEN );
1869 HASH_Final( HASHdigest, &HASHcontext );
1871 keys[nkeys++] = ber_bvdup( &digest );
1875 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
1876 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
1878 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
1881 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
1882 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
1883 HASH_Init( &HASHcontext );
1884 if( prefix != NULL && prefix->bv_len > 0 ) {
1885 HASH_Update( &HASHcontext,
1886 prefix->bv_val, prefix->bv_len );
1888 HASH_Update( &HASHcontext,
1889 &pre, sizeof( pre ) );
1890 HASH_Update( &HASHcontext,
1891 syntax->ssyn_oid, slen );
1892 HASH_Update( &HASHcontext,
1893 mr->smr_oid, mlen );
1894 HASH_Update( &HASHcontext,
1896 HASH_Final( HASHdigest, &HASHcontext );
1898 keys[nkeys++] = ber_bvdup( &digest );
1901 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
1902 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
1903 HASH_Init( &HASHcontext );
1904 if( prefix != NULL && prefix->bv_len > 0 ) {
1905 HASH_Update( &HASHcontext,
1906 prefix->bv_val, prefix->bv_len );
1908 HASH_Update( &HASHcontext,
1909 &pre, sizeof( pre ) );
1910 HASH_Update( &HASHcontext,
1911 syntax->ssyn_oid, slen );
1912 HASH_Update( &HASHcontext,
1913 mr->smr_oid, mlen );
1914 HASH_Update( &HASHcontext,
1915 &value->bv_val[value->bv_len-j], j );
1916 HASH_Final( HASHdigest, &HASHcontext );
1918 keys[nkeys++] = ber_bvdup( &digest );
1933 ber_bvecfree( nvalues );
1935 return LDAP_SUCCESS;
1938 int caseExactIgnoreSubstringsFilter(
1943 struct berval *prefix,
1945 struct berval ***keysp )
1947 SubstringsAssertion *sa;
1949 ber_len_t nkeys = 0;
1950 size_t slen, mlen, klen;
1951 struct berval **keys;
1952 HASH_CONTEXT HASHcontext;
1953 unsigned char HASHdigest[HASH_BYTES];
1954 struct berval *value;
1955 struct berval digest;
1957 casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
1958 ? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
1960 sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
1963 return LDAP_SUCCESS;
1966 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
1967 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1972 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
1974 for( i=0; sa->sa_any[i] != NULL; i++ ) {
1975 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
1976 /* don't bother accounting for stepping */
1977 nkeys += sa->sa_any[i]->bv_len -
1978 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
1983 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
1984 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
1990 ber_bvfree( sa->sa_final );
1991 ber_bvecfree( sa->sa_any );
1992 ber_bvfree( sa->sa_initial );
1995 return LDAP_SUCCESS;
1998 digest.bv_val = HASHdigest;
1999 digest.bv_len = sizeof(HASHdigest);
2001 slen = strlen( syntax->ssyn_oid );
2002 mlen = strlen( mr->smr_oid );
2004 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2007 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2008 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2010 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2011 value = sa->sa_initial;
2013 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2014 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2016 HASH_Init( &HASHcontext );
2017 if( prefix != NULL && prefix->bv_len > 0 ) {
2018 HASH_Update( &HASHcontext,
2019 prefix->bv_val, prefix->bv_len );
2021 HASH_Update( &HASHcontext,
2022 &pre, sizeof( pre ) );
2023 HASH_Update( &HASHcontext,
2024 syntax->ssyn_oid, slen );
2025 HASH_Update( &HASHcontext,
2026 mr->smr_oid, mlen );
2027 HASH_Update( &HASHcontext,
2028 value->bv_val, klen );
2029 HASH_Final( HASHdigest, &HASHcontext );
2031 keys[nkeys++] = ber_bvdup( &digest );
2034 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2036 pre = SLAP_INDEX_SUBSTR_PREFIX;
2037 klen = SLAP_INDEX_SUBSTR_MAXLEN;
2039 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2040 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
2044 value = sa->sa_any[i];
2047 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
2048 j += SLAP_INDEX_SUBSTR_STEP )
2050 HASH_Init( &HASHcontext );
2051 if( prefix != NULL && prefix->bv_len > 0 ) {
2052 HASH_Update( &HASHcontext,
2053 prefix->bv_val, prefix->bv_len );
2055 HASH_Update( &HASHcontext,
2056 &pre, sizeof( pre ) );
2057 HASH_Update( &HASHcontext,
2058 syntax->ssyn_oid, slen );
2059 HASH_Update( &HASHcontext,
2060 mr->smr_oid, mlen );
2061 HASH_Update( &HASHcontext,
2062 &value->bv_val[j], klen );
2063 HASH_Final( HASHdigest, &HASHcontext );
2065 keys[nkeys++] = ber_bvdup( &digest );
2071 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2072 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2074 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2075 value = sa->sa_final;
2077 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2078 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2080 HASH_Init( &HASHcontext );
2081 if( prefix != NULL && prefix->bv_len > 0 ) {
2082 HASH_Update( &HASHcontext,
2083 prefix->bv_val, prefix->bv_len );
2085 HASH_Update( &HASHcontext,
2086 &pre, sizeof( pre ) );
2087 HASH_Update( &HASHcontext,
2088 syntax->ssyn_oid, slen );
2089 HASH_Update( &HASHcontext,
2090 mr->smr_oid, mlen );
2091 HASH_Update( &HASHcontext,
2092 &value->bv_val[value->bv_len-klen], klen );
2093 HASH_Final( HASHdigest, &HASHcontext );
2095 keys[nkeys++] = ber_bvdup( &digest );
2105 ber_bvfree( sa->sa_final );
2106 ber_bvecfree( sa->sa_any );
2107 ber_bvfree( sa->sa_initial );
2110 return LDAP_SUCCESS;
2119 struct berval *value,
2120 void *assertedValue )
2122 *matchp = UTF8normcmp( value->bv_val,
2123 ((struct berval *) assertedValue)->bv_val,
2125 return LDAP_SUCCESS;
2131 struct berval *val )
2135 if( val->bv_len == 0 ) {
2136 /* disallow empty strings */
2137 return LDAP_INVALID_SYNTAX;
2140 if( OID_LEADCHAR(val->bv_val[0]) ) {
2142 for(i=1; i < val->bv_len; i++) {
2143 if( OID_SEPARATOR( val->bv_val[i] ) ) {
2144 if( dot++ ) return 1;
2145 } else if ( OID_CHAR( val->bv_val[i] ) ) {
2148 return LDAP_INVALID_SYNTAX;
2152 return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
2154 } else if( DESC_LEADCHAR(val->bv_val[0]) ) {
2155 for(i=1; i < val->bv_len; i++) {
2156 if( !DESC_CHAR(val->bv_val[i] ) ) {
2157 return LDAP_INVALID_SYNTAX;
2161 return LDAP_SUCCESS;
2164 return LDAP_INVALID_SYNTAX;
2173 struct berval *value,
2174 void *assertedValue )
2177 int vsign=0, avsign=0;
2178 struct berval *asserted;
2179 ber_len_t vlen, avlen;
2182 /* Start off pessimistic */
2185 /* Skip past leading spaces/zeros, and get the sign of the *value number */
2187 vlen = value->bv_len;
2189 if( ASCII_SPACE(*v) || ( *v == '0' )) {
2190 /* empty -- skip spaces */
2192 else if ( *v == '+' ) {
2195 else if ( *v == '-' ) {
2198 else if ( ASCII_DIGIT(*v) ) {
2199 if ( vsign == 0 ) vsign = 1;
2207 /* Skip past leading spaces/zeros, and get the sign of the *assertedValue
2209 asserted = (struct berval *) assertedValue;
2210 av = asserted->bv_val;
2211 avlen = asserted->bv_len;
2213 if( ASCII_SPACE(*av) || ( *av == '0' )) {
2214 /* empty -- skip spaces */
2216 else if ( *av == '+' ) {
2219 else if ( *av == '-' ) {
2222 else if ( ASCII_DIGIT(*av) ) {
2223 if ( avsign == 0 ) avsign = 1;
2231 /* The two ?sign vars are now one of :
2232 -2 negative non-zero number
2234 0 0 collapse these three to 0
2236 +2 positive non-zero number
2238 if ( abs( vsign ) == 1 ) vsign = 0;
2239 if ( abs( avsign ) == 1 ) avsign = 0;
2241 if( vsign != avsign ) return LDAP_SUCCESS;
2243 /* Check the significant digits */
2244 while( vlen && avlen ) {
2245 if( *v != *av ) break;
2252 /* If all digits compared equal, the numbers are equal */
2253 if(( vlen == 0 ) && ( avlen == 0 )) {
2256 return LDAP_SUCCESS;
2262 struct berval *val )
2266 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2268 if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
2269 if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
2270 } else if( !ASCII_DIGIT(val->bv_val[0]) ) {
2271 return LDAP_INVALID_SYNTAX;
2274 for( i=1; i < val->bv_len; i++ ) {
2275 if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2278 return LDAP_SUCCESS;
2285 struct berval **normalized )
2289 struct berval *newval;
2296 /* Ignore leading spaces */
2297 while ( len && ( *p == ' ' )) {
2304 negative = ( *p == '-' );
2305 if(( *p == '-' ) || ( *p == '+' )) {
2311 /* Ignore leading zeros */
2312 while ( len && ( *p == '0' )) {
2317 newval = (struct berval *) ch_malloc( sizeof(struct berval) );
2319 /* If there are no non-zero digits left, the number is zero, otherwise
2320 allocate space for the number and copy it into the buffer */
2322 newval->bv_val = ch_strdup("0");
2326 newval->bv_len = len+negative;
2327 newval->bv_val = ch_malloc( newval->bv_len );
2329 newval->bv_val[0] = '-';
2331 memcpy( newval->bv_val + negative, p, len );
2334 *normalized = newval;
2335 return LDAP_SUCCESS;
2338 /* Index generation function */
2344 struct berval *prefix,
2345 struct berval **values,
2346 struct berval ***keysp )
2349 struct berval **keys;
2351 /* we should have at least one value at this point */
2352 assert( values != NULL && values[0] != NULL );
2354 for( i=0; values[i] != NULL; i++ ) {
2355 /* empty -- just count them */
2358 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2360 for( i=0; values[i] != NULL; i++ ) {
2361 integerNormalize( syntax, values[i], &keys[i] );
2366 return LDAP_SUCCESS;
2369 /* Index generation function */
2375 struct berval *prefix,
2377 struct berval ***keysp )
2379 struct berval **keys;
2381 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2382 integerNormalize( syntax, assertValue, &keys[0] );
2386 return LDAP_SUCCESS;
2391 countryStringValidate(
2393 struct berval *val )
2395 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
2397 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
2398 return LDAP_INVALID_SYNTAX;
2400 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
2401 return LDAP_INVALID_SYNTAX;
2404 return LDAP_SUCCESS;
2408 printableStringValidate(
2410 struct berval *val )
2414 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2416 for(i=0; i < val->bv_len; i++) {
2417 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
2418 return LDAP_INVALID_SYNTAX;
2422 return LDAP_SUCCESS;
2426 printablesStringValidate(
2428 struct berval *val )
2432 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2434 for(i=0; i < val->bv_len; i++) {
2435 if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
2436 return LDAP_INVALID_SYNTAX;
2440 return LDAP_SUCCESS;
2446 struct berval *val )
2450 if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
2452 for(i=0; i < val->bv_len; i++) {
2453 if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
2456 return LDAP_SUCCESS;
2463 struct berval **normalized )
2465 struct berval *newval;
2468 newval = ch_malloc( sizeof( struct berval ) );
2472 /* Ignore initial whitespace */
2473 while ( ASCII_SPACE( *p ) ) {
2479 return LDAP_INVALID_SYNTAX;
2482 newval->bv_val = ch_strdup( p );
2483 p = q = newval->bv_val;
2486 if ( ASCII_SPACE( *p ) ) {
2489 /* Ignore the extra whitespace */
2490 while ( ASCII_SPACE( *p ) ) {
2498 assert( *newval->bv_val );
2499 assert( newval->bv_val < p );
2502 /* cannot start with a space */
2503 assert( !ASCII_SPACE(*newval->bv_val) );
2506 * If the string ended in space, backup the pointer one
2507 * position. One is enough because the above loop collapsed
2508 * all whitespace to a single space.
2511 if ( ASCII_SPACE( q[-1] ) ) {
2515 /* cannot end with a space */
2516 assert( !ASCII_SPACE( q[-1] ) );
2518 /* null terminate */
2521 newval->bv_len = q - newval->bv_val;
2522 *normalized = newval;
2524 return LDAP_SUCCESS;
2533 struct berval *value,
2534 void *assertedValue )
2536 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
2539 match = strncmp( value->bv_val,
2540 ((struct berval *) assertedValue)->bv_val,
2545 return LDAP_SUCCESS;
2549 caseExactIA5SubstringsMatch(
2554 struct berval *value,
2555 void *assertedValue )
2558 SubstringsAssertion *sub = assertedValue;
2559 struct berval left = *value;
2563 /* Add up asserted input length */
2564 if( sub->sa_initial ) {
2565 inlen += sub->sa_initial->bv_len;
2568 for(i=0; sub->sa_any[i] != NULL; i++) {
2569 inlen += sub->sa_any[i]->bv_len;
2572 if( sub->sa_final ) {
2573 inlen += sub->sa_final->bv_len;
2576 if( sub->sa_initial ) {
2577 if( inlen > left.bv_len ) {
2582 match = strncmp( sub->sa_initial->bv_val, left.bv_val,
2583 sub->sa_initial->bv_len );
2589 left.bv_val += sub->sa_initial->bv_len;
2590 left.bv_len -= sub->sa_initial->bv_len;
2591 inlen -= sub->sa_initial->bv_len;
2594 if( sub->sa_final ) {
2595 if( inlen > left.bv_len ) {
2600 match = strncmp( sub->sa_final->bv_val,
2601 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
2602 sub->sa_final->bv_len );
2608 left.bv_len -= sub->sa_final->bv_len;
2609 inlen -= sub->sa_final->bv_len;
2613 for(i=0; sub->sa_any[i]; i++) {
2618 if( inlen > left.bv_len ) {
2619 /* not enough length */
2624 if( sub->sa_any[i]->bv_len == 0 ) {
2628 p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
2635 idx = p - left.bv_val;
2636 assert( idx < left.bv_len );
2638 if( idx >= left.bv_len ) {
2639 /* this shouldn't happen */
2646 if( sub->sa_any[i]->bv_len > left.bv_len ) {
2647 /* not enough left */
2652 match = strncmp( left.bv_val,
2653 sub->sa_any[i]->bv_val,
2654 sub->sa_any[i]->bv_len );
2662 left.bv_val += sub->sa_any[i]->bv_len;
2663 left.bv_len -= sub->sa_any[i]->bv_len;
2664 inlen -= sub->sa_any[i]->bv_len;
2670 return LDAP_SUCCESS;
2673 /* Index generation function */
2674 int caseExactIA5Indexer(
2679 struct berval *prefix,
2680 struct berval **values,
2681 struct berval ***keysp )
2685 struct berval **keys;
2686 HASH_CONTEXT HASHcontext;
2687 unsigned char HASHdigest[HASH_BYTES];
2688 struct berval digest;
2689 digest.bv_val = HASHdigest;
2690 digest.bv_len = sizeof(HASHdigest);
2692 for( i=0; values[i] != NULL; i++ ) {
2693 /* empty - just count them */
2696 /* we should have at least one value at this point */
2699 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
2701 slen = strlen( syntax->ssyn_oid );
2702 mlen = strlen( mr->smr_oid );
2704 for( i=0; values[i] != NULL; i++ ) {
2705 struct berval *value = values[i];
2707 HASH_Init( &HASHcontext );
2708 if( prefix != NULL && prefix->bv_len > 0 ) {
2709 HASH_Update( &HASHcontext,
2710 prefix->bv_val, prefix->bv_len );
2712 HASH_Update( &HASHcontext,
2713 syntax->ssyn_oid, slen );
2714 HASH_Update( &HASHcontext,
2715 mr->smr_oid, mlen );
2716 HASH_Update( &HASHcontext,
2717 value->bv_val, value->bv_len );
2718 HASH_Final( HASHdigest, &HASHcontext );
2720 keys[i] = ber_bvdup( &digest );
2725 return LDAP_SUCCESS;
2728 /* Index generation function */
2729 int caseExactIA5Filter(
2734 struct berval *prefix,
2736 struct berval ***keysp )
2739 struct berval **keys;
2740 HASH_CONTEXT HASHcontext;
2741 unsigned char HASHdigest[HASH_BYTES];
2742 struct berval *value;
2743 struct berval digest;
2744 digest.bv_val = HASHdigest;
2745 digest.bv_len = sizeof(HASHdigest);
2747 slen = strlen( syntax->ssyn_oid );
2748 mlen = strlen( mr->smr_oid );
2750 value = (struct berval *) assertValue;
2752 keys = ch_malloc( sizeof( struct berval * ) * 2 );
2754 HASH_Init( &HASHcontext );
2755 if( prefix != NULL && prefix->bv_len > 0 ) {
2756 HASH_Update( &HASHcontext,
2757 prefix->bv_val, prefix->bv_len );
2759 HASH_Update( &HASHcontext,
2760 syntax->ssyn_oid, slen );
2761 HASH_Update( &HASHcontext,
2762 mr->smr_oid, mlen );
2763 HASH_Update( &HASHcontext,
2764 value->bv_val, value->bv_len );
2765 HASH_Final( HASHdigest, &HASHcontext );
2767 keys[0] = ber_bvdup( &digest );
2771 return LDAP_SUCCESS;
2774 /* Substrings Index generation function */
2775 int caseExactIA5SubstringsIndexer(
2780 struct berval *prefix,
2781 struct berval **values,
2782 struct berval ***keysp )
2786 struct berval **keys;
2787 HASH_CONTEXT HASHcontext;
2788 unsigned char HASHdigest[HASH_BYTES];
2789 struct berval digest;
2790 digest.bv_val = HASHdigest;
2791 digest.bv_len = sizeof(HASHdigest);
2793 /* we should have at least one value at this point */
2794 assert( values != NULL && values[0] != NULL );
2797 for( i=0; values[i] != NULL; i++ ) {
2798 /* count number of indices to generate */
2799 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
2803 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2804 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2805 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2806 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2808 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2812 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
2813 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2814 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2818 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2819 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2820 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
2821 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
2823 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
2829 /* no keys to generate */
2831 return LDAP_SUCCESS;
2834 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2836 slen = strlen( syntax->ssyn_oid );
2837 mlen = strlen( mr->smr_oid );
2840 for( i=0; values[i] != NULL; i++ ) {
2842 struct berval *value;
2845 if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
2847 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
2848 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
2850 char pre = SLAP_INDEX_SUBSTR_PREFIX;
2851 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
2853 for( j=0; j<max; j++ ) {
2854 HASH_Init( &HASHcontext );
2855 if( prefix != NULL && prefix->bv_len > 0 ) {
2856 HASH_Update( &HASHcontext,
2857 prefix->bv_val, prefix->bv_len );
2860 HASH_Update( &HASHcontext,
2861 &pre, sizeof( pre ) );
2862 HASH_Update( &HASHcontext,
2863 syntax->ssyn_oid, slen );
2864 HASH_Update( &HASHcontext,
2865 mr->smr_oid, mlen );
2866 HASH_Update( &HASHcontext,
2868 SLAP_INDEX_SUBSTR_MAXLEN );
2869 HASH_Final( HASHdigest, &HASHcontext );
2871 keys[nkeys++] = ber_bvdup( &digest );
2875 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2876 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
2878 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
2881 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
2882 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2883 HASH_Init( &HASHcontext );
2884 if( prefix != NULL && prefix->bv_len > 0 ) {
2885 HASH_Update( &HASHcontext,
2886 prefix->bv_val, prefix->bv_len );
2888 HASH_Update( &HASHcontext,
2889 &pre, sizeof( pre ) );
2890 HASH_Update( &HASHcontext,
2891 syntax->ssyn_oid, slen );
2892 HASH_Update( &HASHcontext,
2893 mr->smr_oid, mlen );
2894 HASH_Update( &HASHcontext,
2896 HASH_Final( HASHdigest, &HASHcontext );
2898 keys[nkeys++] = ber_bvdup( &digest );
2901 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
2902 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
2903 HASH_Init( &HASHcontext );
2904 if( prefix != NULL && prefix->bv_len > 0 ) {
2905 HASH_Update( &HASHcontext,
2906 prefix->bv_val, prefix->bv_len );
2908 HASH_Update( &HASHcontext,
2909 &pre, sizeof( pre ) );
2910 HASH_Update( &HASHcontext,
2911 syntax->ssyn_oid, slen );
2912 HASH_Update( &HASHcontext,
2913 mr->smr_oid, mlen );
2914 HASH_Update( &HASHcontext,
2915 &value->bv_val[value->bv_len-j], j );
2916 HASH_Final( HASHdigest, &HASHcontext );
2918 keys[nkeys++] = ber_bvdup( &digest );
2932 return LDAP_SUCCESS;
2935 int caseExactIA5SubstringsFilter(
2940 struct berval *prefix,
2942 struct berval ***keysp )
2944 SubstringsAssertion *sa = assertValue;
2946 ber_len_t nkeys = 0;
2947 size_t slen, mlen, klen;
2948 struct berval **keys;
2949 HASH_CONTEXT HASHcontext;
2950 unsigned char HASHdigest[HASH_BYTES];
2951 struct berval *value;
2952 struct berval digest;
2954 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2955 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2960 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
2962 for( i=0; sa->sa_any[i] != NULL; i++ ) {
2963 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
2964 /* don't bother accounting for stepping */
2965 nkeys += sa->sa_any[i]->bv_len -
2966 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
2971 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
2972 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2979 return LDAP_SUCCESS;
2982 digest.bv_val = HASHdigest;
2983 digest.bv_len = sizeof(HASHdigest);
2985 slen = strlen( syntax->ssyn_oid );
2986 mlen = strlen( mr->smr_oid );
2988 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
2991 if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
2992 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
2994 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
2995 value = sa->sa_initial;
2997 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
2998 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3000 HASH_Init( &HASHcontext );
3001 if( prefix != NULL && prefix->bv_len > 0 ) {
3002 HASH_Update( &HASHcontext,
3003 prefix->bv_val, prefix->bv_len );
3005 HASH_Update( &HASHcontext,
3006 &pre, sizeof( pre ) );
3007 HASH_Update( &HASHcontext,
3008 syntax->ssyn_oid, slen );
3009 HASH_Update( &HASHcontext,
3010 mr->smr_oid, mlen );
3011 HASH_Update( &HASHcontext,
3012 value->bv_val, klen );
3013 HASH_Final( HASHdigest, &HASHcontext );
3015 keys[nkeys++] = ber_bvdup( &digest );
3018 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
3020 pre = SLAP_INDEX_SUBSTR_PREFIX;
3021 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3023 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3024 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3028 value = sa->sa_any[i];
3031 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3032 j += SLAP_INDEX_SUBSTR_STEP )
3034 HASH_Init( &HASHcontext );
3035 if( prefix != NULL && prefix->bv_len > 0 ) {
3036 HASH_Update( &HASHcontext,
3037 prefix->bv_val, prefix->bv_len );
3039 HASH_Update( &HASHcontext,
3040 &pre, sizeof( pre ) );
3041 HASH_Update( &HASHcontext,
3042 syntax->ssyn_oid, slen );
3043 HASH_Update( &HASHcontext,
3044 mr->smr_oid, mlen );
3045 HASH_Update( &HASHcontext,
3046 &value->bv_val[j], klen );
3047 HASH_Final( HASHdigest, &HASHcontext );
3049 keys[nkeys++] = ber_bvdup( &digest );
3054 if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
3055 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3057 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3058 value = sa->sa_final;
3060 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3061 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3063 HASH_Init( &HASHcontext );
3064 if( prefix != NULL && prefix->bv_len > 0 ) {
3065 HASH_Update( &HASHcontext,
3066 prefix->bv_val, prefix->bv_len );
3068 HASH_Update( &HASHcontext,
3069 &pre, sizeof( pre ) );
3070 HASH_Update( &HASHcontext,
3071 syntax->ssyn_oid, slen );
3072 HASH_Update( &HASHcontext,
3073 mr->smr_oid, mlen );
3074 HASH_Update( &HASHcontext,
3075 &value->bv_val[value->bv_len-klen], klen );
3076 HASH_Final( HASHdigest, &HASHcontext );
3078 keys[nkeys++] = ber_bvdup( &digest );
3089 return LDAP_SUCCESS;
3098 struct berval *value,
3099 void *assertedValue )
3101 int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
3103 if( match == 0 && value->bv_len ) {
3104 match = strncasecmp( value->bv_val,
3105 ((struct berval *) assertedValue)->bv_val,
3110 return LDAP_SUCCESS;
3114 caseIgnoreIA5SubstringsMatch(
3119 struct berval *value,
3120 void *assertedValue )
3123 SubstringsAssertion *sub = assertedValue;
3124 struct berval left = *value;
3128 /* Add up asserted input length */
3129 if( sub->sa_initial ) {
3130 inlen += sub->sa_initial->bv_len;
3133 for(i=0; sub->sa_any[i] != NULL; i++) {
3134 inlen += sub->sa_any[i]->bv_len;
3137 if( sub->sa_final ) {
3138 inlen += sub->sa_final->bv_len;
3141 if( sub->sa_initial ) {
3142 if( inlen > left.bv_len ) {
3147 match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
3148 sub->sa_initial->bv_len );
3154 left.bv_val += sub->sa_initial->bv_len;
3155 left.bv_len -= sub->sa_initial->bv_len;
3156 inlen -= sub->sa_initial->bv_len;
3159 if( sub->sa_final ) {
3160 if( inlen > left.bv_len ) {
3165 match = strncasecmp( sub->sa_final->bv_val,
3166 &left.bv_val[left.bv_len - sub->sa_final->bv_len],
3167 sub->sa_final->bv_len );
3173 left.bv_len -= sub->sa_final->bv_len;
3174 inlen -= sub->sa_final->bv_len;
3178 for(i=0; sub->sa_any[i]; i++) {
3183 if( inlen > left.bv_len ) {
3184 /* not enough length */
3189 if( sub->sa_any[i]->bv_len == 0 ) {
3193 p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
3200 idx = p - left.bv_val;
3201 assert( idx < left.bv_len );
3203 if( idx >= left.bv_len ) {
3204 /* this shouldn't happen */
3211 if( sub->sa_any[i]->bv_len > left.bv_len ) {
3212 /* not enough left */
3217 match = strncasecmp( left.bv_val,
3218 sub->sa_any[i]->bv_val,
3219 sub->sa_any[i]->bv_len );
3228 left.bv_val += sub->sa_any[i]->bv_len;
3229 left.bv_len -= sub->sa_any[i]->bv_len;
3230 inlen -= sub->sa_any[i]->bv_len;
3236 return LDAP_SUCCESS;
3239 /* Index generation function */
3240 int caseIgnoreIA5Indexer(
3245 struct berval *prefix,
3246 struct berval **values,
3247 struct berval ***keysp )
3251 struct berval **keys;
3252 HASH_CONTEXT HASHcontext;
3253 unsigned char HASHdigest[HASH_BYTES];
3254 struct berval digest;
3255 digest.bv_val = HASHdigest;
3256 digest.bv_len = sizeof(HASHdigest);
3258 /* we should have at least one value at this point */
3259 assert( values != NULL && values[0] != NULL );
3261 for( i=0; values[i] != NULL; i++ ) {
3262 /* just count them */
3265 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
3267 slen = strlen( syntax->ssyn_oid );
3268 mlen = strlen( mr->smr_oid );
3270 for( i=0; values[i] != NULL; i++ ) {
3271 struct berval *value = ber_bvdup( values[i] );
3272 ldap_pvt_str2upper( value->bv_val );
3274 HASH_Init( &HASHcontext );
3275 if( prefix != NULL && prefix->bv_len > 0 ) {
3276 HASH_Update( &HASHcontext,
3277 prefix->bv_val, prefix->bv_len );
3279 HASH_Update( &HASHcontext,
3280 syntax->ssyn_oid, slen );
3281 HASH_Update( &HASHcontext,
3282 mr->smr_oid, mlen );
3283 HASH_Update( &HASHcontext,
3284 value->bv_val, value->bv_len );
3285 HASH_Final( HASHdigest, &HASHcontext );
3287 ber_bvfree( value );
3289 keys[i] = ber_bvdup( &digest );
3294 return LDAP_SUCCESS;
3297 /* Index generation function */
3298 int caseIgnoreIA5Filter(
3303 struct berval *prefix,
3305 struct berval ***keysp )
3308 struct berval **keys;
3309 HASH_CONTEXT HASHcontext;
3310 unsigned char HASHdigest[HASH_BYTES];
3311 struct berval *value;
3312 struct berval digest;
3313 digest.bv_val = HASHdigest;
3314 digest.bv_len = sizeof(HASHdigest);
3316 slen = strlen( syntax->ssyn_oid );
3317 mlen = strlen( mr->smr_oid );
3319 value = ber_bvdup( (struct berval *) assertValue );
3320 ldap_pvt_str2upper( value->bv_val );
3322 keys = ch_malloc( sizeof( struct berval * ) * 2 );
3324 HASH_Init( &HASHcontext );
3325 if( prefix != NULL && prefix->bv_len > 0 ) {
3326 HASH_Update( &HASHcontext,
3327 prefix->bv_val, prefix->bv_len );
3329 HASH_Update( &HASHcontext,
3330 syntax->ssyn_oid, slen );
3331 HASH_Update( &HASHcontext,
3332 mr->smr_oid, mlen );
3333 HASH_Update( &HASHcontext,
3334 value->bv_val, value->bv_len );
3335 HASH_Final( HASHdigest, &HASHcontext );
3337 keys[0] = ber_bvdup( &digest );
3340 ber_bvfree( value );
3344 return LDAP_SUCCESS;
3347 /* Substrings Index generation function */
3348 int caseIgnoreIA5SubstringsIndexer(
3353 struct berval *prefix,
3354 struct berval **values,
3355 struct berval ***keysp )
3359 struct berval **keys;
3360 HASH_CONTEXT HASHcontext;
3361 unsigned char HASHdigest[HASH_BYTES];
3362 struct berval digest;
3363 digest.bv_val = HASHdigest;
3364 digest.bv_len = sizeof(HASHdigest);
3366 /* we should have at least one value at this point */
3367 assert( values != NULL && values[0] != NULL );
3370 for( i=0; values[i] != NULL; i++ ) {
3371 /* count number of indices to generate */
3372 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
3376 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3377 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3378 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3379 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3381 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3385 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
3386 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3387 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3391 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3392 if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3393 nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
3394 ( SLAP_INDEX_SUBSTR_MINLEN - 1);
3396 nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
3402 /* no keys to generate */
3404 return LDAP_SUCCESS;
3407 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
3409 slen = strlen( syntax->ssyn_oid );
3410 mlen = strlen( mr->smr_oid );
3413 for( i=0; values[i] != NULL; i++ ) {
3415 struct berval *value;
3417 if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
3419 value = ber_bvdup( values[i] );
3420 ldap_pvt_str2upper( value->bv_val );
3422 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
3423 ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
3425 char pre = SLAP_INDEX_SUBSTR_PREFIX;
3426 max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
3428 for( j=0; j<max; j++ ) {
3429 HASH_Init( &HASHcontext );
3430 if( prefix != NULL && prefix->bv_len > 0 ) {
3431 HASH_Update( &HASHcontext,
3432 prefix->bv_val, prefix->bv_len );
3435 HASH_Update( &HASHcontext,
3436 &pre, sizeof( pre ) );
3437 HASH_Update( &HASHcontext,
3438 syntax->ssyn_oid, slen );
3439 HASH_Update( &HASHcontext,
3440 mr->smr_oid, mlen );
3441 HASH_Update( &HASHcontext,
3443 SLAP_INDEX_SUBSTR_MAXLEN );
3444 HASH_Final( HASHdigest, &HASHcontext );
3446 keys[nkeys++] = ber_bvdup( &digest );
3450 max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3451 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3453 for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
3456 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
3457 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3458 HASH_Init( &HASHcontext );
3459 if( prefix != NULL && prefix->bv_len > 0 ) {
3460 HASH_Update( &HASHcontext,
3461 prefix->bv_val, prefix->bv_len );
3463 HASH_Update( &HASHcontext,
3464 &pre, sizeof( pre ) );
3465 HASH_Update( &HASHcontext,
3466 syntax->ssyn_oid, slen );
3467 HASH_Update( &HASHcontext,
3468 mr->smr_oid, mlen );
3469 HASH_Update( &HASHcontext,
3471 HASH_Final( HASHdigest, &HASHcontext );
3473 keys[nkeys++] = ber_bvdup( &digest );
3476 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
3477 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3478 HASH_Init( &HASHcontext );
3479 if( prefix != NULL && prefix->bv_len > 0 ) {
3480 HASH_Update( &HASHcontext,
3481 prefix->bv_val, prefix->bv_len );
3483 HASH_Update( &HASHcontext,
3484 &pre, sizeof( pre ) );
3485 HASH_Update( &HASHcontext,
3486 syntax->ssyn_oid, slen );
3487 HASH_Update( &HASHcontext,
3488 mr->smr_oid, mlen );
3489 HASH_Update( &HASHcontext,
3490 &value->bv_val[value->bv_len-j], j );
3491 HASH_Final( HASHdigest, &HASHcontext );
3493 keys[nkeys++] = ber_bvdup( &digest );
3498 ber_bvfree( value );
3509 return LDAP_SUCCESS;
3512 int caseIgnoreIA5SubstringsFilter(
3517 struct berval *prefix,
3519 struct berval ***keysp )
3521 SubstringsAssertion *sa = assertValue;
3523 ber_len_t nkeys = 0;
3524 size_t slen, mlen, klen;
3525 struct berval **keys;
3526 HASH_CONTEXT HASHcontext;
3527 unsigned char HASHdigest[HASH_BYTES];
3528 struct berval *value;
3529 struct berval digest;
3531 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3532 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3537 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3539 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3540 if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
3541 /* don't bother accounting for stepping */
3542 nkeys += sa->sa_any[i]->bv_len -
3543 ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
3548 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3549 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3556 return LDAP_SUCCESS;
3559 digest.bv_val = HASHdigest;
3560 digest.bv_len = sizeof(HASHdigest);
3562 slen = strlen( syntax->ssyn_oid );
3563 mlen = strlen( mr->smr_oid );
3565 keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
3568 if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
3569 sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3571 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
3572 value = ber_bvdup( sa->sa_initial );
3573 ldap_pvt_str2upper( value->bv_val );
3575 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3576 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3578 HASH_Init( &HASHcontext );
3579 if( prefix != NULL && prefix->bv_len > 0 ) {
3580 HASH_Update( &HASHcontext,
3581 prefix->bv_val, prefix->bv_len );
3583 HASH_Update( &HASHcontext,
3584 &pre, sizeof( pre ) );
3585 HASH_Update( &HASHcontext,
3586 syntax->ssyn_oid, slen );
3587 HASH_Update( &HASHcontext,
3588 mr->smr_oid, mlen );
3589 HASH_Update( &HASHcontext,
3590 value->bv_val, klen );
3591 HASH_Final( HASHdigest, &HASHcontext );
3593 ber_bvfree( value );
3594 keys[nkeys++] = ber_bvdup( &digest );
3597 if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
3599 pre = SLAP_INDEX_SUBSTR_PREFIX;
3600 klen = SLAP_INDEX_SUBSTR_MAXLEN;
3602 for( i=0; sa->sa_any[i] != NULL; i++ ) {
3603 if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
3607 value = ber_bvdup( sa->sa_any[i] );
3608 ldap_pvt_str2upper( value->bv_val );
3611 j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
3612 j += SLAP_INDEX_SUBSTR_STEP )
3614 HASH_Init( &HASHcontext );
3615 if( prefix != NULL && prefix->bv_len > 0 ) {
3616 HASH_Update( &HASHcontext,
3617 prefix->bv_val, prefix->bv_len );
3619 HASH_Update( &HASHcontext,
3620 &pre, sizeof( pre ) );
3621 HASH_Update( &HASHcontext,
3622 syntax->ssyn_oid, slen );
3623 HASH_Update( &HASHcontext,
3624 mr->smr_oid, mlen );
3625 HASH_Update( &HASHcontext,
3626 &value->bv_val[j], klen );
3627 HASH_Final( HASHdigest, &HASHcontext );
3629 keys[nkeys++] = ber_bvdup( &digest );
3632 ber_bvfree( value );
3636 if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
3637 sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
3639 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
3640 value = ber_bvdup( sa->sa_final );
3641 ldap_pvt_str2upper( value->bv_val );
3643 klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
3644 ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
3646 HASH_Init( &HASHcontext );
3647 if( prefix != NULL && prefix->bv_len > 0 ) {
3648 HASH_Update( &HASHcontext,
3649 prefix->bv_val, prefix->bv_len );
3651 HASH_Update( &HASHcontext,
3652 &pre, sizeof( pre ) );
3653 HASH_Update( &HASHcontext,
3654 syntax->ssyn_oid, slen );
3655 HASH_Update( &HASHcontext,
3656 mr->smr_oid, mlen );
3657 HASH_Update( &HASHcontext,
3658 &value->bv_val[value->bv_len-klen], klen );
3659 HASH_Final( HASHdigest, &HASHcontext );
3661 ber_bvfree( value );
3662 keys[nkeys++] = ber_bvdup( &digest );
3673 return LDAP_SUCCESS;
3677 numericStringValidate(
3683 for(i=0; i < in->bv_len; i++) {
3684 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
3685 return LDAP_INVALID_SYNTAX;
3689 return LDAP_SUCCESS;
3693 numericStringNormalize(
3696 struct berval **normalized )
3698 /* removal all spaces */
3699 struct berval *newval;
3702 newval = ch_malloc( sizeof( struct berval ) );
3703 newval->bv_val = ch_malloc( val->bv_len + 1 );
3709 if ( ASCII_SPACE( *p ) ) {
3710 /* Ignore whitespace */
3717 /* we should have copied no more then is in val */
3718 assert( (q - newval->bv_val) <= (p - val->bv_val) );
3720 /* null terminate */
3723 newval->bv_len = q - newval->bv_val;
3724 *normalized = newval;
3726 return LDAP_SUCCESS;
3730 objectIdentifierFirstComponentMatch(
3735 struct berval *value,
3736 void *assertedValue )
3738 int rc = LDAP_SUCCESS;
3740 struct berval *asserted = (struct berval *) assertedValue;
3744 if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
3745 return LDAP_INVALID_SYNTAX;
3748 /* trim leading white space */
3749 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
3753 /* grab next word */
3754 oid.bv_val = &value->bv_val[i];
3755 oid.bv_len = value->bv_len - i;
3756 for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
3761 /* insert attributeTypes, objectclass check here */
3762 if( OID_LEADCHAR(asserted->bv_val[0]) ) {
3763 rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
3766 char *stored = ch_malloc( oid.bv_len + 1 );
3767 AC_MEMCPY( stored, oid.bv_val, oid.bv_len );
3768 stored[oid.bv_len] = '\0';
3770 if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
3771 MatchingRule *asserted_mr = mr_find( asserted->bv_val );
3772 MatchingRule *stored_mr = mr_find( stored );
3774 if( asserted_mr == NULL ) {
3775 rc = SLAPD_COMPARE_UNDEFINED;
3777 match = asserted_mr != stored_mr;
3780 } else if ( !strcmp( syntax->ssyn_oid,
3781 SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
3783 AttributeType *asserted_at = at_find( asserted->bv_val );
3784 AttributeType *stored_at = at_find( stored );
3786 if( asserted_at == NULL ) {
3787 rc = SLAPD_COMPARE_UNDEFINED;
3789 match = asserted_at != stored_at;
3792 } else if ( !strcmp( syntax->ssyn_oid,
3793 SLAP_SYNTAX_OBJECTCLASSES_OID ) )
3795 ObjectClass *asserted_oc = oc_find( asserted->bv_val );
3796 ObjectClass *stored_oc = oc_find( stored );
3798 if( asserted_oc == NULL ) {
3799 rc = SLAPD_COMPARE_UNDEFINED;
3801 match = asserted_oc != stored_oc;
3809 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3810 "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
3811 match, value->bv_val, asserted->bv_val ));
3813 Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
3814 "%d\n\t\"%s\"\n\t\"%s\"\n",
3815 match, value->bv_val, asserted->bv_val );
3819 if( rc == LDAP_SUCCESS ) *matchp = match;
3829 struct berval *value,
3830 void *assertedValue )
3832 long lValue, lAssertedValue;
3834 /* safe to assume integers are NUL terminated? */
3835 lValue = strtoul(value->bv_val, NULL, 10);
3836 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3837 return LDAP_CONSTRAINT_VIOLATION;
3839 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3840 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3841 return LDAP_CONSTRAINT_VIOLATION;
3843 *matchp = (lValue & lAssertedValue);
3844 return LDAP_SUCCESS;
3853 struct berval *value,
3854 void *assertedValue )
3856 long lValue, lAssertedValue;
3858 /* safe to assume integers are NUL terminated? */
3859 lValue = strtoul(value->bv_val, NULL, 10);
3860 if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE )
3861 return LDAP_CONSTRAINT_VIOLATION;
3863 lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
3864 if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
3865 return LDAP_CONSTRAINT_VIOLATION;
3867 *matchp = (lValue | lAssertedValue);
3868 return LDAP_SUCCESS;
3872 #include <openssl/x509.h>
3873 #include <openssl/err.h>
3874 char digit[] = "0123456789";
3877 * Next function returns a string representation of a ASN1_INTEGER.
3878 * It works for unlimited lengths.
3881 static struct berval *
3882 asn1_integer2str(ASN1_INTEGER *a)
3887 /* We work backwards, make it fill from the end of buf */
3888 p = buf + sizeof(buf) - 1;
3891 if ( a == NULL || a->length == 0 ) {
3899 /* We want to preserve the original */
3900 copy = ch_malloc(n*sizeof(unsigned int));
3901 for (i = 0; i<n; i++) {
3902 copy[i] = a->data[i];
3906 * base indicates the index of the most significant
3907 * byte that might be nonzero. When it goes off the
3908 * end, we now there is nothing left to do.
3914 for (i = base; i<n; i++ ) {
3915 copy[i] += carry*256;
3916 carry = copy[i] % 10;
3921 * Way too large, we need to leave
3922 * room for sign if negative
3927 *--p = digit[carry];
3928 if (copy[base] == 0)
3934 if ( a->type == V_ASN1_NEG_INTEGER ) {
3938 return ber_bvstrdup(p);
3941 /* Get a DN in RFC2253 format from a X509_NAME internal struct */
3942 static struct berval *
3943 dn_openssl2ldap(X509_NAME *name)
3945 char issuer_dn[1024];
3948 bio = BIO_new(BIO_s_mem());
3951 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3952 "dn_openssl2ldap: error creating BIO_s_mem: %s\n",
3953 ERR_error_string(ERR_get_error(),NULL)));
3955 Debug( LDAP_DEBUG_ARGS, "dn_openssl2ldap: "
3956 "error creating BIO: %s\n",
3957 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3961 X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253);
3963 BIO_gets(bio, issuer_dn, 1024);
3966 return ber_bvstrdup(issuer_dn);
3970 * Given a certificate in DER format, extract the corresponding
3971 * assertion value for certificateExactMatch
3974 certificateExactConvert(
3976 struct berval ** out )
3979 unsigned char *p = in->bv_val;
3980 struct berval *serial;
3981 struct berval *issuer_dn;
3982 struct berval *bv_tmp;
3984 xcert = d2i_X509(NULL, &p, in->bv_len);
3987 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
3988 "certificateExactConvert: error parsing cert: %s\n",
3989 ERR_error_string(ERR_get_error(),NULL)));
3991 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
3992 "error parsing cert: %s\n",
3993 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
3995 return LDAP_INVALID_SYNTAX;
3998 serial = asn1_integer2str(xcert->cert_info->serialNumber);
4001 return LDAP_INVALID_SYNTAX;
4003 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
4007 return LDAP_INVALID_SYNTAX;
4009 /* Actually, dn_openssl2ldap returns in a normalized format, but
4010 it is different from our normalized format */
4012 if ( dnNormalize(NULL, bv_tmp, &issuer_dn) != LDAP_SUCCESS ) {
4016 return LDAP_INVALID_SYNTAX;
4022 *out = ch_malloc(sizeof(struct berval));
4023 (*out)->bv_len = serial->bv_len + 3 + issuer_dn->bv_len + 1;
4024 (*out)->bv_val = ch_malloc((*out)->bv_len);
4026 AC_MEMCPY(p, serial->bv_val, serial->bv_len);
4027 p += serial->bv_len;
4028 AC_MEMCPY(p, " $ ", 3);
4030 AC_MEMCPY(p, issuer_dn->bv_val, issuer_dn->bv_len);
4031 p += issuer_dn->bv_len;
4035 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
4036 "certificateExactConvert: \n %s\n",
4039 Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
4041 (*out)->bv_val, NULL, NULL );
4045 ber_bvfree(issuer_dn);
4047 return LDAP_SUCCESS;
4051 serial_and_issuer_parse(
4052 struct berval *assertion,
4053 struct berval **serial,
4054 struct berval **issuer_dn
4062 begin = assertion->bv_val;
4063 end = assertion->bv_val+assertion->bv_len-1;
4064 for (p=begin; p<=end && *p != '$'; p++)
4067 return LDAP_INVALID_SYNTAX;
4069 /* p now points at the $ sign, now use begin and end to delimit the
4071 while (ASCII_SPACE(*begin))
4074 while (ASCII_SPACE(*end))
4077 q = ch_malloc( (end-begin+1)+1 );
4078 AC_MEMCPY( q, begin, end-begin+1 );
4079 q[end-begin+1] = '\0';
4080 *serial = ber_bvstr(q);
4082 /* now extract the issuer, remember p was at the dollar sign */
4084 end = assertion->bv_val+assertion->bv_len-1;
4085 while (ASCII_SPACE(*begin))
4087 /* should we trim spaces at the end too? is it safe always? */
4089 q = ch_malloc( (end-begin+1)+1 );
4090 AC_MEMCPY( q, begin, end-begin+1 );
4091 q[end-begin+1] = '\0';
4092 *issuer_dn = ber_bvstr(dn_normalize(q));
4094 return LDAP_SUCCESS;
4098 certificateExactMatch(
4103 struct berval *value,
4104 void *assertedValue )
4107 unsigned char *p = value->bv_val;
4108 struct berval *serial;
4109 struct berval *issuer_dn;
4110 struct berval *asserted_serial;
4111 struct berval *asserted_issuer_dn;
4114 xcert = d2i_X509(NULL, &p, value->bv_len);
4117 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
4118 "certificateExactMatch: error parsing cert: %s\n",
4119 ERR_error_string(ERR_get_error(),NULL)));
4121 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
4122 "error parsing cert: %s\n",
4123 ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
4125 return LDAP_INVALID_SYNTAX;
4128 serial = asn1_integer2str(xcert->cert_info->serialNumber);
4129 issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
4133 serial_and_issuer_parse(assertedValue,
4135 &asserted_issuer_dn);
4140 slap_schema.si_syn_integer,
4141 slap_schema.si_mr_integerMatch,
4144 if ( ret == LDAP_SUCCESS ) {
4145 if ( *matchp == 0 ) {
4146 /* We need to normalize everything for dnMatch */
4150 slap_schema.si_syn_distinguishedName,
4151 slap_schema.si_mr_distinguishedNameMatch,
4153 asserted_issuer_dn);
4158 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
4159 "certificateExactMatch: %d\n %s $ %s\n %s $ %s\n",
4160 *matchp, serial->bv_val, issuer_dn->bv_val,
4161 asserted->serial->bv_val, asserted_issuer_dn->bv_val));
4163 Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
4164 "%d\n\t\"%s $ %s\"\n",
4165 *matchp, serial->bv_val, issuer_dn->bv_val );
4166 Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
4167 asserted_serial->bv_val, asserted_issuer_dn->bv_val,
4172 ber_bvfree(issuer_dn);
4173 ber_bvfree(asserted_serial);
4174 ber_bvfree(asserted_issuer_dn);
4180 * Index generation function
4181 * We just index the serials, in most scenarios the issuer DN is one of
4182 * a very small set of values.
4184 int certificateExactIndexer(
4189 struct berval *prefix,
4190 struct berval **values,
4191 struct berval ***keysp )
4194 struct berval **keys;
4197 struct berval * serial;
4199 /* we should have at least one value at this point */
4200 assert( values != NULL && values[0] != NULL );
4202 for( i=0; values[i] != NULL; i++ ) {
4203 /* empty -- just count them */
4206 keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
4208 for( i=0; values[i] != NULL; i++ ) {
4209 p = values[i]->bv_val;
4210 xcert = d2i_X509(NULL, &p, values[i]->bv_len);
4213 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
4214 "certificateExactIndexer: error parsing cert: %s\n",
4215 ERR_error_string(ERR_get_error(),NULL)));
4217 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4218 "error parsing cert: %s\n",
4219 ERR_error_string(ERR_get_error(),NULL),
4222 /* Do we leak keys on error? */
4223 return LDAP_INVALID_SYNTAX;
4226 serial = asn1_integer2str(xcert->cert_info->serialNumber);
4228 integerNormalize( slap_schema.si_syn_integer,
4233 LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
4234 "certificateExactIndexer: returning: %s\n",
4237 Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
4246 return LDAP_SUCCESS;
4249 /* Index generation function */
4250 /* We think this is always called with a value in matching rule syntax */
4251 int certificateExactFilter(
4256 struct berval *prefix,
4258 struct berval ***keysp )
4260 struct berval **keys;
4261 struct berval *asserted_serial;
4262 struct berval *asserted_issuer_dn;
4264 serial_and_issuer_parse(assertValue,
4266 &asserted_issuer_dn);
4268 keys = ch_malloc( sizeof( struct berval * ) * 2 );
4269 integerNormalize( syntax, asserted_serial, &keys[0] );
4273 ber_bvfree(asserted_serial);
4274 ber_bvfree(asserted_issuer_dn);
4275 return LDAP_SUCCESS;
4280 check_time_syntax (struct berval *val,
4284 static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
4285 static int mdays[2][12] = {
4286 /* non-leap years */
4287 { 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
4289 { 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
4292 int part, c, tzoffset, leapyear = 0 ;
4294 if( val->bv_len == 0 ) {
4295 return LDAP_INVALID_SYNTAX;
4298 p = (char *)val->bv_val;
4299 e = p + val->bv_len;
4301 /* Ignore initial whitespace */
4302 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4306 if (e - p < 13 - (2 * start)) {
4307 return LDAP_INVALID_SYNTAX;
4310 for (part = 0; part < 9; part++) {
4314 for (part = start; part < 7; part++) {
4316 if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
4323 return LDAP_INVALID_SYNTAX;
4325 if (c < 0 || c > 9) {
4326 return LDAP_INVALID_SYNTAX;
4332 return LDAP_INVALID_SYNTAX;
4334 if (c < 0 || c > 9) {
4335 return LDAP_INVALID_SYNTAX;
4340 if (part == 2 || part == 3) {
4343 if (parts[part] < 0) {
4344 return LDAP_INVALID_SYNTAX;
4346 if (parts[part] > ceiling[part]) {
4347 return LDAP_INVALID_SYNTAX;
4351 /* leapyear check for the Gregorian calendar (year>1581) */
4352 if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
4353 ((parts[0] % 4 == 0) && (parts[1] == 0)))
4358 if (parts[3] > mdays[leapyear][parts[2]]) {
4359 return LDAP_INVALID_SYNTAX;
4364 tzoffset = 0; /* UTC */
4365 } else if (c != '+' && c != '-') {
4366 return LDAP_INVALID_SYNTAX;
4370 } else /* c == '+' */ {
4375 return LDAP_INVALID_SYNTAX;
4378 for (part = 7; part < 9; part++) {
4380 if (c < 0 || c > 9) {
4381 return LDAP_INVALID_SYNTAX;
4386 if (c < 0 || c > 9) {
4387 return LDAP_INVALID_SYNTAX;
4391 if (parts[part] < 0 || parts[part] > ceiling[part]) {
4392 return LDAP_INVALID_SYNTAX;
4397 /* Ignore trailing whitespace */
4398 while ( ( p < e ) && ASCII_SPACE( *p ) ) {
4402 return LDAP_INVALID_SYNTAX;
4405 switch ( tzoffset ) {
4406 case -1: /* negativ offset to UTC, ie west of Greenwich */
4407 parts[4] += parts[7];
4408 parts[5] += parts[8];
4409 for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
4413 c = mdays[leapyear][parts[2]];
4415 if (parts[part] > c) {
4416 parts[part] -= c + 1;
4421 case 1: /* positive offset to UTC, ie east of Greenwich */
4422 parts[4] -= parts[7];
4423 parts[5] -= parts[8];
4424 for (part = 6; --part > 0; ) {
4428 /* first arg to % needs to be non negativ */
4429 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
4431 if (parts[part] < 0) {
4432 parts[part] += c + 1;
4437 case 0: /* already UTC */
4441 return LDAP_SUCCESS;
4448 struct berval **normalized )
4453 rc = check_time_syntax(val, 1, parts);
4454 if (rc != LDAP_SUCCESS) {
4459 out = ch_malloc( sizeof(struct berval) );
4461 return LBER_ERROR_MEMORY;
4464 out->bv_val = ch_malloc( 14 );
4465 if ( out->bv_val == NULL ) {
4467 return LBER_ERROR_MEMORY;
4470 sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02dZ",
4471 parts[1], parts[2] + 1, parts[3] + 1,
4472 parts[4], parts[5], parts[6] );
4476 return LDAP_SUCCESS;
4486 return check_time_syntax(in, 1, parts);
4490 generalizedTimeValidate(
4496 return check_time_syntax(in, 0, parts);
4500 generalizedTimeNormalize(
4503 struct berval **normalized )
4508 rc = check_time_syntax(val, 0, parts);
4509 if (rc != LDAP_SUCCESS) {
4514 out = ch_malloc( sizeof(struct berval) );
4516 return LBER_ERROR_MEMORY;
4519 out->bv_val = ch_malloc( 16 );
4520 if ( out->bv_val == NULL ) {
4522 return LBER_ERROR_MEMORY;
4525 sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
4526 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
4527 parts[4], parts[5], parts[6] );
4531 return LDAP_SUCCESS;
4535 nisNetgroupTripleValidate(
4537 struct berval *val )
4542 if ( val->bv_len == 0 ) {
4543 return LDAP_INVALID_SYNTAX;
4546 p = (char *)val->bv_val;
4547 e = p + val->bv_len;
4549 if ( *p != '(' /*')'*/ ) {
4550 return LDAP_INVALID_SYNTAX;
4553 for ( p++; ( p < e ) && ( *p != ')' ); p++ ) {
4557 return LDAP_INVALID_SYNTAX;
4560 } else if ( !ATTR_CHAR( *p ) ) {
4561 return LDAP_INVALID_SYNTAX;
4565 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
4566 return LDAP_INVALID_SYNTAX;
4572 return LDAP_INVALID_SYNTAX;
4575 return LDAP_SUCCESS;
4579 bootParameterValidate(
4581 struct berval *val )
4585 if ( val->bv_len == 0 ) {
4586 return LDAP_INVALID_SYNTAX;
4589 p = (char *)val->bv_val;
4590 e = p + val->bv_len;
4593 for (; ( p < e ) && ( *p != '=' ); p++ ) {
4594 if ( !ATTR_CHAR( *p ) ) {
4595 return LDAP_INVALID_SYNTAX;
4600 return LDAP_INVALID_SYNTAX;
4604 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
4605 if ( !ATTR_CHAR( *p ) ) {
4606 return LDAP_INVALID_SYNTAX;
4611 return LDAP_INVALID_SYNTAX;
4615 for ( p++; p < e; p++ ) {
4616 if ( !ATTR_CHAR( *p ) ) {
4617 return LDAP_INVALID_SYNTAX;
4621 return LDAP_SUCCESS;
4624 struct syntax_defs_rec {
4627 slap_syntax_validate_func *sd_validate;
4628 slap_syntax_transform_func *sd_normalize;
4629 slap_syntax_transform_func *sd_pretty;
4630 #ifdef SLAPD_BINARY_CONVERSION
4631 slap_syntax_transform_func *sd_ber2str;
4632 slap_syntax_transform_func *sd_str2ber;
4636 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
4637 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
4639 struct syntax_defs_rec syntax_defs[] = {
4640 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
4641 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
4642 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
4643 0, NULL, NULL, NULL},
4644 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
4645 0, NULL, NULL, NULL},
4646 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
4647 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4648 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_NOT_H_R ")",
4649 SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4650 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
4651 0, bitStringValidate, bitStringNormalize, NULL },
4652 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
4653 0, booleanValidate, NULL, NULL},
4654 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
4655 X_BINARY X_NOT_H_R ")",
4656 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4657 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
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.10 DESC 'Certificate Pair' "
4661 X_BINARY X_NOT_H_R ")",
4662 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4663 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
4664 0, countryStringValidate, IA5StringNormalize, NULL},
4665 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
4666 0, dnValidate, dnNormalize, dnPretty},
4667 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
4668 0, NULL, NULL, NULL},
4669 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
4670 0, NULL, NULL, NULL},
4671 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
4672 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4673 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
4674 0, NULL, NULL, NULL},
4675 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
4676 0, NULL, NULL, NULL},
4677 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
4678 0, NULL, NULL, NULL},
4679 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
4680 0, NULL, NULL, NULL},
4681 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
4682 0, NULL, NULL, NULL},
4683 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
4684 0, printablesStringValidate, IA5StringNormalize, NULL},
4685 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
4686 SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
4687 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
4688 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
4689 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
4690 0, NULL, NULL, NULL},
4691 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
4692 0, IA5StringValidate, IA5StringNormalize, NULL},
4693 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
4694 0, integerValidate, integerNormalize, NULL},
4695 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
4696 SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
4697 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
4698 0, NULL, NULL, NULL},
4699 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
4700 0, NULL, NULL, NULL},
4701 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
4702 0, NULL, NULL, NULL},
4703 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
4704 0, NULL, NULL, NULL},
4705 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
4706 0, NULL, NULL, NULL},
4707 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
4708 0, nameUIDValidate, nameUIDNormalize, NULL},
4709 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
4710 0, NULL, NULL, NULL},
4711 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
4712 0, numericStringValidate, numericStringNormalize, NULL},
4713 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
4714 0, NULL, NULL, NULL},
4715 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
4716 0, oidValidate, NULL, NULL},
4717 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
4718 0, IA5StringValidate, IA5StringNormalize, NULL},
4719 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
4720 0, blobValidate, NULL, NULL},
4721 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
4722 0, UTF8StringValidate, UTF8StringNormalize, NULL},
4723 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
4724 0, NULL, NULL, NULL},
4725 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
4726 0, NULL, NULL, NULL},
4727 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
4728 0, printableStringValidate, IA5StringNormalize, NULL},
4729 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
4730 X_BINARY X_NOT_H_R ")",
4731 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
4732 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
4733 0, printableStringValidate, IA5StringNormalize, NULL},
4734 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
4735 0, NULL, NULL, NULL},
4736 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
4737 0, printablesStringValidate, IA5StringNormalize, NULL},
4738 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
4739 0, utcTimeValidate, utcTimeNormalize, NULL},
4740 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
4741 0, NULL, NULL, NULL},
4742 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
4743 0, NULL, NULL, NULL},
4744 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
4745 0, NULL, NULL, NULL},
4746 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
4747 0, NULL, NULL, NULL},
4748 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
4749 0, NULL, NULL, NULL},
4751 /* RFC 2307 NIS Syntaxes */
4752 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
4753 0, nisNetgroupTripleValidate, NULL, NULL},
4754 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
4755 0, bootParameterValidate, NULL, NULL},
4759 /* These OIDs are not published yet, but will be in the next
4760 * I-D for PKIX LDAPv3 schema as have been advanced by David
4761 * Chadwick in private mail.
4763 {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
4764 0, NULL, NULL, NULL},
4767 /* OpenLDAP Experimental Syntaxes */
4768 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
4770 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
4773 /* needs updating */
4774 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
4775 SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
4777 /* OpenLDAP Void Syntax */
4778 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
4779 SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
4780 {NULL, 0, NULL, NULL, NULL}
4783 struct mrule_defs_rec {
4785 slap_mask_t mrd_usage;
4786 slap_mr_convert_func * mrd_convert;
4787 slap_mr_normalize_func * mrd_normalize;
4788 slap_mr_match_func * mrd_match;
4789 slap_mr_indexer_func * mrd_indexer;
4790 slap_mr_filter_func * mrd_filter;
4792 char * mrd_associated;
4796 * Other matching rules in X.520 that we do not use (yet):
4798 * 2.5.13.9 numericStringOrderingMatch
4799 * 2.5.13.15 integerOrderingMatch
4800 * 2.5.13.18 octetStringOrderingMatch
4801 * 2.5.13.19 octetStringSubstringsMatch
4802 * 2.5.13.25 uTCTimeMatch
4803 * 2.5.13.26 uTCTimeOrderingMatch
4804 * 2.5.13.31 directoryStringFirstComponentMatch
4805 * 2.5.13.32 wordMatch
4806 * 2.5.13.33 keywordMatch
4807 * 2.5.13.35 certificateMatch
4808 * 2.5.13.36 certificatePairExactMatch
4809 * 2.5.13.37 certificatePairMatch
4810 * 2.5.13.38 certificateListExactMatch
4811 * 2.5.13.39 certificateListMatch
4812 * 2.5.13.40 algorithmIdentifierMatch
4813 * 2.5.13.41 storedPrefixMatch
4814 * 2.5.13.42 attributeCertificateMatch
4815 * 2.5.13.43 readerAndKeyIDMatch
4816 * 2.5.13.44 attributeIntegrityMatch
4819 struct mrule_defs_rec mrule_defs[] = {
4821 * EQUALITY matching rules must be listed after associated APPROX
4822 * matching rules. So, we list all APPROX matching rules first.
4824 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
4825 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4826 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4828 directoryStringApproxMatch,
4829 directoryStringApproxIndexer,
4830 directoryStringApproxFilter,
4833 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
4834 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
4835 SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
4837 IA5StringApproxMatch,
4838 IA5StringApproxIndexer,
4839 IA5StringApproxFilter,
4843 * Other matching rules
4846 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
4847 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
4848 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4850 objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
4853 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
4854 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
4855 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4857 dnMatch, dnIndexer, dnFilter,
4860 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
4861 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4862 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4864 caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4865 directoryStringApproxMatchOID },
4867 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
4868 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4871 caseIgnoreOrderingMatch, NULL, NULL,
4874 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
4875 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4876 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4878 caseExactIgnoreSubstringsMatch,
4879 caseExactIgnoreSubstringsIndexer,
4880 caseExactIgnoreSubstringsFilter,
4883 {"( 2.5.13.5 NAME 'caseExactMatch' "
4884 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4885 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4887 caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
4888 directoryStringApproxMatchOID },
4890 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
4891 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
4894 caseExactOrderingMatch, NULL, NULL,
4897 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
4898 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4899 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4901 caseExactIgnoreSubstringsMatch,
4902 caseExactIgnoreSubstringsIndexer,
4903 caseExactIgnoreSubstringsFilter,
4906 {"( 2.5.13.8 NAME 'numericStringMatch' "
4907 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
4908 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4911 caseIgnoreIA5Indexer,
4912 caseIgnoreIA5Filter,
4915 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
4916 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4917 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4919 caseIgnoreIA5SubstringsMatch,
4920 caseIgnoreIA5SubstringsIndexer,
4921 caseIgnoreIA5SubstringsFilter,
4924 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
4925 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
4926 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4928 caseIgnoreListMatch, NULL, NULL,
4931 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
4932 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4933 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4935 caseIgnoreListSubstringsMatch, NULL, NULL,
4938 {"( 2.5.13.13 NAME 'booleanMatch' "
4939 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
4940 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4942 booleanMatch, NULL, NULL,
4945 {"( 2.5.13.14 NAME 'integerMatch' "
4946 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
4947 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4949 integerMatch, integerIndexer, integerFilter,
4952 {"( 2.5.13.16 NAME 'bitStringMatch' "
4953 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
4954 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4956 bitStringMatch, bitStringIndexer, bitStringFilter,
4959 {"( 2.5.13.17 NAME 'octetStringMatch' "
4960 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
4961 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4963 octetStringMatch, octetStringIndexer, octetStringFilter,
4966 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
4967 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
4968 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
4970 telephoneNumberMatch,
4971 telephoneNumberIndexer,
4972 telephoneNumberFilter,
4975 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
4976 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
4977 SLAP_MR_SUBSTR | SLAP_MR_EXT,
4979 telephoneNumberSubstringsMatch,
4980 telephoneNumberSubstringsIndexer,
4981 telephoneNumberSubstringsFilter,
4984 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
4985 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
4986 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4991 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
4992 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
4993 SLAP_MR_EQUALITY | SLAP_MR_EXT,
4995 uniqueMemberMatch, NULL, NULL,
4998 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
4999 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
5000 SLAP_MR_EQUALITY | SLAP_MR_EXT,
5002 protocolInformationMatch, NULL, NULL,
5005 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
5006 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5007 SLAP_MR_EQUALITY | SLAP_MR_EXT,
5009 generalizedTimeMatch, NULL, NULL,
5012 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
5013 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
5016 generalizedTimeOrderingMatch, NULL, NULL,
5019 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
5020 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5021 SLAP_MR_EQUALITY | SLAP_MR_EXT,
5023 integerFirstComponentMatch, NULL, NULL,
5026 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
5027 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
5028 SLAP_MR_EQUALITY | SLAP_MR_EXT,
5030 objectIdentifierFirstComponentMatch, NULL, NULL,
5034 {"( 2.5.13.34 NAME 'certificateExactMatch' "
5035 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
5036 SLAP_MR_EQUALITY | SLAP_MR_EXT,
5037 certificateExactConvert, NULL,
5038 certificateExactMatch,
5039 certificateExactIndexer, certificateExactFilter,
5043 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
5044 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5045 SLAP_MR_EQUALITY | SLAP_MR_EXT,
5047 caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
5048 IA5StringApproxMatchOID },
5050 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
5051 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5052 SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
5054 caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
5055 IA5StringApproxMatchOID },
5057 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
5058 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5061 caseIgnoreIA5SubstringsMatch,
5062 caseIgnoreIA5SubstringsIndexer,
5063 caseIgnoreIA5SubstringsFilter,
5066 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
5067 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
5070 caseExactIA5SubstringsMatch,
5071 caseExactIA5SubstringsIndexer,
5072 caseExactIA5SubstringsFilter,
5075 /* needs updating */
5076 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
5077 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
5080 authPasswordMatch, NULL, NULL,
5083 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
5084 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
5087 OpenLDAPaciMatch, NULL, NULL,
5090 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
5091 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5094 integerBitAndMatch, NULL, NULL,
5097 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
5098 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
5101 integerBitOrMatch, NULL, NULL,
5104 {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
5113 /* we should only be called once (from main) */
5114 assert( schema_init_done == 0 );
5116 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
5117 res = register_syntax( syntax_defs[i].sd_desc,
5118 syntax_defs[i].sd_flags,
5119 syntax_defs[i].sd_validate,
5120 syntax_defs[i].sd_normalize,
5121 syntax_defs[i].sd_pretty
5122 #ifdef SLAPD_BINARY_CONVERSION
5124 syntax_defs[i].sd_ber2str,
5125 syntax_defs[i].sd_str2ber
5130 fprintf( stderr, "schema_init: Error registering syntax %s\n",
5131 syntax_defs[i].sd_desc );
5136 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
5137 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
5139 "schema_init: Ingoring unusable matching rule %s\n",
5140 mrule_defs[i].mrd_desc );
5144 res = register_matching_rule(
5145 mrule_defs[i].mrd_desc,
5146 mrule_defs[i].mrd_usage,
5147 mrule_defs[i].mrd_convert,
5148 mrule_defs[i].mrd_normalize,
5149 mrule_defs[i].mrd_match,
5150 mrule_defs[i].mrd_indexer,
5151 mrule_defs[i].mrd_filter,
5152 mrule_defs[i].mrd_associated );
5156 "schema_init: Error registering matching rule %s\n",
5157 mrule_defs[i].mrd_desc );
5161 schema_init_done = 1;
5162 return LDAP_SUCCESS;
5166 schema_destroy( void )