+ HASH_Update( &HASHcontext,
+ &pre, sizeof( pre ) );
+ HASH_Update( &HASHcontext,
+ syntax->ssyn_oid, slen );
+ HASH_Update( &HASHcontext,
+ mr->smr_oid, mlen );
+ HASH_Update( &HASHcontext,
+ &value.bv_val[value.bv_len-klen], klen );
+ HASH_Final( HASHdigest, &HASHcontext );
+
+ free( value.bv_val );
+ ber_dupbv( &keys[nkeys++], &digest );
+ }
+
+ if( nkeys > 0 ) {
+ keys[nkeys].bv_val = NULL;
+ *keysp = keys;
+ } else {
+ ch_free( keys );
+ *keysp = NULL;
+ }
+
+ return LDAP_SUCCESS;
+}
+
+static int
+numericStringValidate(
+ Syntax *syntax,
+ struct berval *in )
+{
+ 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;
+ }
+ }
+
+ return LDAP_SUCCESS;
+}
+
+static int
+numericStringNormalize(
+ Syntax *syntax,
+ struct berval *val,
+ struct berval *normalized )
+{
+ /* removal all spaces */
+ char *p, *q;
+
+ assert( val->bv_len );
+
+ normalized->bv_val = ch_malloc( val->bv_len + 1 );
+
+ p = val->bv_val;
+ q = normalized->bv_val;
+
+ while ( *p ) {
+ if ( ASCII_SPACE( *p ) ) {
+ /* Ignore whitespace */
+ p++;
+ } else {
+ *q++ = *p++;
+ }
+ }
+
+ /* we should have copied no more then is in val */
+ assert( (q - normalized->bv_val) <= (p - val->bv_val) );
+
+ /* null terminate */
+ *q = '\0';
+
+ 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;
+}
+
+static int
+objectIdentifierFirstComponentMatch(
+ int *matchp,
+ slap_mask_t flags,
+ Syntax *syntax,
+ MatchingRule *mr,
+ struct berval *value,
+ void *assertedValue )
+{
+ int rc = LDAP_SUCCESS;
+ int match;
+ struct berval *asserted = (struct berval *) assertedValue;
+ ber_len_t i;
+ struct berval oid;
+
+ if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+
+ /* trim leading white space */
+ for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
+ /* empty */
+ }
+
+ /* 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++ ) {
+ /* empty */
+ }
+ oid.bv_len = i;
+
+ /* insert attributeTypes, objectclass check here */
+ if( OID_LEADCHAR(asserted->bv_val[0]) ) {
+ rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
+
+ } else {
+ if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
+ MatchingRule *asserted_mr = mr_bvfind( asserted );
+ MatchingRule *stored_mr = mr_bvfind( &oid );
+
+ if( asserted_mr == NULL ) {
+ rc = SLAPD_COMPARE_UNDEFINED;
+ } else {
+ match = asserted_mr != stored_mr;
+ }
+
+ } else if ( !strcmp( syntax->ssyn_oid,
+ SLAP_SYNTAX_ATTRIBUTETYPES_OID ) )
+ {
+ AttributeType *asserted_at = at_bvfind( asserted );
+ AttributeType *stored_at = at_bvfind( &oid );
+
+ if( asserted_at == NULL ) {
+ rc = SLAPD_COMPARE_UNDEFINED;
+ } else {
+ match = asserted_at != stored_at;
+ }
+
+ } else if ( !strcmp( syntax->ssyn_oid,
+ SLAP_SYNTAX_OBJECTCLASSES_OID ) )
+ {
+ ObjectClass *asserted_oc = oc_bvfind( asserted );
+ ObjectClass *stored_oc = oc_bvfind( &oid );
+
+ if( asserted_oc == NULL ) {
+ rc = SLAPD_COMPARE_UNDEFINED;
+ } else {
+ match = asserted_oc != stored_oc;
+ }
+ }
+ }
+
+#ifdef NEW_LOGGING
+ 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;
+}
+
+static int
+integerBitAndMatch(
+ int *matchp,
+ slap_mask_t flags,
+ Syntax *syntax,
+ MatchingRule *mr,
+ struct berval *value,
+ void *assertedValue )
+{
+ 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 )
+ return LDAP_CONSTRAINT_VIOLATION;
+
+ lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
+ if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
+ return LDAP_CONSTRAINT_VIOLATION;
+
+ *matchp = (lValue & lAssertedValue);
+ return LDAP_SUCCESS;
+}
+
+static int
+integerBitOrMatch(
+ int *matchp,
+ slap_mask_t flags,
+ Syntax *syntax,
+ MatchingRule *mr,
+ struct berval *value,
+ void *assertedValue )
+{
+ 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 )
+ return LDAP_CONSTRAINT_VIOLATION;
+
+ lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10);
+ if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE )
+ return LDAP_CONSTRAINT_VIOLATION;
+
+ *matchp = (lValue | lAssertedValue);
+ return LDAP_SUCCESS;
+}
+
+#ifdef HAVE_TLS
+#include <openssl/x509.h>
+#include <openssl/err.h>
+char digit[] = "0123456789";
+
+/*
+ * Next function returns a string representation of a ASN1_INTEGER.
+ * It works for unlimited lengths.
+ */
+
+static struct berval *
+asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
+{
+ char buf[256];
+ char *p;
+
+ /* We work backwards, make it fill from the end of buf */
+ p = buf + sizeof(buf) - 1;
+ *p = '\0';
+
+ if ( a == NULL || a->length == 0 ) {
+ *--p = '0';
+ } else {
+ int i;
+ int n = a->length;
+ int base = 0;
+ unsigned int *copy;
+
+ /* We want to preserve the original */
+ copy = ch_malloc(n*sizeof(unsigned int));
+ for (i = 0; i<n; i++) {
+ copy[i] = a->data[i];
+ }