X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fschema_init.c;h=d1e4068a23fcfdec981b9872af0ec0ace50c88ac;hb=fbc6a7e8ac780fd421e057c34caa9d4ecb166807;hp=b1febd47c2bf340c0cd7d0671cd9cd65c68f5d2a;hpb=9dee603fdf3a9b236808f6153a94eb24bc5cf2b0;p=openldap diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index b1febd47c2..d1e4068a23 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -1,7 +1,7 @@ /* schema_init.c - init builtin schema */ /* $OpenLDAP$ */ /* - * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ @@ -28,23 +28,121 @@ #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len) #define HASH_Final(d,c) lutil_HASHFinal(d,c) -/* recycled validatation routines */ -#define berValidate blobValidate +#define SLAP_NVALUES 1 -/* unimplemented pretters */ -#define integerPretty NULL +#ifdef SLAP_NVALUES +/* TO BE DELETED */ +#define SLAP_MR_DN_FOLD (0) + +#define SLAP_MR_ASSOCIATED(mr, with) \ + ((mr) == (with) || (mr)->smr_associated == (with)) + +#define xUTF8StringNormalize NULL +#define xIA5StringNormalize NULL +#define xtelephoneNumberNormalize NULL +#define xgeneralizedTimeNormalize NULL +#define xintegerNormalize NULL +#define xnumericStringNormalize NULL +#define xnameUIDNormalize NULL +#define xdnNormalize NULL + +/* (new) normalization routines */ +#define caseExactIA5Normalize IA5StringNormalize +#define caseIgnoreIA5Normalize IA5StringNormalize +#define caseExactNormalize UTF8StringNormalize +#define caseIgnoreNormalize UTF8StringNormalize + +#define integerFirstComponentNormalize NULL +#define objectIdentifierNormalize NULL +#define objectIdentifierFirstComponentNormalize NULL + +#define distinguishedNameNormalize dnNormalize +#define distinguishedNameMatch dnMatch +#define distinguishedNameIndexer octetStringIndexer +#define distinguishedNameFilter octetStringFilter + +#define integerOrderingMatch integerMatch +#define integerFirstComponentMatch NULL +#define integerIndexer octetStringIndexer +#define integerFilter octetStringFilter -/* recycled matching routines */ -#define bitStringMatch octetStringMatch -#define numericStringMatch caseIgnoreIA5Match -#define objectIdentifierMatch caseIgnoreIA5Match -#define telephoneNumberMatch caseIgnoreIA5Match -#define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch #define generalizedTimeMatch caseIgnoreIA5Match #define generalizedTimeOrderingMatch caseIgnoreIA5Match -#define uniqueMemberMatch dnMatch + +#define uniqueMemberMatch dnMatch /* FIXME! */ + +#define objectIdentifierMatch octetStringMatch +#define objectIdentifierIndexer octetStringIndexer +#define objectIdentifierFilter octetStringFilter + +#define OpenLDAPaciMatch NULL + +#define bitStringMatch octetStringMatch +#define bitStringIndexer octetStringIndexer +#define bitStringFilter octetStringFilter + +#define caseIgnoreMatch octetStringMatch +#define caseIgnoreOrderingMatch octetStringOrderingMatch +#define caseIgnoreIndexer octetStringIndexer +#define caseIgnoreFilter octetStringFilter + +#define caseIgnoreSubstringsMatch octetStringSubstringsMatch +#define caseIgnoreSubstringsIndexer octetStringSubstringsIndexer +#define caseIgnoreSubstringsFilter octetStringSubstringsFilter + +#define caseExactMatch octetStringMatch +#define caseExactOrderingMatch octetStringOrderingMatch +#define caseExactIndexer octetStringIndexer +#define caseExactFilter octetStringFilter + +#define caseExactSubstringsMatch octetStringSubstringsMatch +#define caseExactSubstringsIndexer octetStringSubstringsIndexer +#define caseExactSubstringsFilter octetStringSubstringsFilter + +#define caseExactIA5Match octetStringMatch +#define caseExactIA5Indexer octetStringIndexer +#define caseExactIA5Filter octetStringFilter + +#define caseExactIA5SubstringsMatch octetStringSubstringsMatch +#define caseExactIA5SubstringsIndexer octetStringSubstringsIndexer +#define caseExactIA5SubstringsFilter octetStringSubstringsFilter + +#define caseIgnoreIA5Match octetStringMatch +#define caseIgnoreIA5Indexer octetStringIndexer +#define caseIgnoreIA5Filter octetStringFilter + +#define caseIgnoreIA5SubstringsMatch caseExactIA5SubstringsMatch +#define caseIgnoreIA5SubstringsIndexer caseExactIA5SubstringsIndexer +#define caseIgnoreIA5SubstringsFilter caseExactIA5SubstringsFilter + +#define numericStringMatch octetStringMatch +#define numericStringIndexer octetStringIndexer +#define numericStringFilter octetStringFilter + +#define numericStringSubstringsMatch caseExactIA5SubstringsMatch +#define numericStringSubstringsIndexer caseExactIA5SubstringsIndexer +#define numericStringSubstringsFilter caseExactIA5SubstringsFilter + +#define telephoneNumberMatch octetStringMatch +#define telephoneNumberIndexer octetStringIndexer +#define telephoneNumberFilter octetStringFilter + +#define telephoneNumberSubstringsMatch caseExactIA5SubstringsMatch +#define telephoneNumberSubstringsIndexer caseExactIA5SubstringsIndexer +#define telephoneNumberSubstringsFilter caseExactIA5SubstringsFilter + +#define booleanIndexer octetStringIndexer +#define booleanFilter octetStringFilter +#endif + +/* validatation routines */ +#define berValidate blobValidate /* approx matching rules */ +#ifdef SLAP_NVALUES +#define directoryStringApproxMatchOID NULL +#define IA5StringApproxMatchOID NULL +#else #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4" #define directoryStringApproxMatch approxMatch #define directoryStringApproxIndexer approxIndexer @@ -53,44 +151,89 @@ #define IA5StringApproxMatch approxMatch #define IA5StringApproxIndexer approxIndexer #define IA5StringApproxFilter approxFilter +#endif -/* orderring matching rules */ -#define caseIgnoreOrderingMatch caseIgnoreMatch -#define caseExactOrderingMatch caseExactMatch +#ifndef SLAP_NVALUES -/* unimplemented matching routines */ -#define caseIgnoreListMatch NULL -#define caseIgnoreListSubstringsMatch NULL -#define protocolInformationMatch NULL -#define integerFirstComponentMatch NULL +#define xdnNormalize dnNormalize -#ifdef SLAPD_ACI_ENABLED +/* (new) normalization routines */ +#define caseExactNormalize NULL +#define caseExactIA5Normalize NULL +#define caseIgnoreNormalize NULL +#define caseIgnoreIA5Normalize NULL +#define distinguishedNameNormalize NULL +#define integerNormalize NULL +#define integerFirstComponentNormalize NULL +#define numericStringNormalize NULL +#define objectIdentifierNormalize NULL +#define objectIdentifierFirstComponentNormalize NULL +#define generalizedTimeNormalize NULL +#define uniqueMemberNormalize NULL +#define telephoneNumberNormalize NULL + + +/* matching routines */ +#define bitStringMatch octetStringMatch +#define bitStringIndexer octetStringIndexer +#define bitStringFilter octetStringFilter + +#define numericStringMatch caseIgnoreIA5Match +#define numericStringIndexer NULL +#define numericStringFilter NULL +#define numericStringSubstringsIndexer NULL +#define numericStringSubstringsFilter NULL + +#define objectIdentifierMatch octetStringMatch +#define objectIdentifierIndexer caseIgnoreIA5Indexer +#define objectIdentifierFilter caseIgnoreIA5Filter + +#define octetStringSubstringsMatch NULL #define OpenLDAPaciMatch NULL -#endif -#ifdef SLAPD_AUTHPASSWD -#define authPasswordMatch NULL -#endif -/* recycled indexing/filtering routines */ -#define dnIndexer caseExactIgnoreIndexer -#define dnFilter caseExactIgnoreFilter -#define bitStringFilter octetStringFilter -#define bitStringIndexer octetStringIndexer +#define generalizedTimeMatch caseIgnoreIA5Match +#define generalizedTimeOrderingMatch caseIgnoreIA5Match + +#define uniqueMemberMatch dnMatch +#define numericStringSubstringsMatch NULL -#define telephoneNumberIndexer caseIgnoreIA5Indexer -#define telephoneNumberFilter caseIgnoreIA5Filter +#define caseExactIndexer caseExactIgnoreIndexer +#define caseExactFilter caseExactIgnoreFilter +#define caseExactOrderingMatch caseExactMatch +#define caseExactSubstringsMatch caseExactIgnoreSubstringsMatch +#define caseExactSubstringsIndexer caseExactIgnoreSubstringsIndexer +#define caseExactSubstringsFilter caseExactIgnoreSubstringsFilter +#define caseIgnoreIndexer caseExactIgnoreIndexer +#define caseIgnoreFilter caseExactIgnoreFilter +#define caseIgnoreOrderingMatch caseIgnoreMatch +#define caseIgnoreSubstringsMatch caseExactIgnoreSubstringsMatch +#define caseIgnoreSubstringsIndexer caseExactIgnoreSubstringsIndexer +#define caseIgnoreSubstringsFilter caseExactIgnoreSubstringsFilter + +#define integerOrderingMatch integerMatch +#define integerFirstComponentMatch integerMatch + +#define distinguishedNameMatch dnMatch +#define distinguishedNameIndexer caseExactIgnoreIndexer +#define distinguishedNameFilter caseExactIgnoreFilter + +#define telephoneNumberMatch caseIgnoreIA5Match +#define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch +#define telephoneNumberIndexer caseIgnoreIA5Indexer +#define telephoneNumberFilter caseIgnoreIA5Filter #define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer #define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter -/* must match OIDs below */ -#define caseExactMatchOID "2.5.13.5" -#define caseExactSubstringsMatchOID "2.5.13.7" +#define booleanIndexer octetStringIndexer +#define booleanFilter octetStringFilter +#endif -static char *bvcasechr( struct berval *bv, int c, ber_len_t *len ) + +static char *bvcasechr( struct berval *bv, unsigned char c, ber_len_t *len ) { ber_len_t i; - int lower = TOLOWER( c ); - int upper = TOUPPER( c ); + char lower = TOLOWER( c ); + char upper = TOUPPER( c ); if( c == 0 ) return NULL; @@ -125,8 +268,30 @@ octetStringMatch( return LDAP_SUCCESS; } +static int +octetStringOrderingMatch( + int *matchp, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + void *assertedValue ) +{ + ber_len_t v_len = value->bv_len; + ber_len_t av_len = ((struct berval *) assertedValue)->bv_len; + + int match = memcmp( value->bv_val, + ((struct berval *) assertedValue)->bv_val, + (v_len < av_len ? v_len : av_len) ); + + if( match == 0 ) match = v_len - av_len; + + *matchp = match; + return LDAP_SUCCESS; +} + /* Index generation function */ -static int octetStringIndexer( +int octetStringIndexer( slap_mask_t use, slap_mask_t flags, Syntax *syntax, @@ -174,6 +339,7 @@ static int octetStringIndexer( } keys[i].bv_val = NULL; + keys[i].bv_len = 0; *keysp = keys; @@ -181,20 +347,20 @@ static int octetStringIndexer( } /* Index generation function */ -static int octetStringFilter( +int octetStringFilter( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { size_t slen, mlen; BerVarray keys; HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; - struct berval *value = (struct berval *) assertValue; + struct berval *value = (struct berval *) assertedValue; struct berval digest; digest.bv_val = HASHdigest; digest.bv_len = sizeof(HASHdigest); @@ -219,12 +385,68 @@ static int octetStringFilter( ber_dupbv( keys, &digest ); keys[1].bv_val = NULL; + keys[1].bv_len = 0; *keysp = keys; return LDAP_SUCCESS; } +static int +inValidate( + Syntax *syntax, + struct berval *in ) +{ + /* no value allowed */ + return LDAP_INVALID_SYNTAX; +} + +static int +blobValidate( + Syntax *syntax, + struct berval *in ) +{ + /* any value allowed */ + return LDAP_SUCCESS; +} + +static int +bitStringValidate( + Syntax *syntax, + struct berval *in ) +{ + ber_len_t i; + + /* very unforgiving validation, requires no normalization + * before simplistic matching + */ + if( in->bv_len < 3 ) { + return LDAP_INVALID_SYNTAX; + } + + /* + * rfc 2252 section 6.3 Bit String + * bitstring = "'" *binary-digit "'" + * binary-digit = "0" / "1" + * example: '0101111101'B + */ + + if( in->bv_val[0] != '\'' || + in->bv_val[in->bv_len-2] != '\'' || + in->bv_val[in->bv_len-1] != 'B' ) + { + return LDAP_INVALID_SYNTAX; + } + + for( i=in->bv_len-3; i>0; i-- ) { + if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) { + return LDAP_INVALID_SYNTAX; + } + } + + return LDAP_SUCCESS; +} + static int nameUIDValidate( Syntax *syntax, @@ -249,8 +471,7 @@ nameUIDValidate( break; } } - if( dn.bv_val[i] != '\'' || - dn.bv_val[i-1] != '#' ) { + if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) { ber_memfree( dn.bv_val ); return LDAP_INVALID_SYNTAX; } @@ -262,165 +483,77 @@ nameUIDValidate( rc = dnValidate( NULL, &dn ); - ber_memfree( &dn ); + ber_memfree( dn.bv_val ); return rc; } +#ifdef SLAP_NVALUES static int -nameUIDNormalize( +uniqueMemberNormalize( + slap_mask_t usage, Syntax *syntax, + MatchingRule *mr, struct berval *val, struct berval *normalized ) +#else +static int +xnameUIDNormalize( + Syntax *syntax, + struct berval *val, + struct berval *normalized ) +#endif { struct berval out; int rc; ber_dupbv( &out, val ); if( out.bv_len != 0 ) { - ber_len_t dnlen; - char *uid = NULL; - ber_len_t uidlen = 0; + struct berval uid = { 0, NULL }; - if( out.bv_val[out.bv_len-1] == '\'' ) { + if( out.bv_val[out.bv_len-1] == 'B' + && out.bv_val[out.bv_len-2] == '\'' ) + { /* assume presence of optional UID */ - uid = strrchr( out.bv_val, '#' ); + uid.bv_val = strrchr( out.bv_val, '#' ); - if( uid == NULL ) { + if( uid.bv_val == NULL ) { free( out.bv_val ); return LDAP_INVALID_SYNTAX; } - uidlen = out.bv_len - (uid - out.bv_val); + uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val); + out.bv_len -= uid.bv_len--; + /* temporarily trim the UID */ - *uid = '\0'; - out.bv_len -= uidlen; + *(uid.bv_val++) = '\0'; } -#ifdef USE_DN_NORMALIZE rc = dnNormalize2( NULL, &out, normalized ); -#else - rc = dnPretty2( NULL, &out, normalized ); -#endif if( rc != LDAP_SUCCESS ) { free( out.bv_val ); return LDAP_INVALID_SYNTAX; } - dnlen = normalized->bv_len; - - if( uidlen ) { - struct berval b2; - b2.bv_val = ch_malloc(dnlen + uidlen + 1); - AC_MEMCPY( b2.bv_val, normalized->bv_val, dnlen ); - - /* restore the separator */ - *uid = '#'; - /* shift the UID */ - AC_MEMCPY( normalized->bv_val+dnlen, uid, uidlen ); - b2.bv_len = dnlen + uidlen; - normalized->bv_val[dnlen+uidlen] = '\0'; - free(normalized->bv_val); - *normalized = b2; - } - free( out.bv_val ); - } - - return LDAP_SUCCESS; -} - -static int -inValidate( - Syntax *syntax, - struct berval *in ) -{ - /* any value allowed */ - return LDAP_OTHER; -} - -static int -blobValidate( - Syntax *syntax, - struct berval *in ) -{ - /* any value allowed */ - return LDAP_SUCCESS; -} + if( uid.bv_len ) { + normalized->bv_val = ch_realloc( normalized->bv_val, + normalized->bv_len + uid.bv_len + sizeof("#") ); -static int -bitStringValidate( - Syntax *syntax, - struct berval *in ) -{ - ber_len_t i; + /* insert the separator */ + normalized->bv_val[normalized->bv_len++] = '#'; - /* very unforgiving validation, requires no normalization - * before simplistic matching - */ - if( in->bv_len < 3 ) { - return LDAP_INVALID_SYNTAX; - } + /* append the UID */ + AC_MEMCPY( &normalized->bv_val[normalized->bv_len], + uid.bv_val, uid.bv_len ); + normalized->bv_len += uid.bv_len; - /* - * rfc 2252 section 6.3 Bit String - * bitstring = "'" *binary-digit "'" - * binary-digit = "0" / "1" - * example: '0101111101'B - */ - - if( in->bv_val[0] != '\'' || - in->bv_val[in->bv_len-2] != '\'' || - in->bv_val[in->bv_len-1] != 'B' ) - { - return LDAP_INVALID_SYNTAX; - } - - for( i=in->bv_len-3; i>0; i-- ) { - if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) { - return LDAP_INVALID_SYNTAX; + /* terminate */ + normalized->bv_val[normalized->bv_len] = '\0'; } - } - - return LDAP_SUCCESS; -} -static int -bitStringNormalize( - Syntax *syntax, - struct berval *val, - struct berval *normalized ) -{ - /* - * A normalized bitString is has no extaneous (leading) zero bits. - * That is, '00010'B is normalized to '10'B - * However, as a special case, '0'B requires no normalization. - */ - char *p; - - /* start at the first bit */ - p = &val->bv_val[1]; - - /* Find the first non-zero bit */ - while ( *p == '0' ) p++; - - if( *p == '\'' ) { - /* no non-zero bits */ - ber_str2bv( "\'0\'B", sizeof("\'0\'B") - 1, 1, normalized ); - goto done; - } - - normalized->bv_val = ch_malloc( val->bv_len + 1 ); - - normalized->bv_val[0] = '\''; - normalized->bv_len = 1; - - for( ; *p != '\0'; p++ ) { - normalized->bv_val[normalized->bv_len++] = *p; + free( out.bv_val ); } - normalized->bv_val[normalized->bv_len] = '\0'; - -done: return LDAP_SUCCESS; } @@ -467,6 +600,78 @@ booleanMatch( return LDAP_SUCCESS; } +/*------------------------------------------------------------------- +LDAP/X.500 string syntax / matching rules have a few oddities. This +comment attempts to detail how slapd(8) treats them. + +Summary: + StringSyntax X.500 LDAP Matching/Comments + DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces + PrintableString subset subset i/e + ignore insignificant spaces + PrintableString subset subset i/e + ignore insignificant spaces + NumericString subset subset ignore all spaces + IA5String ASCII ASCII i/e + ignore insignificant spaces + TeletexString T.61 T.61 i/e + ignore insignificant spaces + + TelephoneNumber subset subset i + ignore all spaces and "-" + + See draft-ietf-ldapbis-strpro for details (once published). + + +Directory String - + In X.500(93), a directory string can be either a PrintableString, + a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)). + In later versions, more CHOICEs were added. In all cases the string + must be non-empty. + + In LDAPv3, a directory string is a UTF-8 encoded UCS string. + A directory string cannot be zero length. + + For matching, there are both case ignore and exact rules. Both + also require that "insignificant" spaces be ignored. + spaces before the first non-space are ignored; + spaces after the last non-space are ignored; + spaces after a space are ignored. + Note: by these rules (and as clarified in X.520), a string of only + spaces is to be treated as if held one space, not empty (which + would be a syntax error). + +NumericString + In ASN.1, numeric string is just a string of digits and spaces + and could be empty. However, in X.500, all attribute values of + numeric string carry a non-empty constraint. For example: + + internationalISDNNumber ATTRIBUTE ::= { + WITH SYNTAX InternationalISDNNumber + EQUALITY MATCHING RULE numericStringMatch + SUBSTRINGS MATCHING RULE numericStringSubstringsMatch + ID id-at-internationalISDNNumber } + InternationalISDNNumber ::= + NumericString (SIZE(1..ub-international-isdn-number)) + + Unforunately, some assertion values are don't carry the same + constraint (but its unclear how such an assertion could ever + be true). In LDAP, there is one syntax (numericString) not two + (numericString with constraint, numericString without constraint). + This should be treated as numericString with non-empty constraint. + Note that while someone may have no ISDN number, there are no ISDN + numbers which are zero length. + + In matching, spaces are ignored. + +PrintableString + In ASN.1, Printable string is just a string of printable characters + and can be empty. In X.500, semantics much like NumericString (see + serialNumber for a like example) excepting uses insignificant space + handling instead of ignore all spaces. + +IA5String + Basically same as PrintableString. There are no examples in X.500, + but same logic applies. So we require them to be non-empty as + well. + +-------------------------------------------------------------------*/ + static int UTF8StringValidate( Syntax *syntax, @@ -476,7 +681,10 @@ UTF8StringValidate( int len; unsigned char *u = in->bv_val; - if( !in->bv_len ) return LDAP_INVALID_SYNTAX; + if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) { + /* directory strings cannot be empty */ + return LDAP_INVALID_SYNTAX; + } for( count = in->bv_len; count > 0; count-=len, u+=len ) { /* get the length indicated by the first byte */ @@ -516,13 +724,83 @@ UTF8StringValidate( if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX; } - if( count != 0 ) return LDAP_INVALID_SYNTAX; + if( count != 0 ) { + return LDAP_INVALID_SYNTAX; + } return LDAP_SUCCESS; } +#ifdef SLAP_NVALUES static int UTF8StringNormalize( + slap_mask_t use, + Syntax *syntax, + MatchingRule *mr, + struct berval *val, + struct berval *normalized ) +{ + struct berval tmp, nvalue; + int flags; + int i, wasspace; + + if( val->bv_val == NULL ) { + /* assume we're dealing with a syntax (e.g., UTF8String) + * which allows empty strings + */ + normalized->bv_len = 0; + normalized->bv_val = NULL; + return LDAP_SUCCESS; + } + + flags = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactMatch ) + ? LDAP_UTF8_NOCASEFOLD : LDAP_UTF8_CASEFOLD; + flags |= ( ( use & SLAP_MR_EQUALITY_APPROX ) == SLAP_MR_EQUALITY_APPROX ) + ? LDAP_UTF8_APPROX : 0; + + val = UTF8bvnormalize( val, &tmp, flags ); + if( val == NULL ) { + return LDAP_OTHER; + } + + /* collapse spaces (in place) */ + nvalue.bv_len = 0; + nvalue.bv_val = tmp.bv_val; + + wasspace=1; /* trim leading spaces */ + for( i=0; ibv_len ); + p = val->bv_val; /* Ignore initial whitespace */ @@ -537,8 +818,10 @@ UTF8StringNormalize( for ( ; p < val->bv_val + val->bv_len && ASCII_SPACE( p[ 0 ] ); p++ ); normalized->bv_len = val->bv_len - (p - val->bv_val); - if ( normalized->bv_len == 0 ) { - return LDAP_INVALID_SYNTAX; + + if( !normalized->bv_len ) { + ber_mem2bv( " ", 1, 1, normalized ); + return LDAP_SUCCESS; } ber_mem2bv( p, normalized->bv_len, 1, normalized ); @@ -567,11 +850,11 @@ UTF8StringNormalize( } } - assert( normalized->bv_val < p ); + assert( normalized->bv_val <= p ); assert( q+len <= p ); /* cannot start with a space */ - assert( !ASCII_SPACE(normalized->bv_val[0]) ); + assert( !ASCII_SPACE( normalized->bv_val[0] ) ); /* * If the string ended in space, backup the pointer one @@ -600,14 +883,14 @@ UTF8StringNormalize( /* Returns Unicode canonically normalized copy of a substring assertion * Skipping attribute description */ static SubstringsAssertion * -UTF8SubstringsassertionNormalize( +UTF8SubstringsAssertionNormalize( SubstringsAssertion *sa, unsigned casefold ) { SubstringsAssertion *nsa; int i; - nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) ); + nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) ); if( nsa == NULL ) { return NULL; } @@ -623,10 +906,15 @@ UTF8SubstringsassertionNormalize( for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) { /* empty */ } - nsa->sa_any = (struct berval *)ch_malloc( (i + 1) * sizeof(struct berval) ); + nsa->sa_any = (struct berval *) + SLAP_MALLOC( (i + 1) * sizeof(struct berval) ); + if( nsa->sa_any == NULL ) { + goto err; + } + for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) { UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i], - casefold ); + casefold ); if( nsa->sa_any[i].bv_val == NULL ) { goto err; } @@ -645,7 +933,7 @@ UTF8SubstringsassertionNormalize( err: if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val ); - if ( nsa->sa_any )ber_bvarray_free( nsa->sa_any ); + if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any ); if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val ); ch_free( nsa ); return NULL; @@ -682,7 +970,8 @@ approxMatch( } /* Yes, this is necessary */ - assertv = UTF8bvnormalize( ((struct berval *)assertedValue), NULL, LDAP_UTF8_APPROX ); + assertv = UTF8bvnormalize( ((struct berval *)assertedValue), + NULL, LDAP_UTF8_APPROX ); if( assertv == NULL ) { ber_bvfree( nval ); *matchp = 1; @@ -830,7 +1119,7 @@ approxFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { char *c; @@ -839,7 +1128,8 @@ approxFilter( BerVarray keys; /* Yes, this is necessary */ - val = UTF8bvnormalize( ((struct berval *)assertValue), NULL, LDAP_UTF8_APPROX ); + val = UTF8bvnormalize( ((struct berval *)assertedValue), + NULL, LDAP_UTF8_APPROX ); if( val == NULL || val->bv_val == NULL ) { keys = (struct berval *)ch_malloc( sizeof(struct berval) ); keys[0].bv_val = NULL; @@ -968,7 +1258,7 @@ approxFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { BerVarray keys; @@ -977,7 +1267,7 @@ approxFilter( keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 ); /* Yes, this is necessary */ - s = UTF8normalize( ((struct berval *)assertValue), + s = UTF8normalize( ((struct berval *)assertedValue), UTF8_NOCASEFOLD ); if( s == NULL ) { keys[0] = NULL; @@ -1003,7 +1293,9 @@ caseExactMatch( struct berval *value, void *assertedValue ) { - *matchp = UTF8bvnormcmp( value, (struct berval *) assertedValue, LDAP_UTF8_NOCASEFOLD ); + *matchp = UTF8bvnormcmp( value, + (struct berval *) assertedValue, + LDAP_UTF8_NOCASEFOLD ); return LDAP_SUCCESS; } @@ -1024,7 +1316,7 @@ caseExactIgnoreSubstringsMatch( char *nav = NULL; unsigned casefold; - casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID ) + casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch ) ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD; if ( UTF8bvnormalize( value, &left, casefold ) == NULL ) { @@ -1033,7 +1325,7 @@ caseExactIgnoreSubstringsMatch( } nav = left.bv_val; - sub = UTF8SubstringsassertionNormalize( assertedValue, casefold ); + sub = UTF8SubstringsAssertionNormalize( assertedValue, casefold ); if( sub == NULL ) { match = -1; goto done; @@ -1172,8 +1464,8 @@ static int caseExactIgnoreIndexer( BerVarray values, BerVarray *keysp ) { - int i; - unsigned casefold; + int i,j; + unsigned casefold,wasspace; size_t slen, mlen; BerVarray keys; HASH_CONTEXT HASHcontext; @@ -1194,13 +1486,37 @@ static int caseExactIgnoreIndexer( slen = syntax->ssyn_oidlen; mlen = mr->smr_oidlen; - casefold = strcmp( mr->smr_oid, caseExactMatchOID ) + casefold = ( mr != slap_schema.si_mr_caseExactMatch ) ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD; for( i=0; values[i].bv_val != NULL; i++ ) { - struct berval value; + struct berval value, nvalue; UTF8bvnormalize( &values[i], &value, casefold ); + /* collapse spaces (in place) */ + nvalue.bv_len = 0; + nvalue.bv_val = value.bv_val; + + wasspace=1; + for( j=0; jbv_len > 0 ) { HASH_Update( &HASHcontext, @@ -1211,11 +1527,10 @@ static int caseExactIgnoreIndexer( HASH_Update( &HASHcontext, mr->smr_oid, mlen ); HASH_Update( &HASHcontext, - value.bv_val, value.bv_len ); + nvalue.bv_val, nvalue.bv_len ); HASH_Final( HASHdigest, &HASHcontext ); free( value.bv_val ); - ber_dupbv( &keys[i], &digest ); } @@ -1231,7 +1546,7 @@ static int caseExactIgnoreFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { unsigned casefold; @@ -1248,10 +1563,10 @@ static int caseExactIgnoreFilter( slen = syntax->ssyn_oidlen; mlen = mr->smr_oidlen; - casefold = strcmp( mr->smr_oid, caseExactMatchOID ) + casefold = ( mr != slap_schema.si_mr_caseExactMatch ) ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD; - UTF8bvnormalize( (struct berval *) assertValue, &value, casefold ); + UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold ); /* This usually happens if filter contains bad UTF8 */ if( value.bv_val == NULL ) { keys = ch_malloc( sizeof( struct berval ) ); @@ -1282,10 +1597,16 @@ static int caseExactIgnoreFilter( *keysp = keys; return LDAP_SUCCESS; } +#endif /* Substrings Index generation function */ -static int caseExactIgnoreSubstringsIndexer( - slap_mask_t use, +static int +#ifdef SLAP_NVALUES +octetStringSubstringsIndexer +#else +caseExactIgnoreSubstringsIndexer +#endif + ( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, @@ -1293,11 +1614,13 @@ static int caseExactIgnoreSubstringsIndexer( BerVarray values, BerVarray *keysp ) { - unsigned casefold; - ber_len_t i, nkeys; + ber_len_t i, j, nkeys; size_t slen, mlen; BerVarray keys; - BerVarray nvalues; +#ifndef SLAP_NVALUES + BerVarray tvalues, nvalues; + unsigned casefold, wasspace; +#endif HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; @@ -1305,8 +1628,7 @@ static int caseExactIgnoreSubstringsIndexer( digest.bv_val = HASHdigest; digest.bv_len = sizeof(HASHdigest); - nkeys=0; - +#ifndef SLAP_NVALUES for( i=0; values[i].bv_val != NULL; i++ ) { /* empty - just count them */ } @@ -1314,15 +1636,47 @@ static int caseExactIgnoreSubstringsIndexer( /* we should have at least one value at this point */ assert( i > 0 ); - casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID ) + casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch ) ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD; + tvalues = ch_malloc( sizeof( struct berval ) * (i+1) ); nvalues = ch_malloc( sizeof( struct berval ) * (i+1) ); + for( i=0; values[i].bv_val != NULL; i++ ) { - UTF8bvnormalize( &values[i], &nvalues[i], casefold ); + UTF8bvnormalize( &values[i], &tvalues[i], casefold ); + + /* collapse spaces (in place) */ + nvalues[i].bv_len = 0; + nvalues[i].bv_val = tvalues[i].bv_val; + + wasspace=1; + for( j=0; jsmr_oid, caseExactSubstringsMatchOID ) +#ifndef SLAP_NVALUES + casefold = ( mr != slap_schema.si_mr_caseExactSubstringsMatch ) ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD; - sa = UTF8SubstringsassertionNormalize( assertValue, casefold ); + sa = UTF8SubstringsAssertionNormalize( assertedValue, casefold ); if( sa == NULL ) { *keysp = NULL; return LDAP_SUCCESS; } +#else + sa = (SubstringsAssertion *) assertedValue; +#endif if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial.bv_val != NULL && sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) @@ -1517,10 +1886,12 @@ static int caseExactIgnoreSubstringsFilter( } if( nkeys == 0 ) { +#ifndef SLAP_NVALUES if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val ); if ( sa->sa_any ) ber_bvarray_free( sa->sa_any ); if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val ); ch_free( sa ); +#endif *keysp = NULL; return LDAP_SUCCESS; } @@ -1632,13 +2003,17 @@ static int caseExactIgnoreSubstringsFilter( ch_free( keys ); *keysp = NULL; } + +#ifndef SLAP_NVALUES if ( sa->sa_final.bv_val ) free( sa->sa_final.bv_val ); if ( sa->sa_any ) ber_bvarray_free( sa->sa_any ); if ( sa->sa_initial.bv_val ) free( sa->sa_initial.bv_val ); ch_free( sa ); +#endif return LDAP_SUCCESS; } +#ifndef SLAP_NVALUES static int caseIgnoreMatch( @@ -1649,10 +2024,53 @@ caseIgnoreMatch( struct berval *value, void *assertedValue ) { - *matchp = UTF8bvnormcmp( value, (struct berval *) assertedValue, LDAP_UTF8_CASEFOLD ); + *matchp = UTF8bvnormcmp( value, + (struct berval *) assertedValue, + LDAP_UTF8_CASEFOLD ); return LDAP_SUCCESS; } +#endif +/* Remove all spaces and '-' characters */ +static int +#ifdef SLAP_NVALUES +telephoneNumberNormalize( + slap_mask_t usage, + Syntax *syntax, + MatchingRule *mr, + struct berval *val, + struct berval *normalized ) +#else +xtelephoneNumberNormalize( + Syntax *syntax, + struct berval *val, + struct berval *normalized ) +#endif +{ + char *p, *q; + + /* validator should have refused an empty string */ + assert( val->bv_len ); + + q = normalized->bv_val = ch_malloc( val->bv_len + 1 ); + + for( p = val->bv_val; *p; p++ ) { + if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) { + *q++ = *p; + } + } + *q = '\0'; + + normalized->bv_len = q - normalized->bv_val; + + if( normalized->bv_len == 0 ) { + free( normalized->bv_val ); + return LDAP_INVALID_SYNTAX; + } + + return LDAP_SUCCESS; +} + static int oidValidate( Syntax *syntax, @@ -1702,85 +2120,49 @@ integerMatch( void *assertedValue ) { char *v, *av; - int vsign=0, avsign=0; + int vsign = 1, avsign = 1; /* default sign = '+' */ struct berval *asserted; ber_len_t vlen, avlen; + int match; - - /* Start off pessimistic */ - *matchp = 1; - - /* Skip past leading spaces/zeros, and get the sign of the *value number */ + /* Skip leading space/sign/zeroes, and get the sign of the *value number */ v = value->bv_val; vlen = value->bv_len; - while( vlen ) { - if( ASCII_SPACE(*v) || ( *v == '0' )) { - /* empty -- skip spaces */ - } - else if ( *v == '+' ) { - vsign = 1; - } - else if ( *v == '-' ) { - vsign = -1; - } - else if ( ASCII_DIGIT(*v) ) { - if ( vsign == 0 ) vsign = 1; - vsign *= 2; - break; - } - v++; - vlen--; + +#ifndef SLAP_NVALUES + if( mr == slap_schema.si_mr_integerFirstComponentMatch ) { + char *tmp = memchr( v, '$', vlen ); + if( tmp ) vlen = tmp - v; + while( vlen && ASCII_SPACE( v[vlen-1] )) vlen--; + } +#endif + + for( ; vlen && ( *v < '1' || '9' < *v ); v++, vlen-- ) { /* ANSI 2.2.1 */ + if( *v == '-' ) vsign = -1; } - /* Skip past leading spaces/zeros, and get the sign of the *assertedValue - number */ + if( vlen == 0 ) vsign = 0; + + /* Do the same with the *assertedValue number */ asserted = (struct berval *) assertedValue; av = asserted->bv_val; avlen = asserted->bv_len; - while( avlen ) { - if( ASCII_SPACE(*av) || ( *av == '0' )) { - /* empty -- skip spaces */ - } - else if ( *av == '+' ) { - avsign = 1; - } - else if ( *av == '-' ) { + for( ; avlen && ( *av < '1' || '9' < *av ); av++, avlen-- ) + if( *av == '-' ) avsign = -1; - } - else if ( ASCII_DIGIT(*av) ) { - if ( avsign == 0 ) avsign = 1; - avsign *= 2; - break; - } - av++; - avlen--; - } - - /* The two ?sign vars are now one of : - -2 negative non-zero number - -1 -0 \ - 0 0 collapse these three to 0 - +1 +0 / - +2 positive non-zero number - */ - if ( abs( vsign ) == 1 ) vsign = 0; - if ( abs( avsign ) == 1 ) avsign = 0; - - if( vsign != avsign ) return LDAP_SUCCESS; + if( avlen == 0 ) + avsign = 0; - /* Check the significant digits */ - while( vlen && avlen ) { - if( *v != *av ) break; - v++; - vlen--; - av++; - avlen--; + match = vsign - avsign; + if( match == 0 ) { + match = (vlen != avlen + ? ( vlen < avlen ? -1 : 1 ) + : memcmp( v, av, vlen )); + if( vsign < 0 ) + match = -match; } - /* If all digits compared equal, the numbers are equal */ - if(( vlen == 0 ) && ( avlen == 0 )) { - *matchp = 0; - } + *matchp = match; return LDAP_SUCCESS; } @@ -1795,6 +2177,7 @@ integerValidate( if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) { if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX; + } else if( !ASCII_DIGIT(val->bv_val[0]) ) { return LDAP_INVALID_SYNTAX; } @@ -1807,10 +2190,19 @@ integerValidate( } static int +#ifdef SLAP_NVALUES integerNormalize( + slap_mask_t use, + Syntax *syntax, + MatchingRule *mr, + struct berval *val, + struct berval *normalized ) +#else +xintegerNormalize( Syntax *syntax, struct berval *val, struct berval *normalized ) +#endif { char *p; int negative=0; @@ -1846,19 +2238,20 @@ integerNormalize( if( len == 0 ) { normalized->bv_val = ch_strdup("0"); normalized->bv_len = 1; - } - else { + + } else { normalized->bv_len = len+negative; - normalized->bv_val = ch_malloc( normalized->bv_len ); - if( negative ) { - normalized->bv_val[0] = '-'; - } + normalized->bv_val = ch_malloc( normalized->bv_len + 1 ); + if( negative ) normalized->bv_val[0] = '-'; AC_MEMCPY( normalized->bv_val + negative, p, len ); + normalized->bv_val[len+negative] = '\0'; } return LDAP_SUCCESS; } +#ifndef SLAP_NVALUES + /* Index generation function */ static int integerIndexer( slap_mask_t use, @@ -1870,19 +2263,45 @@ static int integerIndexer( BerVarray *keysp ) { int i; + size_t slen, mlen; BerVarray keys; - - /* we should have at least one value at this point */ - assert( values != NULL && values[0].bv_val != NULL ); + HASH_CONTEXT HASHcontext; + unsigned char HASHdigest[HASH_BYTES]; + struct berval digest; + digest.bv_val = HASHdigest; + digest.bv_len = sizeof(HASHdigest); for( i=0; values[i].bv_val != NULL; i++ ) { - /* empty -- just count them */ + /* empty - just count them */ } + /* we should have at least one value at this point */ + assert( i > 0 ); + keys = ch_malloc( sizeof( struct berval ) * (i+1) ); + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; + for( i=0; values[i].bv_val != NULL; i++ ) { - integerNormalize( syntax, &values[i], &keys[i] ); + struct berval norm; + xintegerNormalize( syntax, &values[i], &norm ); + + HASH_Init( &HASHcontext ); + if( prefix != NULL && prefix->bv_len > 0 ) { + HASH_Update( &HASHcontext, + prefix->bv_val, prefix->bv_len ); + } + HASH_Update( &HASHcontext, + syntax->ssyn_oid, slen ); + HASH_Update( &HASHcontext, + mr->smr_oid, mlen ); + HASH_Update( &HASHcontext, + norm.bv_val, norm.bv_len ); + HASH_Final( HASHdigest, &HASHcontext ); + + ber_dupbv( &keys[i], &digest ); + ch_free( norm.bv_val ); } keys[i].bv_val = NULL; @@ -1897,19 +2316,47 @@ static int integerFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { + size_t slen, mlen; BerVarray keys; + HASH_CONTEXT HASHcontext; + unsigned char HASHdigest[HASH_BYTES]; + struct berval norm; + struct berval digest; + digest.bv_val = HASHdigest; + digest.bv_len = sizeof(HASHdigest); + + slen = syntax->ssyn_oidlen; + mlen = mr->smr_oidlen; + + xintegerNormalize( syntax, assertedValue, &norm ); keys = ch_malloc( sizeof( struct berval ) * 2 ); - integerNormalize( syntax, assertValue, &keys[0] ); + + HASH_Init( &HASHcontext ); + if( prefix != NULL && prefix->bv_len > 0 ) { + HASH_Update( &HASHcontext, + prefix->bv_val, prefix->bv_len ); + } + HASH_Update( &HASHcontext, + syntax->ssyn_oid, slen ); + HASH_Update( &HASHcontext, + mr->smr_oid, mlen ); + HASH_Update( &HASHcontext, + norm.bv_val, norm.bv_len ); + HASH_Final( HASHdigest, &HASHcontext ); + + ber_dupbv( &keys[0], &digest ); keys[1].bv_val = NULL; - *keysp = keys; + ch_free( norm.bv_val ); + *keysp = keys; return LDAP_SUCCESS; } +#endif static int countryStringValidate( @@ -1935,6 +2382,8 @@ printableStringValidate( { ber_len_t i; + if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX; + for(i=0; i < val->bv_len; i++) { if( !SLAP_PRINTABLE(val->bv_val[i]) ) { return LDAP_INVALID_SYNTAX; @@ -1949,14 +2398,30 @@ printablesStringValidate( Syntax *syntax, struct berval *val ) { - ber_len_t i; + ber_len_t i, len; - for(i=0; i < val->bv_len; i++) { - if( !SLAP_PRINTABLES(val->bv_val[i]) ) { + if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX; + + for(i=0,len=0; i < val->bv_len; i++) { + int c = val->bv_val[i]; + + if( c == '$' ) { + if( len == 0 ) { + return LDAP_INVALID_SYNTAX; + } + len = 0; + + } else if ( SLAP_PRINTABLE(c) ) { + len++; + } else { return LDAP_INVALID_SYNTAX; } } + if( len == 0 ) { + return LDAP_INVALID_SYNTAX; + } + return LDAP_SUCCESS; } @@ -1967,6 +2432,8 @@ IA5StringValidate( { ber_len_t i; + if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX; + for(i=0; i < val->bv_len; i++) { if( !LDAP_ASCII(val->bv_val[i]) ) { return LDAP_INVALID_SYNTAX; @@ -1977,12 +2444,26 @@ IA5StringValidate( } static int +#ifdef SLAP_NVALUES IA5StringNormalize( + slap_mask_t use, + Syntax *syntax, + MatchingRule *mr, + struct berval *val, + struct berval *normalized ) +#else +xIA5StringNormalize( Syntax *syntax, struct berval *val, struct berval *normalized ) +#endif { char *p, *q; +#ifdef SLAP_NVALUES + int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match); +#endif + + assert( val->bv_len ); p = val->bv_val; @@ -2002,6 +2483,13 @@ IA5StringNormalize( while ( ASCII_SPACE( *p ) ) { p++; } + +#ifdef SLAP_NVALUES + } else if ( casefold ) { + /* Most IA5 rules require casefolding */ + *q++ = TOLOWER(*p++); +#endif + } else { *q++ = *p++; } @@ -2025,9 +2513,18 @@ IA5StringNormalize( normalized->bv_len = q - normalized->bv_val; + if( normalized->bv_len == 0 ) { + normalized->bv_val = ch_realloc( normalized->bv_val, 2 ); + normalized->bv_val[0] = ' '; + normalized->bv_val[1] = '\0'; + normalized->bv_len = 1; + } + return LDAP_SUCCESS; } +#ifndef SLAP_NVALUES + static int caseExactIA5Match( int *matchp, @@ -2050,7 +2547,12 @@ caseExactIA5Match( } static int -caseExactIA5SubstringsMatch( +caseExactIA5SubstringsMatch +#else +static int +octetStringSubstringsMatch +#endif +( int *matchp, slap_mask_t flags, Syntax *syntax, @@ -2083,7 +2585,7 @@ caseExactIA5SubstringsMatch( goto done; } - match = strncmp( sub->sa_initial.bv_val, left.bv_val, + match = memcmp( sub->sa_initial.bv_val, left.bv_val, sub->sa_initial.bv_len ); if( match != 0 ) { @@ -2101,7 +2603,7 @@ caseExactIA5SubstringsMatch( goto done; } - match = strncmp( sub->sa_final.bv_val, + match = memcmp( sub->sa_final.bv_val, &left.bv_val[left.bv_len - sub->sa_final.bv_len], sub->sa_final.bv_len ); @@ -2129,7 +2631,7 @@ retry: continue; } - p = strchr( left.bv_val, *sub->sa_any[i].bv_val ); + p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len ); if( p == NULL ) { match = 1; @@ -2152,7 +2654,7 @@ retry: goto done; } - match = strncmp( left.bv_val, + match = memcmp( left.bv_val, sub->sa_any[i].bv_val, sub->sa_any[i].bv_len ); @@ -2173,6 +2675,8 @@ done: return LDAP_SUCCESS; } +#ifndef SLAP_NVALUES + /* Index generation function */ static int caseExactIA5Indexer( slap_mask_t use, @@ -2235,7 +2739,7 @@ static int caseExactIA5Filter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { size_t slen, mlen; @@ -2250,7 +2754,7 @@ static int caseExactIA5Filter( slen = syntax->ssyn_oidlen; mlen = mr->smr_oidlen; - value = (struct berval *) assertValue; + value = (struct berval *) assertedValue; keys = ch_malloc( sizeof( struct berval ) * 2 ); @@ -2441,10 +2945,10 @@ static int caseExactIA5SubstringsFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { - SubstringsAssertion *sa = assertValue; + SubstringsAssertion *sa = assertedValue; char pre; ber_len_t nkeys = 0; size_t slen, mlen, klen; @@ -2748,6 +3252,7 @@ static int caseIgnoreIA5Indexer( BerVarray *keysp ) { int i; + int rc = LDAP_SUCCESS; size_t slen, mlen; BerVarray keys; HASH_CONTEXT HASHcontext; @@ -2770,8 +3275,24 @@ static int caseIgnoreIA5Indexer( for( i=0; values[i].bv_val != NULL; i++ ) { struct berval value; - ber_dupbv( &value, &values[i] ); - ldap_pvt_str2upper( value.bv_val ); + + if( mr->smr_normalize ) { + rc = (mr->smr_normalize)( use, syntax, mr, &values[i], &value ); + if( rc != LDAP_SUCCESS ) { + break; + } +#ifndef SLAP_NVALUES + } else if ( mr->smr_syntax->ssyn_normalize ) { + rc = (mr->smr_syntax->ssyn_normalize)( syntax, &values[i], &value ); + if( rc != LDAP_SUCCESS ) { + break; + } +#endif + } else { + ber_dupbv( &value, &values[i] ); + } + + ldap_pvt_str2lower( value.bv_val ); HASH_Init( &HASHcontext ); if( prefix != NULL && prefix->bv_len > 0 ) { @@ -2792,8 +3313,12 @@ static int caseIgnoreIA5Indexer( } keys[i].bv_val = NULL; + if( rc != LDAP_SUCCESS ) { + ber_bvarray_free( keys ); + keys = NULL; + } *keysp = keys; - return LDAP_SUCCESS; + return rc; } /* Index generation function */ @@ -2803,7 +3328,7 @@ static int caseIgnoreIA5Filter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { size_t slen, mlen; @@ -2818,8 +3343,8 @@ static int caseIgnoreIA5Filter( slen = syntax->ssyn_oidlen; mlen = mr->smr_oidlen; - ber_dupbv( &value, (struct berval *) assertValue ); - ldap_pvt_str2upper( value.bv_val ); + ber_dupbv( &value, (struct berval *) assertedValue ); + ldap_pvt_str2lower( value.bv_val ); keys = ch_malloc( sizeof( struct berval ) * 2 ); @@ -2919,7 +3444,7 @@ static int caseIgnoreIA5SubstringsIndexer( if( values[i].bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue; ber_dupbv( &value, &values[i] ); - ldap_pvt_str2upper( value.bv_val ); + ldap_pvt_str2lower( value.bv_val ); if( ( flags & SLAP_INDEX_SUBSTR_ANY ) && ( value.bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) ) @@ -3017,10 +3542,10 @@ static int caseIgnoreIA5SubstringsFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { - SubstringsAssertion *sa = assertValue; + SubstringsAssertion *sa = assertedValue; char pre; ber_len_t nkeys = 0; size_t slen, mlen, klen; @@ -3072,7 +3597,7 @@ static int caseIgnoreIA5SubstringsFilter( { pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX; ber_dupbv( &value, &sa->sa_initial ); - ldap_pvt_str2upper( value.bv_val ); + ldap_pvt_str2lower( value.bv_val ); klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len; @@ -3107,7 +3632,7 @@ static int caseIgnoreIA5SubstringsFilter( } ber_dupbv( &value, &sa->sa_any[i] ); - ldap_pvt_str2upper( value.bv_val ); + ldap_pvt_str2lower( value.bv_val ); for(j=0; j <= value.bv_len - SLAP_INDEX_SUBSTR_MAXLEN; @@ -3140,7 +3665,7 @@ static int caseIgnoreIA5SubstringsFilter( { pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX; ber_dupbv( &value, &sa->sa_final ); - ldap_pvt_str2upper( value.bv_val ); + ldap_pvt_str2lower( value.bv_val ); klen = SLAP_INDEX_SUBSTR_MAXLEN < value.bv_len ? SLAP_INDEX_SUBSTR_MAXLEN : value.bv_len; @@ -3175,6 +3700,8 @@ static int caseIgnoreIA5SubstringsFilter( return LDAP_SUCCESS; } +#endif + static int numericStringValidate( Syntax *syntax, @@ -3182,6 +3709,8 @@ numericStringValidate( { ber_len_t i; + if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX; + for(i=0; i < in->bv_len; i++) { if( !SLAP_NUMERIC(in->bv_val[i]) ) { return LDAP_INVALID_SYNTAX; @@ -3192,14 +3721,25 @@ numericStringValidate( } static int +#ifdef SLAP_NVALUES numericStringNormalize( + slap_mask_t usage, + Syntax *syntax, + MatchingRule *mr, + struct berval *val, + struct berval *normalized ) +#else +xnumericStringNormalize( Syntax *syntax, struct berval *val, struct berval *normalized ) +#endif { /* removal all spaces */ char *p, *q; + assert( val->bv_len ); + normalized->bv_val = ch_malloc( val->bv_len + 1 ); p = val->bv_val; @@ -3222,9 +3762,17 @@ numericStringNormalize( normalized->bv_len = q - normalized->bv_val; + if( normalized->bv_len == 0 ) { + normalized->bv_val = ch_realloc( normalized->bv_val, 2 ); + normalized->bv_val[0] = ' '; + normalized->bv_val[1] = '\0'; + normalized->bv_len = 1; + } + return LDAP_SUCCESS; } +#ifndef SLAP_NVALUES static int objectIdentifierFirstComponentMatch( int *matchp, @@ -3237,7 +3785,7 @@ objectIdentifierFirstComponentMatch( int rc = LDAP_SUCCESS; int match; struct berval *asserted = (struct berval *) assertedValue; - ber_len_t i; + ber_len_t i, j; struct berval oid; if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) { @@ -3251,8 +3799,8 @@ objectIdentifierFirstComponentMatch( /* grab next word */ oid.bv_val = &value->bv_val[i]; - oid.bv_len = value->bv_len - i; - for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) { + j = value->bv_len - i; + for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) { /* empty */ } oid.bv_len = i; @@ -3299,20 +3847,21 @@ objectIdentifierFirstComponentMatch( } #ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n", - match, value->bv_val, asserted->bv_val )); + LDAP_LOG( CONFIG, ENTRY, + "objectIdentifierFirstComponentMatch: %d\n %s\n %s\n", + match, value->bv_val, asserted->bv_val ); #else Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch " "%d\n\t\"%s\"\n\t\"%s\"\n", match, value->bv_val, asserted->bv_val ); #endif - if( rc == LDAP_SUCCESS ) *matchp = match; return rc; } +#endif + static int integerBitAndMatch( int *matchp, @@ -3325,15 +3874,19 @@ integerBitAndMatch( long lValue, lAssertedValue; /* safe to assume integers are NUL terminated? */ - lValue = strtoul(value->bv_val, NULL, 10); - if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) + lValue = strtol(value->bv_val, NULL, 10); + if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) { return LDAP_CONSTRAINT_VIOLATION; + } lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10); - if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE ) + if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) + && errno == ERANGE ) + { return LDAP_CONSTRAINT_VIOLATION; + } - *matchp = (lValue & lAssertedValue); + *matchp = (lValue & lAssertedValue) ? 0 : 1; return LDAP_SUCCESS; } @@ -3349,22 +3902,27 @@ integerBitOrMatch( long lValue, lAssertedValue; /* safe to assume integers are NUL terminated? */ - lValue = strtoul(value->bv_val, NULL, 10); - if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) + lValue = strtol(value->bv_val, NULL, 10); + if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) { return LDAP_CONSTRAINT_VIOLATION; + } lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10); - if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE ) + if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) + && errno == ERANGE ) + { return LDAP_CONSTRAINT_VIOLATION; + } - *matchp = (lValue | lAssertedValue); + *matchp = (lValue | lAssertedValue) ? 0 : -1; return LDAP_SUCCESS; } +#ifndef SLAP_NVALUES + #ifdef HAVE_TLS #include #include -char digit[] = "0123456789"; /* * Next function returns a string representation of a ASN1_INTEGER. @@ -3372,10 +3930,11 @@ char digit[] = "0123456789"; */ static struct berval * -asn1_integer2str(ASN1_INTEGER *a) +asn1_integer2str(ASN1_INTEGER *a, struct berval *bv) { char buf[256]; char *p; + static char digit[] = "0123456789"; /* We work backwards, make it fill from the end of buf */ p = buf + sizeof(buf) - 1; @@ -3418,8 +3977,8 @@ asn1_integer2str(ASN1_INTEGER *a) return NULL; } *--p = digit[carry]; - if (copy[base] == 0) - base++; + + if (copy[base] == 0) base++; } free(copy); } @@ -3428,35 +3987,7 @@ asn1_integer2str(ASN1_INTEGER *a) *--p = '-'; } - return ber_bvstrdup(p); -} - -/* Get a DN in RFC2253 format from a X509_NAME internal struct */ -static struct berval * -dn_openssl2ldap(X509_NAME *name) -{ - char issuer_dn[1024]; - BIO *bio; - - bio = BIO_new(BIO_s_mem()); - if ( !bio ) { -#ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "dn_openssl2ldap: error creating BIO_s_mem: %s\n", - ERR_error_string(ERR_get_error(),NULL))); -#else - Debug( LDAP_DEBUG_ARGS, "dn_openssl2ldap: " - "error creating BIO: %s\n", - ERR_error_string(ERR_get_error(),NULL), NULL, NULL ); -#endif - return NULL; - } - X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253); - - BIO_gets(bio, issuer_dn, 1024); - - BIO_free(bio); - return ber_bvstrdup(issuer_dn); + return ber_str2bv( p, 0, 1, bv ); } /* @@ -3470,16 +4001,15 @@ certificateExactConvert( { X509 *xcert; unsigned char *p = in->bv_val; - struct berval *serial; - struct berval *issuer_dn; - struct berval *bv_tmp; + struct berval serial; + struct berval issuer_dn; xcert = d2i_X509(NULL, &p, in->bv_len); if ( !xcert ) { #ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "certificateExactConvert: error parsing cert: %s\n", - ERR_error_string(ERR_get_error(),NULL))); + LDAP_LOG( CONFIG, ENTRY, + "certificateExactConvert: error parsing cert: %s\n", + ERR_error_string(ERR_get_error(),NULL), 0, 0 ); #else Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: " "error parsing cert: %s\n", @@ -3488,53 +4018,42 @@ certificateExactConvert( return LDAP_INVALID_SYNTAX; } - serial = asn1_integer2str(xcert->cert_info->serialNumber); - if ( !serial ) { - X509_free(xcert); - return LDAP_INVALID_SYNTAX; - } - issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert)); - if ( !issuer_dn ) { + if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) { X509_free(xcert); - ber_bvfree(serial); return LDAP_INVALID_SYNTAX; } - /* Actually, dn_openssl2ldap returns in a normalized format, but - it is different from our normalized format */ - bv_tmp = issuer_dn; - if ( dnNormalize(NULL, bv_tmp, &issuer_dn) != LDAP_SUCCESS ) { + if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn ) + != LDAP_SUCCESS ) + { X509_free(xcert); - ber_bvfree(serial); - ber_bvfree(bv_tmp); + ber_memfree(serial.bv_val); return LDAP_INVALID_SYNTAX; } - ber_bvfree(bv_tmp); X509_free(xcert); - out->bv_len = serial->bv_len + issuer_dn->bv_len + sizeof(" $ "); + out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ "); out->bv_val = ch_malloc(out->bv_len); p = out->bv_val; - AC_MEMCPY(p, serial->bv_val, serial->bv_len); - p += serial->bv_len; + AC_MEMCPY(p, serial.bv_val, serial.bv_len); + p += serial.bv_len; AC_MEMCPY(p, " $ ", sizeof(" $ ")-1); p += 3; - AC_MEMCPY(p, issuer_dn->bv_val, issuer_dn->bv_len); - p += issuer_dn->bv_len; + AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len); + p += issuer_dn.bv_len; *p++ = '\0'; #ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "certificateExactConvert: \n %s\n", - out->bv_val)); + LDAP_LOG( CONFIG, ARGS, + "certificateExactConvert: \n %s\n", out->bv_val, 0, 0 ); #else Debug( LDAP_DEBUG_ARGS, "certificateExactConvert " "\n\t\"%s\"\n", out->bv_val, NULL, NULL ); #endif - ber_bvfree(serial); - ber_bvfree(issuer_dn); + ber_memfree(serial.bv_val); + ber_memfree(issuer_dn.bv_val); return LDAP_SUCCESS; } @@ -3542,8 +4061,8 @@ certificateExactConvert( static int serial_and_issuer_parse( struct berval *assertion, - struct berval **serial, - struct berval **issuer_dn + struct berval *serial, + struct berval *issuer_dn ) { char *begin; @@ -3553,33 +4072,36 @@ serial_and_issuer_parse( begin = assertion->bv_val; end = assertion->bv_val+assertion->bv_len-1; - for (p=begin; p<=end && *p != '$'; p++) - ; - if ( p > end ) - return LDAP_INVALID_SYNTAX; + for (p=begin; p<=end && *p != '$'; p++) /* empty */ ; + if ( p > end ) return LDAP_INVALID_SYNTAX; - /* p now points at the $ sign, now use begin and end to delimit the - serial number */ - while (ASCII_SPACE(*begin)) - begin++; + /* p now points at the $ sign, now use + * begin and end to delimit the serial number + */ + while (ASCII_SPACE(*begin)) begin++; end = p-1; - while (ASCII_SPACE(*end)) - end--; + while (ASCII_SPACE(*end)) end--; + + if( end <= begin ) return LDAP_INVALID_SYNTAX; bv.bv_len = end-begin+1; bv.bv_val = begin; - *serial = ber_dupbv(NULL, &bv); + ber_dupbv(serial, &bv); /* now extract the issuer, remember p was at the dollar sign */ begin = p+1; end = assertion->bv_val+assertion->bv_len-1; - while (ASCII_SPACE(*begin)) - begin++; - /* should we trim spaces at the end too? is it safe always? */ + while (ASCII_SPACE(*begin)) begin++; + /* should we trim spaces at the end too? is it safe always? no, no */ - bv.bv_len = end-begin+1; - bv.bv_val = begin; - dnNormalize( NULL, &bv, issuer_dn ); + if( end <= begin ) return LDAP_INVALID_SYNTAX; + + if ( issuer_dn ) { + bv.bv_len = end-begin+1; + bv.bv_val = begin; + + dnNormalize2( NULL, &bv, issuer_dn ); + } return LDAP_SUCCESS; } @@ -3595,18 +4117,18 @@ certificateExactMatch( { X509 *xcert; unsigned char *p = value->bv_val; - struct berval *serial; - struct berval *issuer_dn; - struct berval *asserted_serial; - struct berval *asserted_issuer_dn; + struct berval serial; + struct berval issuer_dn; + struct berval asserted_serial; + struct berval asserted_issuer_dn; int ret; xcert = d2i_X509(NULL, &p, value->bv_len); if ( !xcert ) { #ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "certificateExactMatch: error parsing cert: %s\n", - ERR_error_string(ERR_get_error(),NULL))); + LDAP_LOG( CONFIG, ENTRY, + "certificateExactMatch: error parsing cert: %s\n", + ERR_error_string(ERR_get_error(),NULL), 0, 0 ); #else Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: " "error parsing cert: %s\n", @@ -3615,22 +4137,21 @@ certificateExactMatch( return LDAP_INVALID_SYNTAX; } - serial = asn1_integer2str(xcert->cert_info->serialNumber); - issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert)); + asn1_integer2str(xcert->cert_info->serialNumber, &serial); + dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn); X509_free(xcert); serial_and_issuer_parse(assertedValue, - &asserted_serial, - &asserted_issuer_dn); + &asserted_serial, &asserted_issuer_dn); ret = integerMatch( matchp, flags, slap_schema.si_syn_integer, slap_schema.si_mr_integerMatch, - serial, - asserted_serial); + &serial, + &asserted_serial); if ( ret == LDAP_SUCCESS ) { if ( *matchp == 0 ) { /* We need to normalize everything for dnMatch */ @@ -3639,29 +4160,31 @@ certificateExactMatch( flags, slap_schema.si_syn_distinguishedName, slap_schema.si_mr_distinguishedNameMatch, - issuer_dn, - asserted_issuer_dn); + &issuer_dn, + &asserted_issuer_dn); } } #ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "certificateExactMatch: %d\n %s $ %s\n %s $ %s\n", - *matchp, serial->bv_val, issuer_dn->bv_val, - asserted->serial->bv_val, asserted_issuer_dn->bv_val)); + LDAP_LOG( CONFIG, ARGS, "certificateExactMatch " + "%d\n\t\"%s $ %s\"\n", + *matchp, serial.bv_val, issuer_dn.bv_val ); + LDAP_LOG( CONFIG, ARGS, "\t\"%s $ %s\"\n", + asserted_serial.bv_val, asserted_issuer_dn.bv_val, + 0 ); #else Debug( LDAP_DEBUG_ARGS, "certificateExactMatch " "%d\n\t\"%s $ %s\"\n", - *matchp, serial->bv_val, issuer_dn->bv_val ); + *matchp, serial.bv_val, issuer_dn.bv_val ); Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n", - asserted_serial->bv_val, asserted_issuer_dn->bv_val, + asserted_serial.bv_val, asserted_issuer_dn.bv_val, NULL ); #endif - ber_bvfree(serial); - ber_bvfree(issuer_dn); - ber_bvfree(asserted_serial); - ber_bvfree(asserted_issuer_dn); + ber_memfree(serial.bv_val); + ber_memfree(issuer_dn.bv_val); + ber_memfree(asserted_serial.bv_val); + ber_memfree(asserted_issuer_dn.bv_val); return ret; } @@ -3684,7 +4207,7 @@ static int certificateExactIndexer( BerVarray keys; X509 *xcert; unsigned char *p; - struct berval * serial; + struct berval serial; /* we should have at least one value at this point */ assert( values != NULL && values[0].bv_val != NULL ); @@ -3700,9 +4223,9 @@ static int certificateExactIndexer( xcert = d2i_X509(NULL, &p, values[i].bv_len); if ( !xcert ) { #ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "certificateExactIndexer: error parsing cert: %s\n", - ERR_error_string(ERR_get_error(),NULL))); + LDAP_LOG( CONFIG, ENTRY, + "certificateExactIndexer: error parsing cert: %s\n", + ERR_error_string(ERR_get_error(),NULL), 0, 0); #else Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: " "error parsing cert: %s\n", @@ -3713,16 +4236,14 @@ static int certificateExactIndexer( return LDAP_INVALID_SYNTAX; } - serial = asn1_integer2str(xcert->cert_info->serialNumber); + asn1_integer2str(xcert->cert_info->serialNumber, &serial); X509_free(xcert); - integerNormalize( slap_schema.si_syn_integer, - serial, - &keys[i] ); - ber_bvfree(serial); + xintegerNormalize( slap_schema.si_syn_integer, + &serial, &keys[i] ); + ber_memfree(serial.bv_val); #ifdef NEW_LOGGING - LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY, - "certificateExactIndexer: returning: %s\n", - keys[i].bv_val)); + LDAP_LOG( CONFIG, ENTRY, + "certificateExactIndexer: returning: %s\n", keys[i].bv_val, 0, 0); #else Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: " "returning: %s\n", @@ -3744,27 +4265,26 @@ static int certificateExactFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { BerVarray keys; - struct berval *asserted_serial; - struct berval *asserted_issuer_dn; + struct berval asserted_serial; + int ret; - serial_and_issuer_parse(assertValue, - &asserted_serial, - &asserted_issuer_dn); + ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL ); + if( ret != LDAP_SUCCESS ) return ret; keys = ch_malloc( sizeof( struct berval ) * 2 ); - integerNormalize( syntax, asserted_serial, &keys[0] ); + xintegerNormalize( syntax, &asserted_serial, &keys[0] ); keys[1].bv_val = NULL; *keysp = keys; - ber_bvfree(asserted_serial); - ber_bvfree(asserted_issuer_dn); + ber_memfree(asserted_serial.bv_val); return LDAP_SUCCESS; } #endif +#endif static int check_time_syntax (struct berval *val, @@ -3931,8 +4451,9 @@ check_time_syntax (struct berval *val, return LDAP_SUCCESS; } +#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX static int -utcTimeNormalize( +xutcTimeNormalize( Syntax *syntax, struct berval *val, struct berval *normalized ) @@ -3956,7 +4477,9 @@ utcTimeNormalize( return LDAP_SUCCESS; } +#endif +#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX static int utcTimeValidate( Syntax *syntax, @@ -3966,6 +4489,7 @@ utcTimeValidate( return check_time_syntax(in, 1, parts); } +#endif static int generalizedTimeValidate( @@ -3978,10 +4502,19 @@ generalizedTimeValidate( } static int +#ifdef SLAP_NVALUES generalizedTimeNormalize( + slap_mask_t usage, + Syntax *syntax, + MatchingRule *mr, + struct berval *val, + struct berval *normalized ) +#else +xgeneralizedTimeNormalize( Syntax *syntax, struct berval *val, struct berval *normalized ) +#endif { int parts[9], rc; @@ -4029,7 +4562,7 @@ nisNetgroupTripleValidate( return LDAP_INVALID_SYNTAX; } - } else if ( !ATTR_CHAR( *p ) ) { + } else if ( !AD_CHAR( *p ) ) { return LDAP_INVALID_SYNTAX; } } @@ -4063,7 +4596,7 @@ bootParameterValidate( /* key */ for (; ( p < e ) && ( *p != '=' ); p++ ) { - if ( !ATTR_CHAR( *p ) ) { + if ( !AD_CHAR( *p ) ) { return LDAP_INVALID_SYNTAX; } } @@ -4074,7 +4607,7 @@ bootParameterValidate( /* server */ for ( p++; ( p < e ) && ( *p != ':' ); p++ ) { - if ( !ATTR_CHAR( *p ) ) { + if ( !AD_CHAR( *p ) ) { return LDAP_INVALID_SYNTAX; } } @@ -4085,7 +4618,7 @@ bootParameterValidate( /* path */ for ( p++; p < e; p++ ) { - if ( !ATTR_CHAR( *p ) ) { + if ( !SLAP_PRINTABLE( *p ) ) { return LDAP_INVALID_SYNTAX; } } @@ -4093,19 +4626,10 @@ bootParameterValidate( return LDAP_SUCCESS; } -static struct syntax_defs_rec { - char *sd_desc; #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' " #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' " - int sd_flags; - slap_syntax_validate_func *sd_validate; - slap_syntax_transform_func *sd_normalize; - slap_syntax_transform_func *sd_pretty; -#ifdef SLAPD_BINARY_CONVERSION - slap_syntax_transform_func *sd_ber2str; - slap_syntax_transform_func *sd_str2ber; -#endif -} syntax_defs[] = { + +static slap_syntax_defs_rec syntax_defs[] = { {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")", SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL}, @@ -4120,7 +4644,7 @@ static struct syntax_defs_rec { X_NOT_H_R ")", SLAP_SYNTAX_BER, berValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )", - 0, bitStringValidate, bitStringNormalize, NULL }, + 0, bitStringValidate, NULL, NULL }, {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )", 0, booleanValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' " @@ -4133,15 +4657,15 @@ static struct syntax_defs_rec { X_BINARY X_NOT_H_R ")", SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )", - 0, countryStringValidate, IA5StringNormalize, NULL}, + 0, countryStringValidate, xIA5StringNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )", - 0, dnValidate, dnNormalize2, dnPretty2}, + 0, dnValidate, xdnNormalize, dnPretty2}, {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )", - 0, UTF8StringValidate, UTF8StringNormalize, NULL}, + 0, UTF8StringValidate, xUTF8StringNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )", @@ -4153,17 +4677,17 @@ static struct syntax_defs_rec { {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )", - 0, printablesStringValidate, IA5StringNormalize, NULL}, + 0, printablesStringValidate, xtelephoneNumberNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")", SLAP_SYNTAX_BLOB, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )", - 0, generalizedTimeValidate, generalizedTimeNormalize, NULL}, + 0, generalizedTimeValidate, xgeneralizedTimeNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )", - 0, IA5StringValidate, IA5StringNormalize, NULL}, + 0, IA5StringValidate, xIA5StringNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )", - 0, integerValidate, integerNormalize, NULL}, + 0, integerValidate, xintegerNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")", SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )", @@ -4177,27 +4701,27 @@ static struct syntax_defs_rec { {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )", - 0, nameUIDValidate, nameUIDNormalize, NULL}, + 0, nameUIDValidate, xnameUIDNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )", - 0, numericStringValidate, numericStringNormalize, NULL}, + 0, numericStringValidate, xnumericStringNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )", 0, oidValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )", - 0, IA5StringValidate, IA5StringNormalize, NULL}, + 0, IA5StringValidate, xIA5StringNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )", 0, blobValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )", - 0, UTF8StringValidate, UTF8StringNormalize, NULL}, + 0, UTF8StringValidate, xUTF8StringNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )", - 0, printableStringValidate, IA5StringNormalize, NULL}, + 0, printableStringValidate, xIA5StringNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' " X_BINARY X_NOT_H_R ")", SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL}, @@ -4205,13 +4729,15 @@ static struct syntax_defs_rec { X_BINARY X_NOT_H_R ")", SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )", - 0, printableStringValidate, IA5StringNormalize, NULL}, + 0, printableStringValidate, xtelephoneNumberNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )", - 0, printablesStringValidate, IA5StringNormalize, NULL}, + 0, printablesStringValidate, xIA5StringNormalize, NULL}, +#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )", - 0, utcTimeValidate, utcTimeNormalize, NULL}, + 0, utcTimeValidate, xutcTimeNormalize, NULL}, +#endif {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )", @@ -4236,7 +4762,7 @@ static struct syntax_defs_rec { * Chadwick in private mail. */ {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )", - 0, NULL, NULL, NULL}, + 0, UTF8StringValidate, NULL, NULL}, #endif /* OpenLDAP Experimental Syntaxes */ @@ -4259,13 +4785,37 @@ static struct syntax_defs_rec { {NULL, 0, NULL, NULL, NULL} }; +#ifdef HAVE_TLS +char *certificateExactMatchSyntaxes[] = { + "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */, + NULL +}; +#endif +char *directoryStringSyntaxes[] = { + "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */, + NULL +}; +char *integerFirstComponentMatchSyntaxes[] = { + "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */, + "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */, + NULL +}; +char *objectIdentifierFirstComponentMatchSyntaxes[] = { + "1.3.6.1.4.1.1466.115.121.1.38" /* OID */, + "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */, + "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */, + "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */, + "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */, + "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */, + "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */, + "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */, + NULL +}; + /* * Other matching rules in X.520 that we do not use (yet): * * 2.5.13.9 numericStringOrderingMatch - * 2.5.13.15 integerOrderingMatch - * 2.5.13.18 octetStringOrderingMatch - * 2.5.13.19 octetStringSubstringsMatch * 2.5.13.25 uTCTimeMatch * 2.5.13.26 uTCTimeOrderingMatch * 2.5.13.31 directoryStringFirstComponentMatch @@ -4282,38 +4832,26 @@ static struct syntax_defs_rec { * 2.5.13.43 readerAndKeyIDMatch * 2.5.13.44 attributeIntegrityMatch */ -static struct mrule_defs_rec { - char * mrd_desc; - slap_mask_t mrd_usage; - slap_mr_convert_func * mrd_convert; - slap_mr_normalize_func * mrd_normalize; - slap_mr_match_func * mrd_match; - slap_mr_indexer_func * mrd_indexer; - slap_mr_filter_func * mrd_filter; - - char * mrd_associated; -} mrule_defs[] = { +static slap_mrule_defs_rec mrule_defs[] = { /* * EQUALITY matching rules must be listed after associated APPROX * matching rules. So, we list all APPROX matching rules first. */ +#ifndef SLAP_NVALUES {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, - NULL, NULL, - directoryStringApproxMatch, - directoryStringApproxIndexer, - directoryStringApproxFilter, + SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL, + NULL, NULL, directoryStringApproxMatch, + directoryStringApproxIndexer, directoryStringApproxFilter, NULL}, {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, - NULL, NULL, - IA5StringApproxMatch, - IA5StringApproxIndexer, - IA5StringApproxFilter, + SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL, + NULL, NULL, IA5StringApproxMatch, + IA5StringApproxIndexer, IA5StringApproxFilter, NULL}, +#endif /* * Other matching rules @@ -4321,238 +4859,260 @@ static struct mrule_defs_rec { {"( 2.5.13.0 NAME 'objectIdentifierMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, NULL, - objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, + NULL, + objectIdentifierNormalize, objectIdentifierMatch, + objectIdentifierIndexer, objectIdentifierFilter, NULL}, {"( 2.5.13.1 NAME 'distinguishedNameMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, NULL, - dnMatch, dnIndexer, dnFilter, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, + NULL, + distinguishedNameNormalize, distinguishedNameMatch, + distinguishedNameIndexer, distinguishedNameFilter, NULL}, {"( 2.5.13.2 NAME 'caseIgnoreMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, - NULL, NULL, - caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter, + directoryStringSyntaxes, + NULL, + caseIgnoreNormalize, caseIgnoreMatch, + caseIgnoreIndexer, caseIgnoreFilter, directoryStringApproxMatchOID }, {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - SLAP_MR_ORDERING, - NULL, NULL, - caseIgnoreOrderingMatch, NULL, NULL, - NULL}, + SLAP_MR_ORDERING, directoryStringSyntaxes, + NULL, caseIgnoreNormalize, caseIgnoreOrderingMatch, + NULL, NULL, NULL}, {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - SLAP_MR_SUBSTR | SLAP_MR_EXT, + SLAP_MR_SUBSTR, NULL, NULL, NULL, - caseExactIgnoreSubstringsMatch, - caseExactIgnoreSubstringsIndexer, - caseExactIgnoreSubstringsFilter, + caseIgnoreSubstringsMatch, + caseIgnoreSubstringsIndexer, caseIgnoreSubstringsFilter, NULL}, {"( 2.5.13.5 NAME 'caseExactMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, NULL, - caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter, + SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes, + NULL, + caseExactNormalize, caseExactMatch, + caseExactIndexer, caseExactFilter, directoryStringApproxMatchOID }, {"( 2.5.13.6 NAME 'caseExactOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - SLAP_MR_ORDERING, - NULL, NULL, - caseExactOrderingMatch, NULL, NULL, - NULL}, + SLAP_MR_ORDERING, directoryStringSyntaxes, + NULL, caseExactNormalize, caseExactOrderingMatch, + NULL, NULL, NULL}, {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - SLAP_MR_SUBSTR | SLAP_MR_EXT, - NULL, NULL, - caseExactIgnoreSubstringsMatch, - caseExactIgnoreSubstringsIndexer, - caseExactIgnoreSubstringsFilter, + SLAP_MR_SUBSTR, directoryStringSyntaxes, + NULL, + NULL, caseExactSubstringsMatch, + caseExactSubstringsIndexer, caseExactSubstringsFilter, NULL}, {"( 2.5.13.8 NAME 'numericStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, - NULL, NULL, - caseIgnoreIA5Match, - caseIgnoreIA5Indexer, - caseIgnoreIA5Filter, + SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL, + NULL, + numericStringNormalize, numericStringMatch, + numericStringIndexer, numericStringFilter, NULL}, {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - SLAP_MR_SUBSTR | SLAP_MR_EXT, - NULL, NULL, - caseIgnoreIA5SubstringsMatch, - caseIgnoreIA5SubstringsIndexer, - caseIgnoreIA5SubstringsFilter, + SLAP_MR_SUBSTR, NULL, + NULL, + NULL, numericStringSubstringsMatch, + numericStringSubstringsIndexer, numericStringSubstringsFilter, NULL}, {"( 2.5.13.11 NAME 'caseIgnoreListMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, - NULL, NULL, - caseIgnoreListMatch, NULL, NULL, - NULL}, + SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL, + NULL, NULL, NULL, NULL, NULL, NULL}, {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - SLAP_MR_SUBSTR | SLAP_MR_EXT, - NULL, NULL, - caseIgnoreListSubstringsMatch, NULL, NULL, - NULL}, + SLAP_MR_SUBSTR, NULL, + NULL, NULL, NULL, NULL, NULL, NULL}, {"( 2.5.13.13 NAME 'booleanMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, NULL, - booleanMatch, NULL, NULL, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, + NULL, + NULL, booleanMatch, + booleanIndexer, booleanFilter, NULL}, {"( 2.5.13.14 NAME 'integerMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, NULL, - integerMatch, integerIndexer, integerFilter, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, + NULL, + integerNormalize, integerMatch, + integerIndexer, integerFilter, + NULL}, + + {"( 2.5.13.15 NAME 'integerOrderingMatch' " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", + SLAP_MR_ORDERING, NULL, NULL, + integerNormalize, integerOrderingMatch, + integerIndexer, integerFilter, NULL}, {"( 2.5.13.16 NAME 'bitStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, NULL, - bitStringMatch, bitStringIndexer, bitStringFilter, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, + NULL, + NULL, bitStringMatch, + bitStringIndexer, bitStringFilter, NULL}, {"( 2.5.13.17 NAME 'octetStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, octetStringMatch, octetStringIndexer, octetStringFilter, NULL}, + {"( 2.5.13.18 NAME 'octetStringOrderingMatch' " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", + SLAP_MR_ORDERING, NULL, + NULL, NULL, + octetStringOrderingMatch, NULL, NULL, + NULL}, + + {"( 2.5.13.19 NAME 'octetStringSubstringsMatch' " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", + SLAP_MR_SUBSTR, NULL, + NULL, NULL, + octetStringSubstringsMatch, NULL, NULL, + NULL}, + {"( 2.5.13.20 NAME 'telephoneNumberMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, - NULL, NULL, - telephoneNumberMatch, - telephoneNumberIndexer, - telephoneNumberFilter, + SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL, + NULL, + telephoneNumberNormalize, telephoneNumberMatch, + telephoneNumberIndexer, telephoneNumberFilter, NULL}, {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - SLAP_MR_SUBSTR | SLAP_MR_EXT, - NULL, NULL, - telephoneNumberSubstringsMatch, - telephoneNumberSubstringsIndexer, - telephoneNumberSubstringsFilter, + SLAP_MR_SUBSTR, NULL, + NULL, NULL, telephoneNumberSubstringsMatch, + telephoneNumberSubstringsIndexer, telephoneNumberSubstringsFilter, NULL}, {"( 2.5.13.22 NAME 'presentationAddressMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, {"( 2.5.13.23 NAME 'uniqueMemberMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, + NULL, + uniqueMemberNormalize, uniqueMemberMatch, NULL, NULL, - uniqueMemberMatch, NULL, NULL, NULL}, {"( 2.5.13.24 NAME 'protocolInformationMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, NULL, - protocolInformationMatch, NULL, NULL, - NULL}, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, + NULL, NULL, NULL, NULL, NULL, NULL}, {"( 2.5.13.27 NAME 'generalizedTimeMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, + NULL, + generalizedTimeNormalize, generalizedTimeMatch, NULL, NULL, - generalizedTimeMatch, NULL, NULL, NULL}, {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", - SLAP_MR_ORDERING, + SLAP_MR_ORDERING, NULL, + NULL, + generalizedTimeNormalize, generalizedTimeOrderingMatch, NULL, NULL, - generalizedTimeOrderingMatch, NULL, NULL, NULL}, {"( 2.5.13.29 NAME 'integerFirstComponentMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes, + NULL, + integerFirstComponentNormalize, integerMatch, NULL, NULL, - integerFirstComponentMatch, NULL, NULL, NULL}, {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, + objectIdentifierFirstComponentMatchSyntaxes, + NULL, + objectIdentifierFirstComponentNormalize, objectIdentifierMatch, NULL, NULL, - objectIdentifierFirstComponentMatch, NULL, NULL, NULL}, +#ifndef SLAP_NVALUES #ifdef HAVE_TLS {"( 2.5.13.34 NAME 'certificateExactMatch' " "SYNTAX 1.2.826.0.1.3344810.7.1 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes, certificateExactConvert, NULL, certificateExactMatch, certificateExactIndexer, certificateExactFilter, NULL}, +#endif #endif {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, NULL, - caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, + NULL, + caseExactIA5Normalize, caseExactIA5Match, + caseExactIA5Indexer, caseExactIA5Filter, IA5StringApproxMatchOID }, {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, - NULL, NULL, - caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter, + SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL, + NULL, + NULL, caseIgnoreIA5Match, + caseIgnoreIA5Indexer, caseIgnoreIA5Filter, IA5StringApproxMatchOID }, {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - SLAP_MR_SUBSTR, - NULL, NULL, - caseIgnoreIA5SubstringsMatch, - caseIgnoreIA5SubstringsIndexer, - caseIgnoreIA5SubstringsFilter, + SLAP_MR_SUBSTR, NULL, + NULL, + NULL, caseIgnoreIA5SubstringsMatch, + caseIgnoreIA5SubstringsIndexer, caseIgnoreIA5SubstringsFilter, NULL}, {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - SLAP_MR_SUBSTR, - NULL, NULL, - caseExactIA5SubstringsMatch, - caseExactIA5SubstringsIndexer, - caseExactIA5SubstringsFilter, + SLAP_MR_SUBSTR, NULL, + NULL, + NULL, caseExactIA5SubstringsMatch, + caseExactIA5SubstringsIndexer, caseExactIA5SubstringsFilter, NULL}, #ifdef SLAPD_AUTHPASSWD /* needs updating */ {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", - SLAP_MR_EQUALITY, + SLAP_MR_EQUALITY, NULL, NULL, NULL, authPasswordMatch, NULL, NULL, NULL}, @@ -4561,7 +5121,7 @@ static struct mrule_defs_rec { #ifdef SLAPD_ACI_ENABLED {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' " "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )", - SLAP_MR_EQUALITY, + SLAP_MR_EQUALITY, NULL, NULL, NULL, OpenLDAPaciMatch, NULL, NULL, NULL}, @@ -4569,42 +5129,34 @@ static struct mrule_defs_rec { {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - SLAP_MR_EXT, - NULL, NULL, - integerBitAndMatch, NULL, NULL, + SLAP_MR_EXT, NULL, + NULL, + NULL, integerBitAndMatch, NULL, NULL, NULL}, {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - SLAP_MR_EXT, - NULL, NULL, - integerBitOrMatch, NULL, NULL, + SLAP_MR_EXT, NULL, + NULL, + NULL, integerBitOrMatch, NULL, NULL, NULL}, - {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL} + {NULL, SLAP_MR_NONE, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL } }; int slap_schema_init( void ) { int res; - int i; + int i = 0; /* we should only be called once (from main) */ assert( schema_init_done == 0 ); for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) { - res = register_syntax( syntax_defs[i].sd_desc, - syntax_defs[i].sd_flags, - syntax_defs[i].sd_validate, - syntax_defs[i].sd_normalize, - syntax_defs[i].sd_pretty -#ifdef SLAPD_BINARY_CONVERSION - , - syntax_defs[i].sd_ber2str, - syntax_defs[i].sd_str2ber -#endif - ); + res = register_syntax( &syntax_defs[i] ); if ( res ) { fprintf( stderr, "slap_schema_init: Error registering syntax %s\n", @@ -4614,22 +5166,16 @@ slap_schema_init( void ) } for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) { - if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) { + if( mrule_defs[i].mrd_usage == SLAP_MR_NONE && + mrule_defs[i].mrd_compat_syntaxes == NULL ) + { fprintf( stderr, - "slap_schema_init: Ingoring unusable matching rule %s\n", + "slap_schema_init: Ignoring unusable matching rule %s\n", mrule_defs[i].mrd_desc ); continue; } - res = register_matching_rule( - mrule_defs[i].mrd_desc, - mrule_defs[i].mrd_usage, - mrule_defs[i].mrd_convert, - mrule_defs[i].mrd_normalize, - mrule_defs[i].mrd_match, - mrule_defs[i].mrd_indexer, - mrule_defs[i].mrd_filter, - mrule_defs[i].mrd_associated ); + res = register_matching_rule( &mrule_defs[i] ); if ( res ) { fprintf( stderr, @@ -4647,9 +5193,11 @@ slap_schema_init( void ) void schema_destroy( void ) { + int i; oidm_destroy(); oc_destroy(); at_destroy(); mr_destroy(); + mru_destroy(); syn_destroy(); }