2000-01-30 03:43:19 +08:00
|
|
|
/* schema_init.c - init builtin schema */
|
|
|
|
/* $OpenLDAP$ */
|
|
|
|
/*
|
2000-05-13 10:47:56 +08:00
|
|
|
* Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
|
2000-01-30 03:43:19 +08:00
|
|
|
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "portable.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2001-09-07 10:08:32 +08:00
|
|
|
#include <limits.h>
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
#include <ac/ctype.h>
|
2001-09-02 01:10:43 +08:00
|
|
|
#include <ac/errno.h>
|
2000-01-30 03:43:19 +08:00
|
|
|
#include <ac/string.h>
|
|
|
|
#include <ac/socket.h>
|
|
|
|
|
|
|
|
#include "slap.h"
|
|
|
|
#include "ldap_pvt.h"
|
2000-06-05 06:59:38 +08:00
|
|
|
|
2001-07-22 07:13:04 +08:00
|
|
|
#include "ldap_utf8.h"
|
|
|
|
|
2000-09-23 06:19:46 +08:00
|
|
|
#include "lutil_hash.h"
|
|
|
|
#define HASH_BYTES LUTIL_HASH_BYTES
|
|
|
|
#define HASH_CONTEXT lutil_HASH_CTX
|
|
|
|
#define HASH_Init(c) lutil_HASHInit(c)
|
|
|
|
#define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
|
|
|
|
#define HASH_Final(d,c) lutil_HASHFinal(d,c)
|
2000-09-23 04:47:46 +08:00
|
|
|
|
2000-06-20 11:55:40 +08:00
|
|
|
/* recycled validatation routines */
|
2000-06-21 01:05:15 +08:00
|
|
|
#define berValidate blobValidate
|
2000-06-21 09:12:29 +08:00
|
|
|
|
|
|
|
/* unimplemented pretters */
|
2001-12-06 11:24:31 +08:00
|
|
|
#define integerPretty NULL
|
2001-12-05 04:22:26 +08:00
|
|
|
#ifndef USE_LDAP_DN_PARSING
|
2001-12-06 11:24:31 +08:00
|
|
|
# define dnPretty NULL
|
|
|
|
#else
|
|
|
|
# define SLAP_LDAPDN_PRETTY 0x1
|
2001-12-05 04:22:26 +08:00
|
|
|
#endif /* !USE_LDAP_DN_PARSING */
|
2000-06-20 11:55:40 +08:00
|
|
|
|
|
|
|
/* recycled matching routines */
|
2000-09-12 08:32:08 +08:00
|
|
|
#define bitStringMatch octetStringMatch
|
2001-01-18 05:02:11 +08:00
|
|
|
#define numericStringMatch caseIgnoreIA5Match
|
|
|
|
#define objectIdentifierMatch caseIgnoreIA5Match
|
|
|
|
#define telephoneNumberMatch caseIgnoreIA5Match
|
2000-09-08 07:46:07 +08:00
|
|
|
#define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch
|
2001-01-18 05:02:11 +08:00
|
|
|
#define generalizedTimeMatch caseIgnoreIA5Match
|
|
|
|
#define generalizedTimeOrderingMatch caseIgnoreIA5Match
|
2000-09-06 06:07:08 +08:00
|
|
|
#define uniqueMemberMatch dnMatch
|
2000-06-20 11:55:40 +08:00
|
|
|
|
2000-07-25 05:29:30 +08:00
|
|
|
/* approx matching rules */
|
|
|
|
#define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
|
2001-01-18 00:35:53 +08:00
|
|
|
#define directoryStringApproxMatch approxMatch
|
|
|
|
#define directoryStringApproxIndexer approxIndexer
|
|
|
|
#define directoryStringApproxFilter approxFilter
|
2000-07-25 05:29:30 +08:00
|
|
|
#define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
|
2001-01-18 00:35:53 +08:00
|
|
|
#define IA5StringApproxMatch approxMatch
|
2000-10-25 04:25:37 +08:00
|
|
|
#define IA5StringApproxIndexer approxIndexer
|
2001-01-18 00:35:53 +08:00
|
|
|
#define IA5StringApproxFilter approxFilter
|
2000-07-25 05:29:30 +08:00
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
/* orderring matching rules */
|
|
|
|
#define caseIgnoreOrderingMatch caseIgnoreMatch
|
|
|
|
#define caseExactOrderingMatch caseExactMatch
|
|
|
|
|
2000-06-20 11:55:40 +08:00
|
|
|
/* unimplemented matching routines */
|
2000-06-21 01:05:15 +08:00
|
|
|
#define caseIgnoreListMatch NULL
|
|
|
|
#define caseIgnoreListSubstringsMatch NULL
|
|
|
|
#define protocolInformationMatch NULL
|
|
|
|
#define integerFirstComponentMatch NULL
|
|
|
|
|
|
|
|
#define OpenLDAPaciMatch NULL
|
|
|
|
#define authPasswordMatch NULL
|
2000-06-20 11:55:40 +08:00
|
|
|
|
|
|
|
/* recycled indexing/filtering routines */
|
2001-07-28 06:54:43 +08:00
|
|
|
#define dnIndexer caseExactIgnoreIndexer
|
|
|
|
#define dnFilter caseExactIgnoreFilter
|
2001-11-17 02:10:37 +08:00
|
|
|
#define bitStringFilter octetStringFilter
|
|
|
|
#define bitStringIndexer octetStringIndexer
|
2000-06-21 01:05:15 +08:00
|
|
|
|
2001-05-03 08:59:47 +08:00
|
|
|
#define telephoneNumberIndexer caseIgnoreIA5Indexer
|
|
|
|
#define telephoneNumberFilter caseIgnoreIA5Filter
|
|
|
|
#define telephoneNumberSubstringsIndexer caseIgnoreIA5SubstringsIndexer
|
|
|
|
#define telephoneNumberSubstringsFilter caseIgnoreIA5SubstringsFilter
|
|
|
|
|
2001-07-28 06:54:43 +08:00
|
|
|
/* must match OIDs below */
|
|
|
|
#define caseExactMatchOID "2.5.13.5"
|
|
|
|
#define caseExactSubstringsMatchOID "2.5.13.7"
|
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
static char *strcasechr( const char *str, int c )
|
|
|
|
{
|
|
|
|
char *lower = strchr( str, TOLOWER(c) );
|
|
|
|
char *upper = strchr( str, TOUPPER(c) );
|
2000-06-20 11:55:40 +08:00
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
if( lower && upper ) {
|
|
|
|
return lower < upper ? lower : upper;
|
|
|
|
} else if ( lower ) {
|
|
|
|
return lower;
|
|
|
|
} else {
|
|
|
|
return upper;
|
|
|
|
}
|
|
|
|
}
|
2000-07-25 05:29:30 +08:00
|
|
|
|
2000-06-05 06:59:38 +08:00
|
|
|
static int
|
|
|
|
octetStringMatch(
|
|
|
|
int *matchp,
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t flags,
|
2000-06-05 06:59:38 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
|
|
|
|
|
|
|
|
if( match == 0 ) {
|
|
|
|
match = memcmp( value->bv_val,
|
|
|
|
((struct berval *) assertedValue)->bv_val,
|
|
|
|
value->bv_len );
|
|
|
|
}
|
|
|
|
|
|
|
|
*matchp = match;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Index generation function */
|
|
|
|
int octetStringIndexer(
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
2000-06-05 06:59:38 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
struct berval **values,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
size_t slen, mlen;
|
|
|
|
struct berval **keys;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
2001-01-18 00:35:53 +08:00
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-06-05 06:59:38 +08:00
|
|
|
struct berval digest;
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-06-05 06:59:38 +08:00
|
|
|
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
|
|
|
/* just count them */
|
|
|
|
}
|
|
|
|
|
2001-07-26 09:08:00 +08:00
|
|
|
/* we should have at least one value at this point */
|
|
|
|
assert( i > 0 );
|
|
|
|
|
2000-06-05 06:59:38 +08:00
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
|
|
|
|
|
|
|
|
slen = strlen( syntax->ssyn_oid );
|
|
|
|
mlen = strlen( mr->smr_oid );
|
|
|
|
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-06-05 06:59:38 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
values[i]->bv_val, values[i]->bv_len );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-06-05 06:59:38 +08:00
|
|
|
|
|
|
|
keys[i] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
|
|
|
keys[i] = NULL;
|
|
|
|
|
|
|
|
*keysp = keys;
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Index generation function */
|
|
|
|
int octetStringFilter(
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
2000-06-05 06:59:38 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
void * assertValue,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
size_t slen, mlen;
|
|
|
|
struct berval **keys;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
2001-01-18 00:35:53 +08:00
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-06-05 06:59:38 +08:00
|
|
|
struct berval *value = (struct berval *) assertValue;
|
|
|
|
struct berval digest;
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-06-05 06:59:38 +08:00
|
|
|
|
|
|
|
slen = strlen( syntax->ssyn_oid );
|
|
|
|
mlen = strlen( mr->smr_oid );
|
|
|
|
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * 2 );
|
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-06-05 06:59:38 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
value->bv_val, value->bv_len );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-06-05 06:59:38 +08:00
|
|
|
|
|
|
|
keys[0] = ber_bvdup( &digest );
|
|
|
|
keys[1] = NULL;
|
|
|
|
|
|
|
|
*keysp = keys;
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2001-12-05 04:22:26 +08:00
|
|
|
#ifdef USE_LDAP_DN_PARSING
|
2001-12-06 19:50:17 +08:00
|
|
|
|
2001-12-10 17:46:50 +08:00
|
|
|
/*
|
|
|
|
* The DN syntax-related functions take advantage of the dn representation
|
|
|
|
* handling functions ldap_str2dn/ldap_dn2str. The latter are not schema-
|
|
|
|
* aware, so the attributes and their values need be validated (and possibly
|
|
|
|
* normalized). In the current implementation the required validation/nor-
|
|
|
|
* malization/"pretty"ing are done on newly created DN structural represen-
|
|
|
|
* tations; however the idea is to move towards DN handling in structural
|
|
|
|
* representation instead of the current string representation. To this
|
|
|
|
* purpose, we need to do only the required operations and keep track of
|
|
|
|
* what has been done to minimize their impact on performances.
|
|
|
|
*
|
|
|
|
* Developers are strongly encouraged to use this feature, to speed-up
|
|
|
|
* its stabilization.
|
|
|
|
*/
|
|
|
|
|
2001-12-06 19:50:17 +08:00
|
|
|
#define AVA_PRIVATE( ava ) ( ( AttributeDescription * )(ava)->la_private )
|
|
|
|
|
|
|
|
/*
|
|
|
|
* In-place, schema-aware validation of the
|
|
|
|
* structural representation of a distinguished name.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
LDAPDN_validate( LDAPDN *dn )
|
|
|
|
{
|
|
|
|
int iRDN;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
assert( dn );
|
|
|
|
|
|
|
|
for ( iRDN = 0; dn[ iRDN ]; iRDN++ ) {
|
|
|
|
LDAPRDN *rdn = dn[ iRDN ][ 0 ];
|
|
|
|
int iAVA;
|
|
|
|
|
2001-12-10 17:46:50 +08:00
|
|
|
assert( rdn );
|
|
|
|
|
2001-12-06 19:50:17 +08:00
|
|
|
for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) {
|
|
|
|
LDAPAVA *ava = rdn[ iAVA ][ 0 ];
|
|
|
|
AttributeDescription *ad;
|
|
|
|
slap_syntax_validate_func *validate = NULL;
|
2001-12-10 17:46:50 +08:00
|
|
|
|
|
|
|
assert( ava );
|
2001-12-06 19:50:17 +08:00
|
|
|
|
|
|
|
if ( ( ad = AVA_PRIVATE( ava ) ) == NULL ) {
|
|
|
|
const char *text = NULL;
|
|
|
|
|
|
|
|
rc = slap_bv2ad( ava->la_attr, &ad, &text );
|
|
|
|
if ( rc != LDAP_SUCCESS ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
ava->la_private = ( void * )ad;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Replace attr oid/name with the canonical name
|
|
|
|
*/
|
|
|
|
ber_bvfree( ava->la_attr );
|
|
|
|
ava->la_attr = ber_bvdup( &ad->ad_cname );
|
|
|
|
|
|
|
|
validate = ad->ad_type->sat_syntax->ssyn_validate;
|
|
|
|
|
|
|
|
if ( validate ) {
|
|
|
|
/*
|
|
|
|
* validate value by validate function
|
|
|
|
*/
|
|
|
|
rc = ( *validate )( ad->ad_type->sat_syntax,
|
|
|
|
ava->la_value );
|
|
|
|
|
|
|
|
if ( rc != LDAP_SUCCESS ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2001-12-10 17:46:50 +08:00
|
|
|
/*
|
|
|
|
* dn validate routine
|
|
|
|
*/
|
2001-12-05 04:22:26 +08:00
|
|
|
static int
|
|
|
|
dnValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
LDAPDN *dn = NULL;
|
|
|
|
|
2001-12-10 17:46:50 +08:00
|
|
|
assert( in );
|
|
|
|
|
2001-12-05 04:22:26 +08:00
|
|
|
if ( in->bv_len == 0 ) {
|
|
|
|
return( LDAP_SUCCESS );
|
|
|
|
}
|
|
|
|
|
2001-12-06 18:01:25 +08:00
|
|
|
rc = ldap_str2dn( in->bv_val, &dn, LDAP_DN_FORMAT_LDAP );
|
|
|
|
|
|
|
|
/*
|
2001-12-06 19:50:17 +08:00
|
|
|
* Schema-aware validate
|
2001-12-06 18:01:25 +08:00
|
|
|
*/
|
2001-12-06 19:50:17 +08:00
|
|
|
if ( rc == LDAP_SUCCESS ) {
|
|
|
|
rc = LDAPDN_validate( dn );
|
|
|
|
}
|
|
|
|
|
2001-12-05 04:22:26 +08:00
|
|
|
ldapava_free_dn( dn );
|
|
|
|
|
|
|
|
if ( rc != LDAP_SUCCESS ) {
|
|
|
|
return( LDAP_INVALID_SYNTAX );
|
|
|
|
}
|
|
|
|
|
|
|
|
return( LDAP_SUCCESS );
|
|
|
|
}
|
|
|
|
|
2001-12-10 17:46:50 +08:00
|
|
|
/*
|
|
|
|
* AVA sorting inside a RDN
|
|
|
|
*
|
|
|
|
* rule: sort attributeTypes in alphabetical order; in case of multiple
|
|
|
|
* occurrences of the same attributeType, sort values in byte order
|
|
|
|
* (use memcmp, which implies alphabetical order in case of IA5 value;
|
|
|
|
* this should guarantee the repeatability of the operation).
|
|
|
|
*
|
|
|
|
* uses a linear search; should be fine since the number of AVAs in
|
|
|
|
* a RDN should be limited.
|
|
|
|
*/
|
2001-12-06 03:26:30 +08:00
|
|
|
static void
|
|
|
|
AVA_Sort( LDAPRDN *rdn, int iAVA )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
LDAPAVA *ava_in = rdn[ iAVA ][ 0 ];
|
2001-12-10 17:46:50 +08:00
|
|
|
|
|
|
|
assert( rdn );
|
|
|
|
assert( ava_in );
|
2001-12-06 03:26:30 +08:00
|
|
|
|
|
|
|
for ( i = 0; i < iAVA; i++ ) {
|
|
|
|
LDAPAVA *ava = rdn[ i ][ 0 ];
|
|
|
|
int a, j;
|
|
|
|
|
2001-12-10 17:46:50 +08:00
|
|
|
assert( ava );
|
|
|
|
|
2001-12-06 03:26:30 +08:00
|
|
|
a = strcmp( ava_in->la_attr->bv_val, ava->la_attr->bv_val );
|
|
|
|
|
|
|
|
if ( a > 0 ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ( a == 0 ) {
|
|
|
|
int v, d;
|
|
|
|
|
|
|
|
d = ava_in->la_value->bv_len - ava->la_value->bv_len;
|
|
|
|
|
|
|
|
v = memcmp( ava_in->la_value->bv_val,
|
|
|
|
ava->la_value->bv_val,
|
|
|
|
d <= 0 ? ava_in->la_value->bv_len
|
|
|
|
: ava->la_value->bv_len );
|
|
|
|
|
|
|
|
if ( v == 0 && d != 0 ) {
|
|
|
|
v = d;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( v <= 0 ) {
|
|
|
|
/*
|
|
|
|
* got it!
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ++i == iAVA ) {
|
|
|
|
/*
|
|
|
|
* already sorted
|
|
|
|
*/
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ava = rdn[ i ][ 0 ];
|
|
|
|
a = strcmp( ava_in->la_value->bv_val,
|
|
|
|
ava->la_value->bv_val );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* move ahead
|
|
|
|
*/
|
|
|
|
for ( j = iAVA; j > i; j-- ) {
|
|
|
|
rdn[ j ][ 0 ] = rdn[ j - 1 ][ 0 ];
|
|
|
|
}
|
|
|
|
rdn[ i ][ 0 ] = ava_in;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-12-06 11:24:31 +08:00
|
|
|
* In-place, schema-aware normalization / "pretty"ing of the
|
|
|
|
* structural representation of a distinguished name.
|
2001-12-06 03:26:30 +08:00
|
|
|
*/
|
|
|
|
static int
|
2001-12-06 11:24:31 +08:00
|
|
|
LDAPDN_rewrite( LDAPDN *dn, unsigned flags )
|
2001-12-06 03:26:30 +08:00
|
|
|
{
|
|
|
|
int iRDN;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
assert( dn );
|
|
|
|
|
|
|
|
for ( iRDN = 0; dn[ iRDN ]; iRDN++ ) {
|
|
|
|
LDAPRDN *rdn = dn[ iRDN ][ 0 ];
|
|
|
|
int iAVA;
|
|
|
|
|
2001-12-10 17:46:50 +08:00
|
|
|
assert( rdn );
|
|
|
|
|
2001-12-06 03:26:30 +08:00
|
|
|
for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) {
|
|
|
|
LDAPAVA *ava = rdn[ iAVA ][ 0 ];
|
2001-12-06 19:50:17 +08:00
|
|
|
AttributeDescription *ad;
|
2001-12-06 11:24:31 +08:00
|
|
|
slap_syntax_transform_func *transf = NULL;
|
|
|
|
MatchingRule *mr;
|
2001-12-06 03:26:30 +08:00
|
|
|
struct berval *bv = NULL;
|
|
|
|
|
2001-12-10 17:46:50 +08:00
|
|
|
assert( ava );
|
|
|
|
|
2001-12-06 19:50:17 +08:00
|
|
|
if ( ( ad = AVA_PRIVATE( ava ) ) == NULL ) {
|
|
|
|
const char *text = NULL;
|
|
|
|
|
|
|
|
rc = slap_bv2ad( ava->la_attr, &ad, &text );
|
|
|
|
if ( rc != LDAP_SUCCESS ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
ava->la_private = ( void * )ad;
|
2001-12-06 03:26:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-12-06 11:24:31 +08:00
|
|
|
* Replace attr oid/name with the canonical name
|
2001-12-06 03:26:30 +08:00
|
|
|
*/
|
|
|
|
ber_bvfree( ava->la_attr );
|
|
|
|
ava->la_attr = ber_bvdup( &ad->ad_cname );
|
2001-12-06 11:24:31 +08:00
|
|
|
|
|
|
|
if( flags & SLAP_LDAPDN_PRETTY ) {
|
|
|
|
transf = ad->ad_type->sat_syntax->ssyn_pretty;
|
|
|
|
mr = NULL;
|
|
|
|
} else {
|
|
|
|
transf = ad->ad_type->sat_syntax->ssyn_normalize;
|
|
|
|
mr = ad->ad_type->sat_equality;
|
2001-12-06 03:26:30 +08:00
|
|
|
}
|
2001-12-06 11:24:31 +08:00
|
|
|
|
|
|
|
if ( transf ) {
|
|
|
|
/*
|
|
|
|
* transform value by normalize/pretty function
|
|
|
|
*/
|
|
|
|
rc = ( *transf )( ad->ad_type->sat_syntax,
|
|
|
|
ava->la_value, &bv );
|
2001-12-06 03:26:30 +08:00
|
|
|
|
2001-12-06 11:24:31 +08:00
|
|
|
if ( rc != LDAP_SUCCESS ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2001-12-06 03:26:30 +08:00
|
|
|
}
|
|
|
|
|
2001-12-06 11:24:31 +08:00
|
|
|
if( mr && ( mr->smr_usage & SLAP_MR_DN_FOLD ) ) {
|
2001-12-06 03:26:30 +08:00
|
|
|
struct berval *s = bv;
|
2001-12-06 11:24:31 +08:00
|
|
|
|
|
|
|
bv = ber_bvstr( UTF8normalize( bv ? bv : ava->la_value,
|
|
|
|
UTF8_CASEFOLD ) );
|
|
|
|
|
2001-12-06 03:26:30 +08:00
|
|
|
ber_bvfree( s );
|
|
|
|
}
|
|
|
|
|
2001-12-06 11:24:31 +08:00
|
|
|
if( bv ) {
|
|
|
|
ber_bvfree( ava->la_value );
|
|
|
|
ava->la_value = bv;
|
|
|
|
}
|
2001-12-06 03:26:30 +08:00
|
|
|
|
|
|
|
AVA_Sort( rdn, iAVA );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-12-06 11:24:31 +08:00
|
|
|
return LDAP_SUCCESS;
|
2001-12-06 03:26:30 +08:00
|
|
|
}
|
|
|
|
|
2001-12-10 17:46:50 +08:00
|
|
|
/*
|
|
|
|
* dn normalize routine
|
|
|
|
*/
|
2001-12-05 04:22:26 +08:00
|
|
|
int
|
|
|
|
dnNormalize(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val,
|
|
|
|
struct berval **normalized )
|
|
|
|
{
|
|
|
|
struct berval *out = NULL;
|
|
|
|
|
2001-12-06 11:24:31 +08:00
|
|
|
Debug( LDAP_DEBUG_TRACE, ">>> dnNormalize: <%s>\n", val->bv_val, 0, 0 );
|
2001-12-06 03:26:30 +08:00
|
|
|
|
2001-12-10 17:46:50 +08:00
|
|
|
assert( val );
|
|
|
|
assert( normalized );
|
|
|
|
|
2001-12-05 04:22:26 +08:00
|
|
|
if ( val->bv_len != 0 ) {
|
|
|
|
LDAPDN *dn = NULL;
|
|
|
|
char *dn_out = NULL;
|
2001-12-06 03:26:30 +08:00
|
|
|
int rc;
|
2001-12-05 04:22:26 +08:00
|
|
|
|
2001-12-06 03:26:30 +08:00
|
|
|
/*
|
|
|
|
* Go to structural representation
|
|
|
|
*/
|
2001-12-06 18:01:25 +08:00
|
|
|
rc = ldap_str2dn( val->bv_val, &dn, LDAP_DN_FORMAT_LDAP );
|
2001-12-05 04:22:26 +08:00
|
|
|
if ( rc != LDAP_SUCCESS ) {
|
2001-12-06 11:24:31 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2001-12-05 04:22:26 +08:00
|
|
|
}
|
|
|
|
|
2001-12-06 00:34:51 +08:00
|
|
|
/*
|
2001-12-06 11:24:31 +08:00
|
|
|
* Schema-aware rewrite
|
2001-12-06 00:34:51 +08:00
|
|
|
*/
|
2001-12-06 11:24:31 +08:00
|
|
|
if ( LDAPDN_rewrite( dn, 0 ) != LDAP_SUCCESS ) {
|
|
|
|
ldapava_free_dn( dn );
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
2001-12-06 00:34:51 +08:00
|
|
|
}
|
|
|
|
|
2001-12-06 03:26:30 +08:00
|
|
|
/*
|
|
|
|
* Back to string representation
|
|
|
|
*/
|
2001-12-05 04:22:26 +08:00
|
|
|
rc = ldap_dn2str( dn, &dn_out, LDAP_DN_FORMAT_LDAPV3 );
|
|
|
|
|
2001-12-06 11:24:31 +08:00
|
|
|
ldapava_free_dn( dn );
|
|
|
|
|
2001-12-05 04:22:26 +08:00
|
|
|
if ( rc != LDAP_SUCCESS ) {
|
2001-12-06 11:24:31 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2001-12-05 04:22:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
out = ber_bvstr( dn_out );
|
|
|
|
|
|
|
|
} else {
|
|
|
|
out = ber_bvdup( val );
|
|
|
|
}
|
|
|
|
|
2001-12-06 11:24:31 +08:00
|
|
|
Debug( LDAP_DEBUG_TRACE, "<<< dnNormalize: <%s>\n", out->bv_val, 0, 0 );
|
2001-12-06 03:26:30 +08:00
|
|
|
|
2001-12-05 04:22:26 +08:00
|
|
|
*normalized = out;
|
|
|
|
|
2001-12-06 11:24:31 +08:00
|
|
|
return LDAP_SUCCESS;
|
2001-12-05 04:22:26 +08:00
|
|
|
}
|
|
|
|
|
2001-12-10 17:46:50 +08:00
|
|
|
/*
|
|
|
|
* dn "pretty"ing routine
|
|
|
|
*/
|
2001-12-05 04:22:26 +08:00
|
|
|
int
|
|
|
|
dnPretty(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val,
|
2001-12-06 05:36:59 +08:00
|
|
|
struct berval **pretty)
|
2001-12-05 04:22:26 +08:00
|
|
|
{
|
|
|
|
struct berval *out = NULL;
|
|
|
|
|
2001-12-06 11:24:31 +08:00
|
|
|
Debug( LDAP_DEBUG_TRACE, ">>> dnPretty: <%s>\n", val->bv_val, 0, 0 );
|
|
|
|
|
2001-12-10 17:46:50 +08:00
|
|
|
assert( val );
|
|
|
|
assert( pretty );
|
|
|
|
|
2001-12-05 04:22:26 +08:00
|
|
|
if ( val->bv_len != 0 ) {
|
|
|
|
LDAPDN *dn = NULL;
|
|
|
|
char *dn_out = NULL;
|
|
|
|
int rc;
|
|
|
|
|
2001-12-06 05:07:57 +08:00
|
|
|
/* FIXME: should be liberal in what we accept */
|
2001-12-06 18:01:25 +08:00
|
|
|
rc = ldap_str2dn( val->bv_val, &dn, LDAP_DN_FORMAT_LDAP );
|
2001-12-05 04:22:26 +08:00
|
|
|
if ( rc != LDAP_SUCCESS ) {
|
2001-12-06 11:24:31 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2001-12-05 04:22:26 +08:00
|
|
|
}
|
|
|
|
|
2001-12-06 11:24:31 +08:00
|
|
|
/*
|
|
|
|
* Schema-aware rewrite
|
2001-12-06 05:07:57 +08:00
|
|
|
*/
|
2001-12-06 11:24:31 +08:00
|
|
|
if ( LDAPDN_rewrite( dn, SLAP_LDAPDN_PRETTY ) != LDAP_SUCCESS ) {
|
|
|
|
ldapava_free_dn( dn );
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2001-12-05 04:22:26 +08:00
|
|
|
|
2001-12-06 05:07:57 +08:00
|
|
|
/* FIXME: not sure why the default isn't pretty */
|
2001-12-10 17:46:50 +08:00
|
|
|
/* RE: the default is the form that is used as
|
|
|
|
* an internal representation; the pretty form
|
|
|
|
* is a variant */
|
2001-12-06 05:07:57 +08:00
|
|
|
rc = ldap_dn2str( dn, &dn_out,
|
|
|
|
LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY );
|
2001-12-06 11:24:31 +08:00
|
|
|
|
2001-12-05 04:22:26 +08:00
|
|
|
ldapava_free_dn( dn );
|
|
|
|
|
|
|
|
if ( rc != LDAP_SUCCESS ) {
|
2001-12-06 11:24:31 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2001-12-05 04:22:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
out = ber_bvstr( dn_out );
|
|
|
|
|
|
|
|
} else {
|
|
|
|
out = ber_bvdup( val );
|
|
|
|
}
|
|
|
|
|
2001-12-06 11:24:31 +08:00
|
|
|
Debug( LDAP_DEBUG_TRACE, "<<< dnPretty: <%s>\n", out->bv_val, 0, 0 );
|
|
|
|
|
2001-12-06 05:36:59 +08:00
|
|
|
*pretty = out;
|
2001-12-05 04:22:26 +08:00
|
|
|
|
2001-12-06 11:24:31 +08:00
|
|
|
return LDAP_SUCCESS;
|
2001-12-05 04:22:26 +08:00
|
|
|
}
|
|
|
|
|
2001-12-10 17:46:50 +08:00
|
|
|
/*
|
|
|
|
* dn match routine
|
|
|
|
*
|
|
|
|
* note: uses exact string match (strcmp) because it is supposed to work
|
|
|
|
* on normalized DNs.
|
|
|
|
*/
|
2001-12-05 04:22:26 +08:00
|
|
|
int
|
|
|
|
dnMatch(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
int match;
|
|
|
|
struct berval *asserted = (struct berval *) assertedValue;
|
2001-12-10 17:46:50 +08:00
|
|
|
|
|
|
|
assert( matchp );
|
|
|
|
assert( value );
|
|
|
|
assert( assertedValue );
|
2001-12-05 04:22:26 +08:00
|
|
|
|
|
|
|
match = value->bv_len - asserted->bv_len;
|
|
|
|
|
|
|
|
if ( match == 0 ) {
|
|
|
|
match = strcmp( value->bv_val, asserted->bv_val );
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef NEW_LOGGING
|
|
|
|
LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
|
|
|
|
"dnMatch: %d\n %s\n %s\n", match,
|
|
|
|
value->bv_val, asserted->bv_val ));
|
|
|
|
#else
|
|
|
|
Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
|
|
|
|
match, value->bv_val, asserted->bv_val );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
*matchp = match;
|
|
|
|
return( LDAP_SUCCESS );
|
|
|
|
}
|
|
|
|
|
|
|
|
#else /* !USE_LDAP_DN_PARSING */
|
|
|
|
|
2000-05-29 08:27:49 +08:00
|
|
|
static int
|
|
|
|
dnValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
char *dn;
|
|
|
|
|
|
|
|
if( in->bv_len == 0 ) return LDAP_SUCCESS;
|
|
|
|
|
2001-07-22 06:44:55 +08:00
|
|
|
dn = ch_strdup( in->bv_val );
|
2000-05-29 08:27:49 +08:00
|
|
|
|
2001-07-22 06:44:55 +08:00
|
|
|
if( dn == NULL ) {
|
2001-07-22 07:02:06 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
dn_validate/dn_normalize has been rewritten by
David A. Cooper <david.cooper@nist.gov> (ITS#1232)
according to draft-ietf-ldapbis-dn-05.txt
A copyright statement follows:
The functions normalize_unicode(), get_hexpair(), write_hex_pair(),
get_next_byte(), get_next_char(), get_ber_length(),
ber_parse_primitive_string(), ber_parse_string(), String_normalize(),
DirectoryString_normalize(), PrintableString_normalize(),
IA5String_normalize(), ber_parse_primitive_bitstring(),
ber_parse_bitstring(), getNext8bits(), bitString_normalize(), match_oid(),
match_key(), get_validated_av_in_dn(), get_validated_rdn_in_dn(),
and get_validated_dn() in this file were developed at the National Institute
of Standards and Technology by employees of the Federal Government in the
course of their official duties. Pursuant to title 17 Section 105 of the
United States Code the code in these functions is not subject to copyright
protection and is in the public domain. The copyright for all other code in
this file is as specified below.
2001-07-13 16:21:14 +08:00
|
|
|
|
2001-07-22 06:44:55 +08:00
|
|
|
} else if ( strlen( in->bv_val ) != in->bv_len ) {
|
2001-07-22 07:02:06 +08:00
|
|
|
rc = LDAP_INVALID_SYNTAX;
|
2000-05-29 08:27:49 +08:00
|
|
|
|
2001-07-22 06:44:55 +08:00
|
|
|
} else if ( dn_validate( dn ) == NULL ) {
|
2001-07-22 07:02:06 +08:00
|
|
|
rc = LDAP_INVALID_SYNTAX;
|
2001-07-22 06:44:55 +08:00
|
|
|
|
|
|
|
} else {
|
|
|
|
rc = LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
ch_free( dn );
|
2000-05-29 08:27:49 +08:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2001-01-26 00:51:59 +08:00
|
|
|
int
|
2000-05-29 08:27:49 +08:00
|
|
|
dnNormalize(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val,
|
|
|
|
struct berval **normalized )
|
|
|
|
{
|
2001-01-26 00:51:59 +08:00
|
|
|
struct berval *out;
|
2000-05-29 08:27:49 +08:00
|
|
|
|
2001-07-22 06:44:55 +08:00
|
|
|
if ( val->bv_len != 0 ) {
|
|
|
|
char *dn;
|
2001-11-10 03:01:23 +08:00
|
|
|
out = ber_bvstr( UTF8normalize( val, UTF8_CASEFOLD ) );
|
2001-07-22 08:32:58 +08:00
|
|
|
|
2001-07-22 06:44:55 +08:00
|
|
|
dn = dn_validate( out->bv_val );
|
|
|
|
|
2000-05-29 08:27:49 +08:00
|
|
|
if( dn == NULL ) {
|
2001-07-22 06:44:55 +08:00
|
|
|
ber_bvfree( out );
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2000-05-29 08:27:49 +08:00
|
|
|
|
2001-07-22 06:44:55 +08:00
|
|
|
out->bv_val = dn;
|
|
|
|
out->bv_len = strlen( dn );
|
|
|
|
} else {
|
|
|
|
out = ber_bvdup( val );
|
2000-05-29 08:27:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
*normalized = out;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2001-12-05 07:42:10 +08:00
|
|
|
int
|
2000-05-29 08:27:49 +08:00
|
|
|
dnMatch(
|
2000-05-29 09:08:09 +08:00
|
|
|
int *matchp,
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t flags,
|
2000-05-29 08:27:49 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
2000-05-29 09:08:09 +08:00
|
|
|
int match;
|
2000-05-29 08:27:49 +08:00
|
|
|
struct berval *asserted = (struct berval *) assertedValue;
|
|
|
|
|
2000-05-29 09:08:09 +08:00
|
|
|
match = value->bv_len - asserted->bv_len;
|
|
|
|
|
|
|
|
if( match == 0 ) {
|
2000-05-29 08:27:49 +08:00
|
|
|
#ifdef USE_DN_NORMALIZE
|
2000-05-29 09:08:09 +08:00
|
|
|
match = strcmp( value->bv_val, asserted->bv_val );
|
2000-05-29 08:27:49 +08:00
|
|
|
#else
|
2000-05-29 09:08:09 +08:00
|
|
|
match = strcasecmp( value->bv_val, asserted->bv_val );
|
2000-05-29 08:27:49 +08:00
|
|
|
#endif
|
2000-05-29 09:08:09 +08:00
|
|
|
}
|
|
|
|
|
2001-01-16 03:17:29 +08:00
|
|
|
#ifdef NEW_LOGGING
|
2001-01-18 00:35:53 +08:00
|
|
|
LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
|
2001-07-22 07:02:06 +08:00
|
|
|
"dnMatch: %d\n %s\n %s\n", match,
|
|
|
|
value->bv_val, asserted->bv_val ));
|
2001-01-16 03:17:29 +08:00
|
|
|
#else
|
2000-05-29 09:08:09 +08:00
|
|
|
Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
|
2001-07-22 07:02:06 +08:00
|
|
|
match, value->bv_val, asserted->bv_val );
|
2001-01-16 03:17:29 +08:00
|
|
|
#endif
|
|
|
|
|
2000-05-29 09:08:09 +08:00
|
|
|
|
|
|
|
*matchp = match;
|
|
|
|
return LDAP_SUCCESS;
|
2000-05-29 08:27:49 +08:00
|
|
|
}
|
2000-06-20 11:55:40 +08:00
|
|
|
|
2001-12-05 04:22:26 +08:00
|
|
|
#endif /* !USE_LDAP_DN_PARSING */
|
|
|
|
|
2000-09-12 08:32:08 +08:00
|
|
|
static int
|
|
|
|
nameUIDValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct berval *dn;
|
|
|
|
|
|
|
|
if( in->bv_len == 0 ) return LDAP_SUCCESS;
|
|
|
|
|
|
|
|
dn = ber_bvdup( in );
|
|
|
|
|
|
|
|
if( dn->bv_val[dn->bv_len-1] == '\'' ) {
|
|
|
|
/* assume presence of optional UID */
|
|
|
|
ber_len_t i;
|
|
|
|
|
|
|
|
for(i=dn->bv_len-2; i>2; i--) {
|
|
|
|
if( dn->bv_val[i] != '0' && dn->bv_val[i] != '1' ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-11-07 06:36:28 +08:00
|
|
|
if( dn->bv_val[i] != '\'' ||
|
|
|
|
dn->bv_val[i-1] != 'B' ||
|
|
|
|
dn->bv_val[i-2] != '#' ) {
|
|
|
|
ber_bvfree( dn );
|
2000-09-12 08:32:08 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* trim the UID to allow use of dn_validate */
|
|
|
|
dn->bv_val[i-2] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = dn_validate( dn->bv_val ) == NULL
|
|
|
|
? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
|
|
|
|
|
|
|
|
ber_bvfree( dn );
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
nameUIDNormalize(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val,
|
|
|
|
struct berval **normalized )
|
|
|
|
{
|
|
|
|
struct berval *out = ber_bvdup( val );
|
|
|
|
|
|
|
|
if( out->bv_len != 0 ) {
|
|
|
|
char *dn;
|
|
|
|
ber_len_t dnlen;
|
|
|
|
char *uid = NULL;
|
|
|
|
ber_len_t uidlen = 0;
|
|
|
|
|
|
|
|
if( out->bv_val[out->bv_len-1] == '\'' ) {
|
|
|
|
/* assume presence of optional UID */
|
|
|
|
uid = strrchr( out->bv_val, '#' );
|
|
|
|
|
|
|
|
if( uid == NULL ) {
|
|
|
|
ber_bvfree( out );
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
uidlen = out->bv_len - (out->bv_val - uid);
|
|
|
|
/* temporarily trim the UID */
|
|
|
|
*uid = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef USE_DN_NORMALIZE
|
|
|
|
dn = dn_normalize( out->bv_val );
|
|
|
|
#else
|
|
|
|
dn = dn_validate( out->bv_val );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if( dn == NULL ) {
|
|
|
|
ber_bvfree( out );
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
dnlen = strlen(dn);
|
|
|
|
|
|
|
|
if( uidlen ) {
|
|
|
|
/* restore the separator */
|
|
|
|
*uid = '#';
|
|
|
|
/* shift the UID */
|
|
|
|
SAFEMEMCPY( &dn[dnlen], uid, uidlen );
|
|
|
|
}
|
|
|
|
|
|
|
|
out->bv_val = dn;
|
|
|
|
out->bv_len = dnlen + uidlen;
|
|
|
|
}
|
|
|
|
|
|
|
|
*normalized = out;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-05-28 03:33:08 +08:00
|
|
|
static int
|
|
|
|
inValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
/* any value allowed */
|
|
|
|
return LDAP_OTHER;
|
|
|
|
}
|
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
static int
|
2000-05-19 01:21:42 +08:00
|
|
|
blobValidate(
|
2000-01-30 03:43:19 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
/* any value allowed */
|
2000-05-25 07:27:33 +08:00
|
|
|
return LDAP_SUCCESS;
|
2000-01-30 03:43:19 +08:00
|
|
|
}
|
|
|
|
|
2000-09-12 08:32:08 +08:00
|
|
|
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;
|
|
|
|
}
|
2001-05-30 14:06:14 +08:00
|
|
|
|
2001-11-17 02:10:37 +08:00
|
|
|
/*
|
|
|
|
* 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' )
|
2000-09-12 08:32:08 +08:00
|
|
|
{
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
2001-11-17 02:10:37 +08:00
|
|
|
for( i=in->bv_len-3; i>0; i-- ) {
|
2000-09-12 08:32:08 +08:00
|
|
|
if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2001-11-17 02:10:37 +08:00
|
|
|
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.
|
|
|
|
*/
|
|
|
|
struct berval *newval;
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
/* start at the first bit */
|
|
|
|
p = &val->bv_val[1];
|
|
|
|
|
|
|
|
/* Find the first non-zero bit */
|
|
|
|
while ( *p == '0' ) p++;
|
|
|
|
|
|
|
|
newval = (struct berval *) ch_malloc( sizeof(struct berval) );
|
|
|
|
|
|
|
|
if( *p == '\'' ) {
|
|
|
|
/* no non-zero bits */
|
|
|
|
newval->bv_val = ch_strdup("\'0\'B");
|
|
|
|
newval->bv_len = sizeof("\'0\'B") - 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
newval->bv_val = ch_malloc( val->bv_len + 1 );
|
|
|
|
|
|
|
|
newval->bv_val[0] = '\'';
|
|
|
|
newval->bv_len = 1;
|
|
|
|
|
|
|
|
for( ; *p != '\0'; p++ ) {
|
|
|
|
newval->bv_val[newval->bv_len++] = *p;
|
|
|
|
}
|
|
|
|
|
|
|
|
newval->bv_val[newval->bv_len] = '\0';
|
|
|
|
|
|
|
|
done:
|
|
|
|
*normalized = newval;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-06-30 03:00:17 +08:00
|
|
|
/*
|
|
|
|
* Handling boolean syntax and matching is quite rigid.
|
|
|
|
* A more flexible approach would be to allow a variety
|
|
|
|
* of strings to be normalized and prettied into TRUE
|
|
|
|
* and FALSE.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
booleanValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
/* very unforgiving validation, requires no normalization
|
|
|
|
* before simplistic matching
|
|
|
|
*/
|
|
|
|
|
|
|
|
if( in->bv_len == 4 ) {
|
|
|
|
if( !memcmp( in->bv_val, "TRUE", 4 ) ) {
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
} else if( in->bv_len == 5 ) {
|
|
|
|
if( !memcmp( in->bv_val, "FALSE", 5 ) ) {
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
booleanMatch(
|
|
|
|
int *matchp,
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t flags,
|
2000-06-30 03:00:17 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
/* simplistic matching allowed by rigid validation */
|
|
|
|
struct berval *asserted = (struct berval *) assertedValue;
|
|
|
|
*matchp = value->bv_len != asserted->bv_len;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
static int
|
|
|
|
UTF8StringValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
ber_len_t count;
|
|
|
|
int len;
|
|
|
|
unsigned char *u = in->bv_val;
|
|
|
|
|
2000-06-24 07:57:53 +08:00
|
|
|
if( !in->bv_len ) return LDAP_INVALID_SYNTAX;
|
|
|
|
|
2000-05-23 10:33:56 +08:00
|
|
|
for( count = in->bv_len; count > 0; count-=len, u+=len ) {
|
2000-01-30 03:43:19 +08:00
|
|
|
/* get the length indicated by the first byte */
|
|
|
|
len = LDAP_UTF8_CHARLEN( u );
|
|
|
|
|
|
|
|
/* should not be zero */
|
2000-05-25 07:27:33 +08:00
|
|
|
if( len == 0 ) return LDAP_INVALID_SYNTAX;
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
/* make sure len corresponds with the offset
|
|
|
|
to the next character */
|
2000-05-25 07:27:33 +08:00
|
|
|
if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
|
2000-01-30 03:43:19 +08:00
|
|
|
}
|
|
|
|
|
2000-05-25 07:27:33 +08:00
|
|
|
if( count != 0 ) return LDAP_INVALID_SYNTAX;
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-05-25 07:27:33 +08:00
|
|
|
return LDAP_SUCCESS;
|
2000-01-30 03:43:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
UTF8StringNormalize(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val,
|
|
|
|
struct berval **normalized )
|
|
|
|
{
|
|
|
|
struct berval *newval;
|
2000-09-08 07:46:07 +08:00
|
|
|
char *p, *q, *s;
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
newval = ch_malloc( sizeof( struct berval ) );
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
p = val->bv_val;
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
/* Ignore initial whitespace */
|
|
|
|
while ( ldap_utf8_isspace( p ) ) {
|
|
|
|
LDAP_UTF8_INCR( p );
|
2000-09-08 07:19:10 +08:00
|
|
|
}
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
if( *p == '\0' ) {
|
|
|
|
ch_free( newval );
|
2000-09-08 07:19:10 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
newval->bv_val = ch_strdup( p );
|
|
|
|
p = q = newval->bv_val;
|
|
|
|
s = NULL;
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
while ( *p ) {
|
|
|
|
int len;
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
if ( ldap_utf8_isspace( p ) ) {
|
|
|
|
len = LDAP_UTF8_COPY(q,p);
|
|
|
|
s=q;
|
|
|
|
p+=len;
|
|
|
|
q+=len;
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
/* Ignore the extra whitespace */
|
|
|
|
while ( ldap_utf8_isspace( p ) ) {
|
|
|
|
LDAP_UTF8_INCR( p );
|
|
|
|
}
|
2000-09-08 07:19:10 +08:00
|
|
|
} else {
|
2000-09-08 07:46:07 +08:00
|
|
|
len = LDAP_UTF8_COPY(q,p);
|
|
|
|
s=NULL;
|
|
|
|
p+=len;
|
|
|
|
q+=len;
|
2000-09-08 07:19:10 +08:00
|
|
|
}
|
2000-09-08 07:46:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
assert( *newval->bv_val );
|
|
|
|
assert( newval->bv_val < p );
|
2000-09-13 09:23:39 +08:00
|
|
|
assert( q <= p );
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
/* cannot start with a space */
|
|
|
|
assert( !ldap_utf8_isspace(newval->bv_val) );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the string ended in space, backup the pointer one
|
|
|
|
* position. One is enough because the above loop collapsed
|
|
|
|
* all whitespace to a single space.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if ( s != NULL ) {
|
|
|
|
q = s;
|
2000-09-08 07:19:10 +08:00
|
|
|
}
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
/* cannot end with a space */
|
|
|
|
assert( !ldap_utf8_isspace( LDAP_UTF8_PREV(q) ) );
|
|
|
|
|
|
|
|
/* null terminate */
|
|
|
|
*q = '\0';
|
|
|
|
|
|
|
|
newval->bv_len = q - newval->bv_val;
|
|
|
|
*normalized = newval;
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-05-25 07:27:33 +08:00
|
|
|
return LDAP_SUCCESS;
|
2000-01-30 03:43:19 +08:00
|
|
|
}
|
|
|
|
|
2001-07-17 06:48:52 +08:00
|
|
|
/* Returns Unicode cannonically normalized copy of a substring assertion
|
|
|
|
* Skipping attribute description */
|
|
|
|
SubstringsAssertion *
|
|
|
|
UTF8SubstringsassertionNormalize(
|
|
|
|
SubstringsAssertion *sa,
|
|
|
|
char casefold )
|
|
|
|
{
|
|
|
|
SubstringsAssertion *nsa;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) );
|
|
|
|
if( nsa == NULL ) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( sa->sa_initial != NULL ) {
|
2001-11-10 03:01:23 +08:00
|
|
|
nsa->sa_initial = ber_bvstr( UTF8normalize( sa->sa_initial, casefold ) );
|
2001-07-17 06:48:52 +08:00
|
|
|
if( nsa->sa_initial == NULL ) {
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( sa->sa_any != NULL ) {
|
|
|
|
for( i=0; sa->sa_any[i] != NULL; i++ ) {
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
nsa->sa_any = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
|
|
|
|
for( i=0; sa->sa_any[i] != NULL; i++ ) {
|
2001-11-10 03:01:23 +08:00
|
|
|
nsa->sa_any[i] = ber_bvstr( UTF8normalize( sa->sa_any[i], casefold ) );
|
2001-07-17 06:48:52 +08:00
|
|
|
if( nsa->sa_any[i] == NULL ) {
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nsa->sa_any[i] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( sa->sa_final != NULL ) {
|
2001-11-10 03:01:23 +08:00
|
|
|
nsa->sa_final = ber_bvstr( UTF8normalize( sa->sa_final, casefold ) );
|
2001-07-17 06:48:52 +08:00
|
|
|
if( nsa->sa_final == NULL ) {
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nsa;
|
|
|
|
|
|
|
|
err:
|
2001-11-07 03:07:15 +08:00
|
|
|
ber_bvfree( nsa->sa_final );
|
2001-07-17 06:48:52 +08:00
|
|
|
ber_bvecfree( nsa->sa_any );
|
2001-11-07 03:07:15 +08:00
|
|
|
ber_bvfree( nsa->sa_initial );
|
2001-07-17 06:48:52 +08:00
|
|
|
ch_free( nsa );
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2001-07-26 05:22:55 +08:00
|
|
|
/* Strip characters with the 8th bit set */
|
|
|
|
char *
|
|
|
|
strip8bitChars(
|
|
|
|
char *in )
|
|
|
|
{
|
|
|
|
char *p = in, *q;
|
|
|
|
|
|
|
|
if( in == NULL ) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
while( *p ) {
|
|
|
|
if( *p & 0x80 ) {
|
|
|
|
q = p;
|
|
|
|
while( *++q & 0x80 ) {
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
p = memmove(p, q, strlen(q) + 1);
|
|
|
|
} else {
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return in;
|
|
|
|
}
|
|
|
|
|
2001-07-27 06:33:28 +08:00
|
|
|
#ifndef SLAPD_APPROX_OLDSINGLESTRING
|
2000-10-25 04:25:37 +08:00
|
|
|
|
|
|
|
#if defined(SLAPD_APPROX_INITIALS)
|
|
|
|
#define SLAPD_APPROX_DELIMITER "._ "
|
|
|
|
#define SLAPD_APPROX_WORDLEN 2
|
|
|
|
#else
|
|
|
|
#define SLAPD_APPROX_DELIMITER " "
|
|
|
|
#define SLAPD_APPROX_WORDLEN 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static int
|
|
|
|
approxMatch(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
2001-11-07 03:07:15 +08:00
|
|
|
char *val, *nval, *assertv, **values, **words, *c;
|
2000-10-25 04:25:37 +08:00
|
|
|
int i, count, len, nextchunk=0, nextavail=0;
|
2001-07-26 05:22:55 +08:00
|
|
|
size_t avlen;
|
2000-10-25 04:25:37 +08:00
|
|
|
|
2001-07-26 05:22:55 +08:00
|
|
|
/* Yes, this is necessary */
|
2001-11-10 03:01:23 +08:00
|
|
|
nval = UTF8normalize( value, UTF8_NOCASEFOLD );
|
2001-11-07 03:07:15 +08:00
|
|
|
if( nval == NULL ) {
|
2001-07-26 05:22:55 +08:00
|
|
|
*matchp = 1;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2001-11-07 03:07:15 +08:00
|
|
|
strip8bitChars( nval );
|
2001-07-26 05:22:55 +08:00
|
|
|
|
|
|
|
/* Yes, this is necessary */
|
2001-11-10 03:01:23 +08:00
|
|
|
assertv = UTF8normalize( ((struct berval *)assertedValue),
|
2001-07-26 05:22:55 +08:00
|
|
|
UTF8_NOCASEFOLD );
|
|
|
|
if( assertv == NULL ) {
|
2001-11-07 03:07:15 +08:00
|
|
|
ch_free( nval );
|
2001-07-26 05:22:55 +08:00
|
|
|
*matchp = 1;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
strip8bitChars( assertv );
|
|
|
|
avlen = strlen( assertv );
|
2000-10-25 04:25:37 +08:00
|
|
|
|
|
|
|
/* Isolate how many words there are */
|
2001-11-07 03:07:15 +08:00
|
|
|
for( c=nval,count=1; *c; c++ ) {
|
2000-10-25 04:25:37 +08:00
|
|
|
c = strpbrk( c, SLAPD_APPROX_DELIMITER );
|
|
|
|
if ( c == NULL ) break;
|
|
|
|
*c = '\0';
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get a phonetic copy of each word */
|
|
|
|
words = (char **)ch_malloc( count * sizeof(char *) );
|
|
|
|
values = (char **)ch_malloc( count * sizeof(char *) );
|
2001-11-07 03:07:15 +08:00
|
|
|
for( c=nval,i=0; i<count; i++,c+=strlen(c)+1 ) {
|
2000-10-25 04:25:37 +08:00
|
|
|
words[i] = c;
|
|
|
|
values[i] = phonetic(c);
|
|
|
|
}
|
|
|
|
|
2001-07-26 05:22:55 +08:00
|
|
|
/* Work through the asserted value's words, to see if at least some
|
2000-10-25 04:25:37 +08:00
|
|
|
of the words are there, in the same order. */
|
|
|
|
len = 0;
|
2001-07-26 05:22:55 +08:00
|
|
|
while ( nextchunk < avlen ) {
|
2000-10-25 04:25:37 +08:00
|
|
|
len = strcspn( assertv + nextchunk, SLAPD_APPROX_DELIMITER);
|
2000-11-04 00:16:27 +08:00
|
|
|
if( len == 0 ) {
|
|
|
|
nextchunk++;
|
|
|
|
continue;
|
|
|
|
}
|
2000-10-25 04:25:37 +08:00
|
|
|
#if defined(SLAPD_APPROX_INITIALS)
|
2000-11-04 00:16:27 +08:00
|
|
|
else if( len == 1 ) {
|
2000-10-25 04:25:37 +08:00
|
|
|
/* Single letter words need to at least match one word's initial */
|
|
|
|
for( i=nextavail; i<count; i++ )
|
2000-11-04 00:16:27 +08:00
|
|
|
if( !strncasecmp( assertv+nextchunk, words[i], 1 )) {
|
|
|
|
nextavail=i+1;
|
2000-10-25 04:25:37 +08:00
|
|
|
break;
|
2000-11-04 00:16:27 +08:00
|
|
|
}
|
2000-10-25 04:25:37 +08:00
|
|
|
}
|
|
|
|
#endif
|
2000-11-04 00:16:27 +08:00
|
|
|
else {
|
2000-10-25 04:25:37 +08:00
|
|
|
/* Isolate the next word in the asserted value and phonetic it */
|
|
|
|
assertv[nextchunk+len] = '\0';
|
|
|
|
val = phonetic( assertv + nextchunk );
|
|
|
|
|
|
|
|
/* See if this phonetic chunk is in the remaining words of *value */
|
|
|
|
for( i=nextavail; i<count; i++ ){
|
|
|
|
if( !strcmp( val, values[i] ) ){
|
|
|
|
nextavail = i+1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-11-07 03:07:15 +08:00
|
|
|
ch_free( val );
|
2000-10-25 04:25:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* This chunk in the asserted value was NOT within the *value. */
|
|
|
|
if( i >= count ) {
|
|
|
|
nextavail=-1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Go on to the next word in the asserted value */
|
|
|
|
nextchunk += len+1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If some of the words were seen, call it a match */
|
|
|
|
if( nextavail > 0 ) {
|
|
|
|
*matchp = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*matchp = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cleanup allocs */
|
2001-07-26 05:22:55 +08:00
|
|
|
free( assertv );
|
2000-10-25 04:25:37 +08:00
|
|
|
for( i=0; i<count; i++ ) {
|
|
|
|
ch_free( values[i] );
|
|
|
|
}
|
|
|
|
ch_free( values );
|
|
|
|
ch_free( words );
|
2001-11-07 03:07:15 +08:00
|
|
|
ch_free( nval );
|
2000-10-25 04:25:37 +08:00
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
approxIndexer(
|
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
struct berval **values,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
char *val, *c;
|
|
|
|
int i,j, len, wordcount, keycount=0;
|
|
|
|
struct berval **newkeys, **keys=NULL;
|
|
|
|
|
|
|
|
for( j=0; values[j] != NULL; j++ ) {
|
2001-07-26 05:22:55 +08:00
|
|
|
/* Yes, this is necessary */
|
2001-11-10 03:01:23 +08:00
|
|
|
val = UTF8normalize( values[j], UTF8_NOCASEFOLD );
|
2001-07-26 05:22:55 +08:00
|
|
|
strip8bitChars( val );
|
|
|
|
|
2000-10-25 04:25:37 +08:00
|
|
|
/* Isolate how many words there are. There will be a key for each */
|
2001-01-18 00:35:53 +08:00
|
|
|
for( wordcount=0,c=val; *c; c++) {
|
2000-10-25 04:25:37 +08:00
|
|
|
len = strcspn(c, SLAPD_APPROX_DELIMITER);
|
|
|
|
if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
|
|
|
|
c+= len;
|
|
|
|
if (*c == '\0') break;
|
|
|
|
*c = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate/increase storage to account for new keys */
|
|
|
|
newkeys = (struct berval **)ch_malloc( (keycount + wordcount + 1)
|
2001-07-22 07:02:06 +08:00
|
|
|
* sizeof(struct berval *) );
|
2000-10-25 04:25:37 +08:00
|
|
|
memcpy( newkeys, keys, keycount * sizeof(struct berval *) );
|
|
|
|
if( keys ) ch_free( keys );
|
|
|
|
keys = newkeys;
|
|
|
|
|
|
|
|
/* Get a phonetic copy of each word */
|
2001-01-18 00:35:53 +08:00
|
|
|
for( c=val,i=0; i<wordcount; c+=len+1 ) {
|
2000-10-25 04:25:37 +08:00
|
|
|
len = strlen( c );
|
|
|
|
if( len < SLAPD_APPROX_WORDLEN ) continue;
|
|
|
|
keys[keycount] = (struct berval *)ch_malloc( sizeof(struct berval) );
|
|
|
|
keys[keycount]->bv_val = phonetic( c );
|
|
|
|
keys[keycount]->bv_len = strlen( keys[keycount]->bv_val );
|
|
|
|
keycount++;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
2001-07-26 05:22:55 +08:00
|
|
|
free( val );
|
2000-10-25 04:25:37 +08:00
|
|
|
}
|
|
|
|
keys[keycount] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
approxFilter(
|
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
void * assertValue,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
char *val, *c;
|
|
|
|
int i, count, len;
|
|
|
|
struct berval **keys;
|
|
|
|
|
2001-07-26 05:22:55 +08:00
|
|
|
/* Yes, this is necessary */
|
2001-11-10 03:01:23 +08:00
|
|
|
val = UTF8normalize( ((struct berval *)assertValue),
|
2001-07-26 05:22:55 +08:00
|
|
|
UTF8_NOCASEFOLD );
|
|
|
|
if( val == NULL ) {
|
|
|
|
keys = (struct berval **)ch_malloc( sizeof(struct berval *) );
|
|
|
|
keys[0] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
strip8bitChars( val );
|
|
|
|
|
2000-10-25 04:25:37 +08:00
|
|
|
/* Isolate how many words there are. There will be a key for each */
|
|
|
|
for( count=0,c=val; *c; c++) {
|
|
|
|
len = strcspn(c, SLAPD_APPROX_DELIMITER);
|
|
|
|
if( len >= SLAPD_APPROX_WORDLEN ) count++;
|
|
|
|
c+= len;
|
|
|
|
if (*c == '\0') break;
|
|
|
|
*c = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate storage for new keys */
|
|
|
|
keys = (struct berval **)ch_malloc( (count + 1) * sizeof(struct berval *) );
|
|
|
|
|
|
|
|
/* Get a phonetic copy of each word */
|
2001-01-18 00:35:53 +08:00
|
|
|
for( c=val,i=0; i<count; c+=len+1 ) {
|
2000-10-25 04:25:37 +08:00
|
|
|
len = strlen(c);
|
|
|
|
if( len < SLAPD_APPROX_WORDLEN ) continue;
|
2001-07-26 05:22:55 +08:00
|
|
|
keys[i] = ber_bvstr( phonetic( c ) );
|
2000-10-25 04:25:37 +08:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
2001-07-26 05:22:55 +08:00
|
|
|
free( val );
|
2000-10-25 04:25:37 +08:00
|
|
|
|
|
|
|
keys[count] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
/* No other form of Approximate Matching is defined */
|
|
|
|
|
|
|
|
static int
|
|
|
|
approxMatch(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
char *vapprox, *avapprox;
|
2001-07-26 05:22:55 +08:00
|
|
|
char *s, *t;
|
2000-10-25 04:25:37 +08:00
|
|
|
|
2001-07-26 05:22:55 +08:00
|
|
|
/* Yes, this is necessary */
|
2001-11-10 03:01:23 +08:00
|
|
|
s = UTF8normalize( value, UTF8_NOCASEFOLD );
|
2001-07-26 05:22:55 +08:00
|
|
|
if( s == NULL ) {
|
|
|
|
*matchp = 1;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Yes, this is necessary */
|
2001-11-10 03:01:23 +08:00
|
|
|
t = UTF8normalize( ((struct berval *)assertedValue),
|
2001-07-26 05:22:55 +08:00
|
|
|
UTF8_NOCASEFOLD );
|
|
|
|
if( t == NULL ) {
|
|
|
|
free( s );
|
|
|
|
*matchp = -1;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
vapprox = phonetic( strip8bitChars( s ) );
|
|
|
|
avapprox = phonetic( strip8bitChars( t ) );
|
|
|
|
|
|
|
|
free( s );
|
|
|
|
free( t );
|
2000-10-25 04:25:37 +08:00
|
|
|
|
|
|
|
*matchp = strcmp( vapprox, avapprox );
|
|
|
|
|
|
|
|
ch_free( vapprox );
|
|
|
|
ch_free( avapprox );
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
approxIndexer(
|
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
struct berval **values,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct berval **keys;
|
2001-07-26 05:22:55 +08:00
|
|
|
char *s;
|
2000-10-25 04:25:37 +08:00
|
|
|
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
2001-07-26 09:08:00 +08:00
|
|
|
/* empty - just count them */
|
2000-10-25 04:25:37 +08:00
|
|
|
}
|
2001-07-26 09:08:00 +08:00
|
|
|
|
|
|
|
/* we should have at least one value at this point */
|
2000-10-25 04:25:37 +08:00
|
|
|
assert( i > 0 );
|
|
|
|
|
|
|
|
keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * (i+1) );
|
|
|
|
|
|
|
|
/* Copy each value and run it through phonetic() */
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
2001-07-26 05:22:55 +08:00
|
|
|
/* Yes, this is necessary */
|
2001-11-10 03:01:23 +08:00
|
|
|
s = UTF8normalize( values[i], UTF8_NOCASEFOLD );
|
2001-07-26 05:22:55 +08:00
|
|
|
|
|
|
|
/* strip 8-bit chars and run through phonetic() */
|
|
|
|
keys[i] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
|
|
|
|
free( s );
|
2000-10-25 04:25:37 +08:00
|
|
|
}
|
|
|
|
keys[i] = NULL;
|
|
|
|
|
|
|
|
*keysp = keys;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
approxFilter(
|
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
void * assertValue,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
struct berval **keys;
|
2001-07-26 05:22:55 +08:00
|
|
|
char *s;
|
2000-10-25 04:25:37 +08:00
|
|
|
|
|
|
|
keys = (struct berval **)ch_malloc( sizeof( struct berval * ) * 2 );
|
|
|
|
|
2001-07-26 05:22:55 +08:00
|
|
|
/* Yes, this is necessary */
|
2001-11-10 03:01:23 +08:00
|
|
|
s = UTF8normalize( ((struct berval *)assertValue),
|
2001-07-26 05:22:55 +08:00
|
|
|
UTF8_NOCASEFOLD );
|
|
|
|
if( s == NULL ) {
|
|
|
|
keys[0] = NULL;
|
|
|
|
} else {
|
|
|
|
/* strip 8-bit chars and run through phonetic() */
|
|
|
|
keys[0] = ber_bvstr( phonetic( strip8bitChars( s ) ) );
|
|
|
|
free( s );
|
|
|
|
keys[1] = NULL;
|
|
|
|
}
|
2000-10-25 04:25:37 +08:00
|
|
|
|
|
|
|
*keysp = keys;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2000-05-23 10:33:56 +08:00
|
|
|
static int
|
2000-09-04 02:04:08 +08:00
|
|
|
caseExactMatch(
|
2000-06-20 11:55:40 +08:00
|
|
|
int *matchp,
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t flags,
|
2000-01-30 03:43:19 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
2000-02-15 04:57:34 +08:00
|
|
|
void *assertedValue )
|
2000-01-30 03:43:19 +08:00
|
|
|
{
|
2001-07-18 04:09:37 +08:00
|
|
|
*matchp = UTF8normcmp( value->bv_val,
|
|
|
|
((struct berval *) assertedValue)->bv_val,
|
|
|
|
UTF8_NOCASEFOLD );
|
2000-05-25 02:49:30 +08:00
|
|
|
return LDAP_SUCCESS;
|
2000-01-30 03:43:19 +08:00
|
|
|
}
|
|
|
|
|
2000-05-28 07:08:28 +08:00
|
|
|
static int
|
2001-07-28 06:54:43 +08:00
|
|
|
caseExactIgnoreSubstringsMatch(
|
2000-05-28 07:08:28 +08:00
|
|
|
int *matchp,
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t flags,
|
2000-05-28 07:08:28 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
int match = 0;
|
2001-11-18 00:18:07 +08:00
|
|
|
SubstringsAssertion *sub = NULL;
|
2001-07-18 03:35:23 +08:00
|
|
|
struct berval left;
|
2000-05-28 07:08:28 +08:00
|
|
|
int i;
|
|
|
|
ber_len_t inlen=0;
|
2001-07-28 06:54:43 +08:00
|
|
|
char *nav, casefold;
|
|
|
|
|
|
|
|
casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
|
|
|
|
? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
|
2001-07-18 03:35:23 +08:00
|
|
|
|
2001-11-10 03:01:23 +08:00
|
|
|
nav = UTF8normalize( value, casefold );
|
2001-07-18 03:35:23 +08:00
|
|
|
if( nav == NULL ) {
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
left.bv_val = nav;
|
|
|
|
left.bv_len = strlen( nav );
|
2001-07-22 07:02:06 +08:00
|
|
|
|
2001-07-28 06:54:43 +08:00
|
|
|
sub = UTF8SubstringsassertionNormalize( assertedValue, casefold );
|
2001-07-18 03:35:23 +08:00
|
|
|
if( sub == NULL ) {
|
|
|
|
match = -1;
|
|
|
|
goto done;
|
|
|
|
}
|
2000-05-28 07:08:28 +08:00
|
|
|
|
2000-06-16 03:32:24 +08:00
|
|
|
/* Add up asserted input length */
|
2000-05-28 07:08:28 +08:00
|
|
|
if( sub->sa_initial ) {
|
|
|
|
inlen += sub->sa_initial->bv_len;
|
|
|
|
}
|
|
|
|
if( sub->sa_any ) {
|
2000-06-16 03:32:24 +08:00
|
|
|
for(i=0; sub->sa_any[i] != NULL; i++) {
|
|
|
|
inlen += sub->sa_any[i]->bv_len;
|
2000-05-28 07:08:28 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if( sub->sa_final ) {
|
|
|
|
inlen += sub->sa_final->bv_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( sub->sa_initial ) {
|
2000-06-16 03:56:51 +08:00
|
|
|
if( inlen > left.bv_len ) {
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
match = strncmp( sub->sa_initial->bv_val, left.bv_val,
|
|
|
|
sub->sa_initial->bv_len );
|
2000-05-28 07:08:28 +08:00
|
|
|
|
|
|
|
if( match != 0 ) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
left.bv_val += sub->sa_initial->bv_len;
|
|
|
|
left.bv_len -= sub->sa_initial->bv_len;
|
2000-05-28 09:18:53 +08:00
|
|
|
inlen -= sub->sa_initial->bv_len;
|
2000-06-16 03:56:51 +08:00
|
|
|
}
|
2000-06-16 03:32:24 +08:00
|
|
|
|
2000-06-16 03:56:51 +08:00
|
|
|
if( sub->sa_final ) {
|
2000-06-16 03:32:24 +08:00
|
|
|
if( inlen > left.bv_len ) {
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
2000-05-28 07:08:28 +08:00
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
match = strncmp( sub->sa_final->bv_val,
|
|
|
|
&left.bv_val[left.bv_len - sub->sa_final->bv_len],
|
|
|
|
sub->sa_final->bv_len );
|
2000-05-28 07:08:28 +08:00
|
|
|
|
|
|
|
if( match != 0 ) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
left.bv_len -= sub->sa_final->bv_len;
|
2000-06-16 03:32:24 +08:00
|
|
|
inlen -= sub->sa_final->bv_len;
|
2000-05-28 07:08:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if( sub->sa_any ) {
|
2000-05-28 09:18:53 +08:00
|
|
|
for(i=0; sub->sa_any[i]; i++) {
|
|
|
|
ber_len_t idx;
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
retry:
|
2000-06-16 03:56:51 +08:00
|
|
|
if( inlen > left.bv_len ) {
|
|
|
|
/* not enough length */
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2000-05-28 09:18:53 +08:00
|
|
|
if( sub->sa_any[i]->bv_len == 0 ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
|
2000-05-28 09:18:53 +08:00
|
|
|
|
|
|
|
if( p == NULL ) {
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
idx = p - left.bv_val;
|
|
|
|
assert( idx < left.bv_len );
|
|
|
|
|
|
|
|
if( idx >= left.bv_len ) {
|
|
|
|
/* this shouldn't happen */
|
2001-11-07 06:36:28 +08:00
|
|
|
free( nav );
|
|
|
|
ch_free( sub->sa_final );
|
|
|
|
ber_bvecfree( sub->sa_any );
|
|
|
|
ch_free( sub->sa_initial );
|
|
|
|
ch_free( sub );
|
2000-05-28 09:18:53 +08:00
|
|
|
return LDAP_OTHER;
|
|
|
|
}
|
|
|
|
|
|
|
|
left.bv_val = p;
|
|
|
|
left.bv_len -= idx;
|
|
|
|
|
|
|
|
if( sub->sa_any[i]->bv_len > left.bv_len ) {
|
|
|
|
/* not enough left */
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
match = strncmp( left.bv_val,
|
|
|
|
sub->sa_any[i]->bv_val,
|
|
|
|
sub->sa_any[i]->bv_len );
|
2000-05-28 09:18:53 +08:00
|
|
|
|
|
|
|
if( match != 0 ) {
|
2000-09-08 07:46:07 +08:00
|
|
|
left.bv_val++;
|
|
|
|
left.bv_len--;
|
2000-05-28 09:18:53 +08:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
|
|
|
|
left.bv_val += sub->sa_any[i]->bv_len;
|
|
|
|
left.bv_len -= sub->sa_any[i]->bv_len;
|
2000-06-16 03:32:24 +08:00
|
|
|
inlen -= sub->sa_any[i]->bv_len;
|
2000-05-28 09:18:53 +08:00
|
|
|
}
|
2000-05-28 07:08:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
2001-07-18 03:35:23 +08:00
|
|
|
free( nav );
|
|
|
|
if( sub != NULL ) {
|
2001-11-07 03:07:15 +08:00
|
|
|
ber_bvfree( sub->sa_final );
|
2001-07-18 03:35:23 +08:00
|
|
|
ber_bvecfree( sub->sa_any );
|
2001-11-07 03:07:15 +08:00
|
|
|
ber_bvfree( sub->sa_initial );
|
2001-07-18 03:35:23 +08:00
|
|
|
ch_free( sub );
|
|
|
|
}
|
2000-05-28 07:08:28 +08:00
|
|
|
*matchp = match;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-06-21 09:12:29 +08:00
|
|
|
/* Index generation function */
|
2001-07-28 06:54:43 +08:00
|
|
|
int caseExactIgnoreIndexer(
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
2000-06-21 09:12:29 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
struct berval **values,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
int i;
|
2001-07-28 06:54:43 +08:00
|
|
|
char casefold;
|
2000-06-21 09:12:29 +08:00
|
|
|
size_t slen, mlen;
|
|
|
|
struct berval **keys;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
2001-01-18 00:35:53 +08:00
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-06-21 09:12:29 +08:00
|
|
|
struct berval digest;
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-06-21 09:12:29 +08:00
|
|
|
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
2001-07-26 09:08:00 +08:00
|
|
|
/* empty - just count them */
|
2000-06-21 09:12:29 +08:00
|
|
|
}
|
|
|
|
|
2001-07-26 09:08:00 +08:00
|
|
|
/* we should have at least one value at this point */
|
|
|
|
assert( i > 0 );
|
|
|
|
|
2000-06-21 09:12:29 +08:00
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
|
|
|
|
|
|
|
|
slen = strlen( syntax->ssyn_oid );
|
|
|
|
mlen = strlen( mr->smr_oid );
|
|
|
|
|
2001-07-28 06:54:43 +08:00
|
|
|
casefold = strcmp( mr->smr_oid, caseExactMatchOID )
|
|
|
|
? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
|
|
|
|
|
2000-06-21 09:12:29 +08:00
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
2001-01-26 23:56:29 +08:00
|
|
|
struct berval *value;
|
2001-11-10 03:01:23 +08:00
|
|
|
value = ber_bvstr( UTF8normalize( values[i],
|
2001-07-28 06:54:43 +08:00
|
|
|
casefold ) );
|
2000-06-21 09:12:29 +08:00
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-06-21 09:12:29 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-21 09:12:29 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-21 09:12:29 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-21 09:12:29 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-21 09:12:29 +08:00
|
|
|
value->bv_val, value->bv_len );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-06-21 09:12:29 +08:00
|
|
|
|
2001-01-26 23:56:29 +08:00
|
|
|
ber_bvfree( value );
|
|
|
|
|
2000-06-21 09:12:29 +08:00
|
|
|
keys[i] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
|
|
|
keys[i] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Index generation function */
|
2001-07-28 06:54:43 +08:00
|
|
|
int caseExactIgnoreFilter(
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
2000-06-21 09:12:29 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
void * assertValue,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
2001-07-28 06:54:43 +08:00
|
|
|
char casefold;
|
2000-06-21 09:12:29 +08:00
|
|
|
size_t slen, mlen;
|
|
|
|
struct berval **keys;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
2001-01-18 00:35:53 +08:00
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-06-21 09:12:29 +08:00
|
|
|
struct berval *value;
|
|
|
|
struct berval digest;
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-06-21 09:12:29 +08:00
|
|
|
|
|
|
|
slen = strlen( syntax->ssyn_oid );
|
|
|
|
mlen = strlen( mr->smr_oid );
|
|
|
|
|
2001-07-28 06:54:43 +08:00
|
|
|
casefold = strcmp( mr->smr_oid, caseExactMatchOID )
|
|
|
|
? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
|
|
|
|
|
2001-11-10 03:01:23 +08:00
|
|
|
value = ber_bvstr( UTF8normalize( ((struct berval *) assertValue),
|
2001-07-28 06:54:43 +08:00
|
|
|
casefold ) );
|
2001-07-16 01:25:49 +08:00
|
|
|
/* This usually happens if filter contains bad UTF8 */
|
|
|
|
if( value == NULL ) {
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) );
|
|
|
|
keys[0] = NULL;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2000-06-21 09:12:29 +08:00
|
|
|
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * 2 );
|
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-06-21 09:12:29 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-21 09:12:29 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-21 09:12:29 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-21 09:12:29 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-21 09:12:29 +08:00
|
|
|
value->bv_val, value->bv_len );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-06-21 09:12:29 +08:00
|
|
|
|
|
|
|
keys[0] = ber_bvdup( &digest );
|
|
|
|
keys[1] = NULL;
|
|
|
|
|
2001-01-26 23:56:29 +08:00
|
|
|
ber_bvfree( value );
|
|
|
|
|
2000-06-21 09:12:29 +08:00
|
|
|
*keysp = keys;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2000-08-22 10:23:52 +08:00
|
|
|
|
2000-07-19 01:46:34 +08:00
|
|
|
/* Substrings Index generation function */
|
2001-07-28 06:54:43 +08:00
|
|
|
int caseExactIgnoreSubstringsIndexer(
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
2000-07-19 01:46:34 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
struct berval **values,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
2001-07-28 06:54:43 +08:00
|
|
|
char casefold;
|
2000-08-22 10:23:52 +08:00
|
|
|
ber_len_t i, nkeys;
|
2000-07-19 01:46:34 +08:00
|
|
|
size_t slen, mlen;
|
|
|
|
struct berval **keys;
|
2001-07-22 07:02:06 +08:00
|
|
|
struct berval **nvalues;
|
2001-07-16 05:28:07 +08:00
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
2001-01-18 00:35:53 +08:00
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-07-19 01:46:34 +08:00
|
|
|
struct berval digest;
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-07-19 01:46:34 +08:00
|
|
|
|
|
|
|
nkeys=0;
|
2001-07-16 05:28:07 +08:00
|
|
|
|
2001-07-22 07:02:06 +08:00
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
2001-07-26 09:08:00 +08:00
|
|
|
/* empty - just count them */
|
2001-07-22 07:02:06 +08:00
|
|
|
}
|
2001-07-26 09:08:00 +08:00
|
|
|
|
|
|
|
/* we should have at least one value at this point */
|
|
|
|
assert( i > 0 );
|
|
|
|
|
2001-07-28 06:54:43 +08:00
|
|
|
casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
|
|
|
|
? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
|
|
|
|
|
2001-07-22 07:02:06 +08:00
|
|
|
nvalues = ch_malloc( sizeof( struct berval * ) * (i+1) );
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
2001-11-10 03:01:23 +08:00
|
|
|
nvalues[i] = ber_bvstr( UTF8normalize( values[i],
|
2001-07-28 06:54:43 +08:00
|
|
|
casefold ) );
|
2001-07-22 07:02:06 +08:00
|
|
|
}
|
|
|
|
nvalues[i] = NULL;
|
|
|
|
values = nvalues;
|
2001-07-16 05:28:07 +08:00
|
|
|
|
2000-07-19 01:46:34 +08:00
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
|
|
|
/* count number of indices to generate */
|
2000-09-08 07:46:07 +08:00
|
|
|
if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
|
2000-07-19 01:46:34 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
|
2000-09-08 07:46:07 +08:00
|
|
|
if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
|
2000-08-22 10:23:52 +08:00
|
|
|
nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
|
2000-09-08 07:46:07 +08:00
|
|
|
( SLAP_INDEX_SUBSTR_MINLEN - 1);
|
2000-08-22 10:23:52 +08:00
|
|
|
} else {
|
2000-09-08 07:46:07 +08:00
|
|
|
nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
|
2000-08-22 10:23:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_ANY ) {
|
2000-09-08 07:46:07 +08:00
|
|
|
if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
|
|
|
|
nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
|
2000-08-22 10:23:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
|
2000-09-08 07:46:07 +08:00
|
|
|
if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
|
2000-08-22 10:23:52 +08:00
|
|
|
nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
|
2000-09-08 07:46:07 +08:00
|
|
|
( SLAP_INDEX_SUBSTR_MINLEN - 1);
|
2000-08-22 10:23:52 +08:00
|
|
|
} else {
|
2000-09-08 07:46:07 +08:00
|
|
|
nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
|
2000-08-22 10:23:52 +08:00
|
|
|
}
|
2000-07-19 01:46:34 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nkeys == 0 ) {
|
|
|
|
/* no keys to generate */
|
|
|
|
*keysp = NULL;
|
2001-11-07 06:36:28 +08:00
|
|
|
ber_bvecfree( nvalues );
|
2000-07-19 01:46:34 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
|
|
|
|
|
|
|
|
slen = strlen( syntax->ssyn_oid );
|
|
|
|
mlen = strlen( mr->smr_oid );
|
|
|
|
|
|
|
|
nkeys=0;
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
2000-08-22 10:23:52 +08:00
|
|
|
ber_len_t j,max;
|
2000-07-19 01:46:34 +08:00
|
|
|
struct berval *value;
|
|
|
|
|
2001-01-26 23:56:29 +08:00
|
|
|
if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
|
|
|
|
|
2000-08-22 07:20:26 +08:00
|
|
|
value = values[i];
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
|
2000-09-08 07:46:07 +08:00
|
|
|
( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
|
2000-08-22 10:23:52 +08:00
|
|
|
{
|
|
|
|
char pre = SLAP_INDEX_SUBSTR_PREFIX;
|
2000-09-08 07:46:07 +08:00
|
|
|
max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
|
2000-08-22 10:23:52 +08:00
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
for( j=0; j<max; j++ ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-08-22 10:23:52 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-08 07:46:07 +08:00
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-08 07:46:07 +08:00
|
|
|
&value->bv_val[j],
|
|
|
|
SLAP_INDEX_SUBSTR_MAXLEN );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-08-22 10:23:52 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
|
|
|
|
? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
|
2000-07-19 01:46:34 +08:00
|
|
|
char pre;
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
|
2000-07-19 01:46:34 +08:00
|
|
|
pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
value->bv_val, j );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
|
2000-07-19 01:46:34 +08:00
|
|
|
pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
&value->bv_val[value->bv_len-j], j );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2001-01-26 23:56:29 +08:00
|
|
|
|
2000-07-19 01:46:34 +08:00
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( nkeys > 0 ) {
|
|
|
|
keys[nkeys] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
} else {
|
|
|
|
ch_free( keys );
|
|
|
|
*keysp = NULL;
|
|
|
|
}
|
|
|
|
|
2001-07-16 05:28:07 +08:00
|
|
|
ber_bvecfree( nvalues );
|
|
|
|
|
2000-07-19 01:46:34 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2000-06-21 09:12:29 +08:00
|
|
|
|
2001-07-28 06:54:43 +08:00
|
|
|
int caseExactIgnoreSubstringsFilter(
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
2000-07-19 01:46:34 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
void * assertValue,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
2001-07-17 06:48:52 +08:00
|
|
|
SubstringsAssertion *sa;
|
2001-07-28 06:54:43 +08:00
|
|
|
char pre, casefold;
|
2000-08-22 10:23:52 +08:00
|
|
|
ber_len_t nkeys = 0;
|
2000-07-19 01:46:34 +08:00
|
|
|
size_t slen, mlen, klen;
|
|
|
|
struct berval **keys;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
2001-01-18 00:35:53 +08:00
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-07-19 01:46:34 +08:00
|
|
|
struct berval *value;
|
|
|
|
struct berval digest;
|
|
|
|
|
2001-07-28 06:54:43 +08:00
|
|
|
casefold = strcmp( mr->smr_oid, caseExactSubstringsMatchOID )
|
|
|
|
? UTF8_CASEFOLD : UTF8_NOCASEFOLD;
|
|
|
|
|
|
|
|
sa = UTF8SubstringsassertionNormalize( assertValue, casefold );
|
2001-07-17 06:48:52 +08:00
|
|
|
if( sa == NULL ) {
|
2001-07-22 07:02:06 +08:00
|
|
|
*keysp = NULL;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2001-07-17 06:48:52 +08:00
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
|
2000-09-08 07:46:07 +08:00
|
|
|
sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
|
2000-07-19 01:46:34 +08:00
|
|
|
{
|
|
|
|
nkeys++;
|
|
|
|
}
|
2000-08-22 10:23:52 +08:00
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
|
2000-08-22 10:23:52 +08:00
|
|
|
ber_len_t i;
|
|
|
|
for( i=0; sa->sa_any[i] != NULL; i++ ) {
|
2000-09-08 07:46:07 +08:00
|
|
|
if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
|
2000-08-22 10:23:52 +08:00
|
|
|
/* don't bother accounting for stepping */
|
2000-09-08 07:46:07 +08:00
|
|
|
nkeys += sa->sa_any[i]->bv_len -
|
2000-08-22 10:23:52 +08:00
|
|
|
( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
|
2000-09-08 07:46:07 +08:00
|
|
|
sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
|
2000-07-19 01:46:34 +08:00
|
|
|
{
|
|
|
|
nkeys++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nkeys == 0 ) {
|
2001-11-07 03:07:15 +08:00
|
|
|
ber_bvfree( sa->sa_final );
|
2001-11-06 07:14:42 +08:00
|
|
|
ber_bvecfree( sa->sa_any );
|
2001-11-07 03:07:15 +08:00
|
|
|
ber_bvfree( sa->sa_initial );
|
2001-11-06 07:14:42 +08:00
|
|
|
ch_free( sa );
|
2000-07-19 01:46:34 +08:00
|
|
|
*keysp = NULL;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-07-19 01:46:34 +08:00
|
|
|
|
|
|
|
slen = strlen( syntax->ssyn_oid );
|
|
|
|
mlen = strlen( mr->smr_oid );
|
|
|
|
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
|
|
|
|
nkeys = 0;
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
|
2000-09-08 07:46:07 +08:00
|
|
|
sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
|
2000-07-19 01:46:34 +08:00
|
|
|
{
|
|
|
|
pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
|
|
|
|
value = sa->sa_initial;
|
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
|
|
|
|
? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
value->bv_val, klen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
|
2000-08-22 10:23:52 +08:00
|
|
|
ber_len_t i, j;
|
|
|
|
pre = SLAP_INDEX_SUBSTR_PREFIX;
|
2000-09-08 07:46:07 +08:00
|
|
|
klen = SLAP_INDEX_SUBSTR_MAXLEN;
|
2000-08-22 10:23:52 +08:00
|
|
|
|
|
|
|
for( i=0; sa->sa_any[i] != NULL; i++ ) {
|
2000-09-08 07:46:07 +08:00
|
|
|
if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
|
2000-08-22 10:23:52 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
value = sa->sa_any[i];
|
|
|
|
|
2000-08-23 06:34:37 +08:00
|
|
|
for(j=0;
|
2000-09-08 07:46:07 +08:00
|
|
|
j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
|
|
|
|
j += SLAP_INDEX_SUBSTR_STEP )
|
2000-08-23 06:34:37 +08:00
|
|
|
{
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-08-22 10:23:52 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-08 07:46:07 +08:00
|
|
|
&value->bv_val[j], klen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-08-22 10:23:52 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
2001-01-26 23:56:29 +08:00
|
|
|
|
2000-08-22 10:23:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
|
2000-09-08 07:46:07 +08:00
|
|
|
sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
|
2000-07-19 01:46:34 +08:00
|
|
|
{
|
|
|
|
pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
|
|
|
|
value = sa->sa_final;
|
|
|
|
|
2000-09-08 07:46:07 +08:00
|
|
|
klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
|
|
|
|
? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
&value->bv_val[value->bv_len-klen], klen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( nkeys > 0 ) {
|
|
|
|
keys[nkeys] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
} else {
|
|
|
|
ch_free( keys );
|
|
|
|
*keysp = NULL;
|
|
|
|
}
|
2001-11-07 03:07:15 +08:00
|
|
|
ber_bvfree( sa->sa_final );
|
2001-07-17 06:48:52 +08:00
|
|
|
ber_bvecfree( sa->sa_any );
|
2001-11-07 03:07:15 +08:00
|
|
|
ber_bvfree( sa->sa_initial );
|
2001-07-17 06:48:52 +08:00
|
|
|
ch_free( sa );
|
2000-07-19 01:46:34 +08:00
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2001-07-28 06:54:43 +08:00
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
static int
|
2000-09-04 02:04:08 +08:00
|
|
|
caseIgnoreMatch(
|
2000-06-20 11:55:40 +08:00
|
|
|
int *matchp,
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t flags,
|
2000-01-30 03:43:19 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
2000-02-15 04:57:34 +08:00
|
|
|
void *assertedValue )
|
2000-01-30 03:43:19 +08:00
|
|
|
{
|
2001-01-31 23:58:00 +08:00
|
|
|
*matchp = UTF8normcmp( value->bv_val,
|
2001-07-16 01:25:49 +08:00
|
|
|
((struct berval *) assertedValue)->bv_val,
|
|
|
|
UTF8_CASEFOLD );
|
2000-05-25 02:49:30 +08:00
|
|
|
return LDAP_SUCCESS;
|
2000-01-30 03:43:19 +08:00
|
|
|
}
|
2000-09-04 02:04:08 +08:00
|
|
|
|
|
|
|
static int
|
|
|
|
oidValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val )
|
|
|
|
{
|
|
|
|
ber_len_t i;
|
|
|
|
|
2000-11-11 07:07:20 +08:00
|
|
|
if( val->bv_len == 0 ) {
|
|
|
|
/* disallow empty strings */
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2000-09-04 02:04:08 +08:00
|
|
|
|
|
|
|
if( OID_LEADCHAR(val->bv_val[0]) ) {
|
|
|
|
int dot = 0;
|
|
|
|
for(i=1; i < val->bv_len; i++) {
|
|
|
|
if( OID_SEPARATOR( val->bv_val[i] ) ) {
|
|
|
|
if( dot++ ) return 1;
|
|
|
|
} else if ( OID_CHAR( val->bv_val[i] ) ) {
|
|
|
|
dot = 0;
|
|
|
|
} else {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
|
|
|
|
|
|
|
|
} else if( DESC_LEADCHAR(val->bv_val[0]) ) {
|
|
|
|
for(i=1; i < val->bv_len; i++) {
|
|
|
|
if( !DESC_CHAR(val->bv_val[i] ) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
2001-09-20 23:50:49 +08:00
|
|
|
static int
|
|
|
|
integerMatch(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
char *v, *av;
|
|
|
|
int vsign=0, avsign=0;
|
|
|
|
struct berval *asserted;
|
|
|
|
ber_len_t vlen, avlen;
|
|
|
|
|
|
|
|
|
|
|
|
/* Start off pessimistic */
|
|
|
|
*matchp = 1;
|
|
|
|
|
|
|
|
/* Skip past leading spaces/zeros, 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--;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Skip past leading spaces/zeros, and get the sign of 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 == '-' ) {
|
|
|
|
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;
|
|
|
|
|
|
|
|
/* Check the significant digits */
|
|
|
|
while( vlen && avlen ) {
|
|
|
|
if( *v != *av ) break;
|
|
|
|
v++;
|
|
|
|
vlen--;
|
|
|
|
av++;
|
|
|
|
avlen--;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If all digits compared equal, the numbers are equal */
|
|
|
|
if(( vlen == 0 ) && ( avlen == 0 )) {
|
|
|
|
*matchp = 0;
|
|
|
|
}
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
static int
|
|
|
|
integerValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val )
|
|
|
|
{
|
|
|
|
ber_len_t i;
|
|
|
|
|
|
|
|
if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
|
|
|
|
|
2001-09-20 23:50:49 +08:00
|
|
|
if(( val->bv_val[0] == '+' ) || ( val->bv_val[0] == '-' )) {
|
2000-09-12 08:00:25 +08:00
|
|
|
if( val->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
|
|
|
|
} else if( !ASCII_DIGIT(val->bv_val[0]) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
2001-09-20 23:50:49 +08:00
|
|
|
for( i=1; i < val->bv_len; i++ ) {
|
2000-09-04 02:04:08 +08:00
|
|
|
if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-09-12 02:34:14 +08:00
|
|
|
static int
|
2000-09-12 08:00:25 +08:00
|
|
|
integerNormalize(
|
2000-09-12 02:34:14 +08:00
|
|
|
Syntax *syntax,
|
2000-09-12 08:00:25 +08:00
|
|
|
struct berval *val,
|
|
|
|
struct berval **normalized )
|
2000-09-12 02:34:14 +08:00
|
|
|
{
|
2000-09-12 08:38:47 +08:00
|
|
|
char *p;
|
2001-09-20 23:50:49 +08:00
|
|
|
int negative=0;
|
|
|
|
struct berval *newval;
|
|
|
|
ber_len_t len;
|
|
|
|
|
2000-09-12 02:34:14 +08:00
|
|
|
|
2000-09-12 08:00:25 +08:00
|
|
|
p = val->bv_val;
|
2001-09-20 23:50:49 +08:00
|
|
|
len = val->bv_len;
|
|
|
|
|
|
|
|
/* Ignore leading spaces */
|
|
|
|
while ( len && ( *p == ' ' )) {
|
|
|
|
p++;
|
|
|
|
len--;
|
|
|
|
}
|
2000-09-12 02:34:14 +08:00
|
|
|
|
2000-09-12 08:00:25 +08:00
|
|
|
/* save sign */
|
2001-09-20 23:50:49 +08:00
|
|
|
if( len ) {
|
|
|
|
negative = ( *p == '-' );
|
|
|
|
if(( *p == '-' ) || ( *p == '+' )) {
|
|
|
|
p++;
|
|
|
|
len--;
|
|
|
|
}
|
|
|
|
}
|
2000-09-12 02:34:14 +08:00
|
|
|
|
2000-09-12 08:00:25 +08:00
|
|
|
/* Ignore leading zeros */
|
2001-09-20 23:50:49 +08:00
|
|
|
while ( len && ( *p == '0' )) {
|
|
|
|
p++;
|
|
|
|
len--;
|
|
|
|
}
|
2000-09-12 02:34:14 +08:00
|
|
|
|
2000-09-12 08:00:25 +08:00
|
|
|
newval = (struct berval *) ch_malloc( sizeof(struct berval) );
|
2000-09-12 02:34:14 +08:00
|
|
|
|
2001-09-20 23:50:49 +08:00
|
|
|
/* If there are no non-zero digits left, the number is zero, otherwise
|
|
|
|
allocate space for the number and copy it into the buffer */
|
|
|
|
if( len == 0 ) {
|
2000-09-12 08:00:25 +08:00
|
|
|
newval->bv_val = ch_strdup("0");
|
|
|
|
newval->bv_len = 1;
|
2001-09-20 23:50:49 +08:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
newval->bv_len = len+negative;
|
|
|
|
newval->bv_val = ch_malloc( newval->bv_len );
|
|
|
|
if( negative ) {
|
|
|
|
newval->bv_val[0] = '-';
|
|
|
|
}
|
|
|
|
memcpy( newval->bv_val + negative, p, len );
|
2000-09-12 02:34:14 +08:00
|
|
|
}
|
|
|
|
|
2001-09-20 23:50:49 +08:00
|
|
|
*normalized = newval;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2000-09-12 02:34:14 +08:00
|
|
|
|
2001-09-20 23:50:49 +08:00
|
|
|
/* Index generation function */
|
|
|
|
int integerIndexer(
|
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
struct berval **values,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct berval **keys;
|
|
|
|
|
|
|
|
/* we should have at least one value at this point */
|
|
|
|
assert( values != NULL && values[0] != NULL );
|
|
|
|
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
|
|
|
/* empty -- just count them */
|
2000-09-12 02:34:14 +08:00
|
|
|
}
|
|
|
|
|
2001-09-20 23:50:49 +08:00
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
|
|
|
|
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
|
|
|
integerNormalize( syntax, values[i], &keys[i] );
|
2000-09-12 02:34:14 +08:00
|
|
|
}
|
|
|
|
|
2001-09-20 23:50:49 +08:00
|
|
|
keys[i] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Index generation function */
|
|
|
|
int integerFilter(
|
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
void * assertValue,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
struct berval **keys;
|
|
|
|
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * 2 );
|
|
|
|
integerNormalize( syntax, assertValue, &keys[0] );
|
|
|
|
keys[1] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
|
2000-09-12 02:34:14 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2001-09-20 23:50:49 +08:00
|
|
|
|
2000-11-05 05:09:23 +08:00
|
|
|
static int
|
|
|
|
countryStringValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val )
|
|
|
|
{
|
|
|
|
if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
|
|
|
|
|
|
|
|
if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
static int
|
|
|
|
printableStringValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val )
|
|
|
|
{
|
|
|
|
ber_len_t i;
|
|
|
|
|
|
|
|
if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
|
|
|
|
|
|
|
|
for(i=0; i < val->bv_len; i++) {
|
2000-11-05 04:31:50 +08:00
|
|
|
if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
2000-09-04 02:04:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-11-05 05:09:23 +08:00
|
|
|
static int
|
|
|
|
printablesStringValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val )
|
|
|
|
{
|
|
|
|
ber_len_t i;
|
|
|
|
|
|
|
|
if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
|
|
|
|
|
|
|
|
for(i=0; i < val->bv_len; i++) {
|
|
|
|
if( !SLAP_PRINTABLES(val->bv_val[i]) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
static int
|
|
|
|
IA5StringValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val )
|
|
|
|
{
|
|
|
|
ber_len_t i;
|
|
|
|
|
|
|
|
if( !val->bv_len ) return LDAP_INVALID_SYNTAX;
|
|
|
|
|
|
|
|
for(i=0; i < val->bv_len; i++) {
|
|
|
|
if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
IA5StringNormalize(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val,
|
|
|
|
struct berval **normalized )
|
|
|
|
{
|
|
|
|
struct berval *newval;
|
|
|
|
char *p, *q;
|
|
|
|
|
|
|
|
newval = ch_malloc( sizeof( struct berval ) );
|
|
|
|
|
|
|
|
p = val->bv_val;
|
|
|
|
|
|
|
|
/* Ignore initial whitespace */
|
|
|
|
while ( ASCII_SPACE( *p ) ) {
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( *p == '\0' ) {
|
|
|
|
ch_free( newval );
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
newval->bv_val = ch_strdup( p );
|
|
|
|
p = q = newval->bv_val;
|
|
|
|
|
|
|
|
while ( *p ) {
|
|
|
|
if ( ASCII_SPACE( *p ) ) {
|
|
|
|
*q++ = *p++;
|
|
|
|
|
|
|
|
/* Ignore the extra whitespace */
|
|
|
|
while ( ASCII_SPACE( *p ) ) {
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
*q++ = *p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assert( *newval->bv_val );
|
|
|
|
assert( newval->bv_val < p );
|
2000-09-13 09:23:39 +08:00
|
|
|
assert( q <= p );
|
2000-09-04 02:04:08 +08:00
|
|
|
|
|
|
|
/* cannot start with a space */
|
|
|
|
assert( !ASCII_SPACE(*newval->bv_val) );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the string ended in space, backup the pointer one
|
|
|
|
* position. One is enough because the above loop collapsed
|
|
|
|
* all whitespace to a single space.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if ( ASCII_SPACE( q[-1] ) ) {
|
|
|
|
--q;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* cannot end with a space */
|
|
|
|
assert( !ASCII_SPACE( q[-1] ) );
|
|
|
|
|
|
|
|
/* null terminate */
|
|
|
|
*q = '\0';
|
|
|
|
|
|
|
|
newval->bv_len = q - newval->bv_val;
|
|
|
|
*normalized = newval;
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
caseExactIA5Match(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
|
|
|
|
|
|
|
|
if( match == 0 ) {
|
|
|
|
match = strncmp( value->bv_val,
|
|
|
|
((struct berval *) assertedValue)->bv_val,
|
|
|
|
value->bv_len );
|
|
|
|
}
|
|
|
|
|
|
|
|
*matchp = match;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
caseExactIA5SubstringsMatch(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
int match = 0;
|
|
|
|
SubstringsAssertion *sub = assertedValue;
|
|
|
|
struct berval left = *value;
|
|
|
|
int i;
|
|
|
|
ber_len_t inlen=0;
|
|
|
|
|
|
|
|
/* Add up asserted input length */
|
|
|
|
if( sub->sa_initial ) {
|
|
|
|
inlen += sub->sa_initial->bv_len;
|
|
|
|
}
|
|
|
|
if( sub->sa_any ) {
|
|
|
|
for(i=0; sub->sa_any[i] != NULL; i++) {
|
|
|
|
inlen += sub->sa_any[i]->bv_len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( sub->sa_final ) {
|
|
|
|
inlen += sub->sa_final->bv_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( sub->sa_initial ) {
|
|
|
|
if( inlen > left.bv_len ) {
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
match = strncmp( sub->sa_initial->bv_val, left.bv_val,
|
|
|
|
sub->sa_initial->bv_len );
|
|
|
|
|
|
|
|
if( match != 0 ) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
left.bv_val += sub->sa_initial->bv_len;
|
|
|
|
left.bv_len -= sub->sa_initial->bv_len;
|
|
|
|
inlen -= sub->sa_initial->bv_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( sub->sa_final ) {
|
|
|
|
if( inlen > left.bv_len ) {
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
match = strncmp( sub->sa_final->bv_val,
|
|
|
|
&left.bv_val[left.bv_len - sub->sa_final->bv_len],
|
|
|
|
sub->sa_final->bv_len );
|
|
|
|
|
|
|
|
if( match != 0 ) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
left.bv_len -= sub->sa_final->bv_len;
|
|
|
|
inlen -= sub->sa_final->bv_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( sub->sa_any ) {
|
|
|
|
for(i=0; sub->sa_any[i]; i++) {
|
|
|
|
ber_len_t idx;
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
retry:
|
|
|
|
if( inlen > left.bv_len ) {
|
|
|
|
/* not enough length */
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( sub->sa_any[i]->bv_len == 0 ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
p = strchr( left.bv_val, *sub->sa_any[i]->bv_val );
|
|
|
|
|
|
|
|
if( p == NULL ) {
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
idx = p - left.bv_val;
|
|
|
|
assert( idx < left.bv_len );
|
|
|
|
|
|
|
|
if( idx >= left.bv_len ) {
|
|
|
|
/* this shouldn't happen */
|
|
|
|
return LDAP_OTHER;
|
|
|
|
}
|
|
|
|
|
|
|
|
left.bv_val = p;
|
|
|
|
left.bv_len -= idx;
|
|
|
|
|
|
|
|
if( sub->sa_any[i]->bv_len > left.bv_len ) {
|
|
|
|
/* not enough left */
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
match = strncmp( left.bv_val,
|
|
|
|
sub->sa_any[i]->bv_val,
|
|
|
|
sub->sa_any[i]->bv_len );
|
|
|
|
|
|
|
|
if( match != 0 ) {
|
|
|
|
left.bv_val++;
|
|
|
|
left.bv_len--;
|
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
|
|
|
|
left.bv_val += sub->sa_any[i]->bv_len;
|
|
|
|
left.bv_len -= sub->sa_any[i]->bv_len;
|
|
|
|
inlen -= sub->sa_any[i]->bv_len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
*matchp = match;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Index generation function */
|
|
|
|
int caseExactIA5Indexer(
|
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
struct berval **values,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
size_t slen, mlen;
|
|
|
|
struct berval **keys;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
2001-01-18 00:35:53 +08:00
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-09-04 02:04:08 +08:00
|
|
|
struct berval digest;
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-09-04 02:04:08 +08:00
|
|
|
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
2001-07-26 09:08:00 +08:00
|
|
|
/* empty - just count them */
|
2000-09-04 02:04:08 +08:00
|
|
|
}
|
|
|
|
|
2001-07-26 09:08:00 +08:00
|
|
|
/* we should have at least one value at this point */
|
|
|
|
assert( i > 0 );
|
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
|
|
|
|
|
|
|
|
slen = strlen( syntax->ssyn_oid );
|
|
|
|
mlen = strlen( mr->smr_oid );
|
|
|
|
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
|
|
|
struct berval *value = values[i];
|
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
value->bv_val, value->bv_len );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
|
|
|
|
keys[i] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
|
|
|
keys[i] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Index generation function */
|
|
|
|
int caseExactIA5Filter(
|
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
void * assertValue,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
size_t slen, mlen;
|
|
|
|
struct berval **keys;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
2001-01-18 00:35:53 +08:00
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-09-04 02:04:08 +08:00
|
|
|
struct berval *value;
|
|
|
|
struct berval digest;
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-09-04 02:04:08 +08:00
|
|
|
|
|
|
|
slen = strlen( syntax->ssyn_oid );
|
|
|
|
mlen = strlen( mr->smr_oid );
|
|
|
|
|
|
|
|
value = (struct berval *) assertValue;
|
|
|
|
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * 2 );
|
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
value->bv_val, value->bv_len );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
|
|
|
|
keys[0] = ber_bvdup( &digest );
|
|
|
|
keys[1] = NULL;
|
|
|
|
|
|
|
|
*keysp = keys;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Substrings Index generation function */
|
|
|
|
int caseExactIA5SubstringsIndexer(
|
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
struct berval **values,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
ber_len_t i, nkeys;
|
|
|
|
size_t slen, mlen;
|
|
|
|
struct berval **keys;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
2001-01-18 00:35:53 +08:00
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-09-04 02:04:08 +08:00
|
|
|
struct berval digest;
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-09-04 02:04:08 +08:00
|
|
|
|
2000-09-15 11:26:22 +08:00
|
|
|
/* we should have at least one value at this point */
|
|
|
|
assert( values != NULL && values[0] != NULL );
|
|
|
|
|
2000-09-04 02:04:08 +08:00
|
|
|
nkeys=0;
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
|
|
|
/* count number of indices to generate */
|
|
|
|
if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
|
|
|
|
if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
|
|
|
|
nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
|
|
|
|
( SLAP_INDEX_SUBSTR_MINLEN - 1);
|
|
|
|
} else {
|
|
|
|
nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( flags & SLAP_INDEX_SUBSTR_ANY ) {
|
|
|
|
if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
|
|
|
|
nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
|
|
|
|
if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
|
|
|
|
nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
|
|
|
|
( SLAP_INDEX_SUBSTR_MINLEN - 1);
|
|
|
|
} else {
|
|
|
|
nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nkeys == 0 ) {
|
|
|
|
/* no keys to generate */
|
|
|
|
*keysp = NULL;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
|
|
|
|
|
|
|
|
slen = strlen( syntax->ssyn_oid );
|
|
|
|
mlen = strlen( mr->smr_oid );
|
|
|
|
|
|
|
|
nkeys=0;
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
|
|
|
ber_len_t j,max;
|
|
|
|
struct berval *value;
|
|
|
|
|
|
|
|
value = values[i];
|
|
|
|
if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
|
|
|
|
|
|
|
|
if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
|
|
|
|
( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
|
|
|
|
{
|
|
|
|
char pre = SLAP_INDEX_SUBSTR_PREFIX;
|
|
|
|
max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
|
|
|
|
|
|
|
|
for( j=0; j<max; j++ ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-08 07:46:07 +08:00
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
&value->bv_val[j],
|
|
|
|
SLAP_INDEX_SUBSTR_MAXLEN );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
|
|
|
|
? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
|
|
|
|
|
|
|
|
for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
|
|
|
|
char pre;
|
|
|
|
|
|
|
|
if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
|
|
|
|
pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
value->bv_val, j );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
|
|
|
|
pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
&value->bv_val[value->bv_len-j], j );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nkeys > 0 ) {
|
|
|
|
keys[nkeys] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
} else {
|
|
|
|
ch_free( keys );
|
|
|
|
*keysp = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int caseExactIA5SubstringsFilter(
|
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
void * assertValue,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
SubstringsAssertion *sa = assertValue;
|
|
|
|
char pre;
|
|
|
|
ber_len_t nkeys = 0;
|
|
|
|
size_t slen, mlen, klen;
|
|
|
|
struct berval **keys;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
2001-01-18 00:35:53 +08:00
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-09-04 02:04:08 +08:00
|
|
|
struct berval *value;
|
|
|
|
struct berval digest;
|
|
|
|
|
|
|
|
if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
|
|
|
|
sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
|
|
|
|
{
|
|
|
|
nkeys++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
|
|
|
|
ber_len_t i;
|
|
|
|
for( i=0; sa->sa_any[i] != NULL; i++ ) {
|
|
|
|
if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
|
|
|
|
/* don't bother accounting for stepping */
|
|
|
|
nkeys += sa->sa_any[i]->bv_len -
|
|
|
|
( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
|
|
|
|
sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
|
|
|
|
{
|
|
|
|
nkeys++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nkeys == 0 ) {
|
|
|
|
*keysp = NULL;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-09-04 02:04:08 +08:00
|
|
|
|
|
|
|
slen = strlen( syntax->ssyn_oid );
|
|
|
|
mlen = strlen( mr->smr_oid );
|
|
|
|
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
|
|
|
|
nkeys = 0;
|
|
|
|
|
|
|
|
if( flags & SLAP_INDEX_SUBSTR_INITIAL && sa->sa_initial != NULL &&
|
|
|
|
sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
|
|
|
|
{
|
|
|
|
pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
|
|
|
|
value = sa->sa_initial;
|
|
|
|
|
|
|
|
klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
|
|
|
|
? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
|
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
value->bv_val, klen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
|
|
|
|
ber_len_t i, j;
|
|
|
|
pre = SLAP_INDEX_SUBSTR_PREFIX;
|
|
|
|
klen = SLAP_INDEX_SUBSTR_MAXLEN;
|
|
|
|
|
|
|
|
for( i=0; sa->sa_any[i] != NULL; i++ ) {
|
|
|
|
if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
value = sa->sa_any[i];
|
|
|
|
|
|
|
|
for(j=0;
|
|
|
|
j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
|
|
|
|
j += SLAP_INDEX_SUBSTR_STEP )
|
|
|
|
{
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
&value->bv_val[j], klen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( flags & SLAP_INDEX_SUBSTR_FINAL && sa->sa_final != NULL &&
|
|
|
|
sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
|
|
|
|
{
|
|
|
|
pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
|
|
|
|
value = sa->sa_final;
|
|
|
|
|
|
|
|
klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
|
|
|
|
? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
|
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-09-04 02:04:08 +08:00
|
|
|
&value->bv_val[value->bv_len-klen], klen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-09-04 02:04:08 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nkeys > 0 ) {
|
|
|
|
keys[nkeys] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
} else {
|
|
|
|
ch_free( keys );
|
|
|
|
*keysp = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
caseIgnoreIA5Match(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
int match = value->bv_len - ((struct berval *) assertedValue)->bv_len;
|
|
|
|
|
2001-01-18 05:02:11 +08:00
|
|
|
if( match == 0 && value->bv_len ) {
|
2000-09-04 02:04:08 +08:00
|
|
|
match = strncasecmp( value->bv_val,
|
|
|
|
((struct berval *) assertedValue)->bv_val,
|
|
|
|
value->bv_len );
|
|
|
|
}
|
|
|
|
|
|
|
|
*matchp = match;
|
|
|
|
return LDAP_SUCCESS;
|
2000-05-28 09:18:53 +08:00
|
|
|
}
|
|
|
|
|
2000-05-28 07:08:28 +08:00
|
|
|
static int
|
|
|
|
caseIgnoreIA5SubstringsMatch(
|
|
|
|
int *matchp,
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t flags,
|
2000-05-28 07:08:28 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
int match = 0;
|
|
|
|
SubstringsAssertion *sub = assertedValue;
|
|
|
|
struct berval left = *value;
|
|
|
|
int i;
|
|
|
|
ber_len_t inlen=0;
|
|
|
|
|
2000-06-16 03:32:24 +08:00
|
|
|
/* Add up asserted input length */
|
2000-05-28 07:08:28 +08:00
|
|
|
if( sub->sa_initial ) {
|
|
|
|
inlen += sub->sa_initial->bv_len;
|
|
|
|
}
|
|
|
|
if( sub->sa_any ) {
|
2000-06-16 03:32:24 +08:00
|
|
|
for(i=0; sub->sa_any[i] != NULL; i++) {
|
2000-06-14 14:07:06 +08:00
|
|
|
inlen += sub->sa_any[i]->bv_len;
|
2000-05-28 07:08:28 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if( sub->sa_final ) {
|
|
|
|
inlen += sub->sa_final->bv_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( sub->sa_initial ) {
|
2000-06-16 03:56:51 +08:00
|
|
|
if( inlen > left.bv_len ) {
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2000-05-28 07:08:28 +08:00
|
|
|
match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
|
|
|
|
sub->sa_initial->bv_len );
|
|
|
|
|
|
|
|
if( match != 0 ) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
left.bv_val += sub->sa_initial->bv_len;
|
|
|
|
left.bv_len -= sub->sa_initial->bv_len;
|
2000-06-16 03:32:24 +08:00
|
|
|
inlen -= sub->sa_initial->bv_len;
|
2000-06-16 03:56:51 +08:00
|
|
|
}
|
2000-06-16 03:32:24 +08:00
|
|
|
|
2000-06-16 03:56:51 +08:00
|
|
|
if( sub->sa_final ) {
|
2000-06-16 03:32:24 +08:00
|
|
|
if( inlen > left.bv_len ) {
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
2000-05-28 07:08:28 +08:00
|
|
|
|
|
|
|
match = strncasecmp( sub->sa_final->bv_val,
|
|
|
|
&left.bv_val[left.bv_len - sub->sa_final->bv_len],
|
|
|
|
sub->sa_final->bv_len );
|
|
|
|
|
|
|
|
if( match != 0 ) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
left.bv_len -= sub->sa_final->bv_len;
|
2000-06-16 03:32:24 +08:00
|
|
|
inlen -= sub->sa_final->bv_len;
|
2000-05-28 07:08:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if( sub->sa_any ) {
|
2000-05-28 09:18:53 +08:00
|
|
|
for(i=0; sub->sa_any[i]; i++) {
|
|
|
|
ber_len_t idx;
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
retry:
|
2000-06-16 03:56:51 +08:00
|
|
|
if( inlen > left.bv_len ) {
|
|
|
|
/* not enough length */
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2000-05-28 09:18:53 +08:00
|
|
|
if( sub->sa_any[i]->bv_len == 0 ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val );
|
|
|
|
|
|
|
|
if( p == NULL ) {
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
idx = p - left.bv_val;
|
|
|
|
assert( idx < left.bv_len );
|
|
|
|
|
|
|
|
if( idx >= left.bv_len ) {
|
|
|
|
/* this shouldn't happen */
|
|
|
|
return LDAP_OTHER;
|
|
|
|
}
|
|
|
|
|
|
|
|
left.bv_val = p;
|
|
|
|
left.bv_len -= idx;
|
|
|
|
|
|
|
|
if( sub->sa_any[i]->bv_len > left.bv_len ) {
|
|
|
|
/* not enough left */
|
|
|
|
match = 1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
match = strncasecmp( left.bv_val,
|
|
|
|
sub->sa_any[i]->bv_val,
|
|
|
|
sub->sa_any[i]->bv_len );
|
|
|
|
|
|
|
|
if( match != 0 ) {
|
2000-06-16 03:56:51 +08:00
|
|
|
left.bv_val++;
|
|
|
|
left.bv_len--;
|
|
|
|
|
2000-05-28 09:18:53 +08:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
|
|
|
|
left.bv_val += sub->sa_any[i]->bv_len;
|
|
|
|
left.bv_len -= sub->sa_any[i]->bv_len;
|
2000-06-16 03:32:24 +08:00
|
|
|
inlen -= sub->sa_any[i]->bv_len;
|
2000-05-28 09:18:53 +08:00
|
|
|
}
|
2000-05-28 07:08:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
*matchp = match;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2000-05-29 12:58:40 +08:00
|
|
|
|
2000-06-05 06:59:38 +08:00
|
|
|
/* Index generation function */
|
|
|
|
int caseIgnoreIA5Indexer(
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
2000-06-05 06:59:38 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
struct berval **values,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
size_t slen, mlen;
|
|
|
|
struct berval **keys;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
2001-01-18 00:35:53 +08:00
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-06-05 06:59:38 +08:00
|
|
|
struct berval digest;
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-06-05 06:59:38 +08:00
|
|
|
|
2000-09-15 11:26:22 +08:00
|
|
|
/* we should have at least one value at this point */
|
|
|
|
assert( values != NULL && values[0] != NULL );
|
|
|
|
|
2000-06-05 06:59:38 +08:00
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
|
|
|
/* just count them */
|
|
|
|
}
|
|
|
|
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
|
|
|
|
|
|
|
|
slen = strlen( syntax->ssyn_oid );
|
|
|
|
mlen = strlen( mr->smr_oid );
|
|
|
|
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
|
|
|
struct berval *value = ber_bvdup( values[i] );
|
|
|
|
ldap_pvt_str2upper( value->bv_val );
|
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-06-05 06:59:38 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
value->bv_val, value->bv_len );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-06-05 06:59:38 +08:00
|
|
|
|
|
|
|
ber_bvfree( value );
|
|
|
|
|
|
|
|
keys[i] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
|
|
|
keys[i] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Index generation function */
|
|
|
|
int caseIgnoreIA5Filter(
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
2000-06-05 06:59:38 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
void * assertValue,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
size_t slen, mlen;
|
|
|
|
struct berval **keys;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
2001-01-18 00:35:53 +08:00
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-06-05 06:59:38 +08:00
|
|
|
struct berval *value;
|
|
|
|
struct berval digest;
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-06-05 06:59:38 +08:00
|
|
|
|
|
|
|
slen = strlen( syntax->ssyn_oid );
|
|
|
|
mlen = strlen( mr->smr_oid );
|
|
|
|
|
|
|
|
value = ber_bvdup( (struct berval *) assertValue );
|
|
|
|
ldap_pvt_str2upper( value->bv_val );
|
|
|
|
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * 2 );
|
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-06-05 06:59:38 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-06-05 06:59:38 +08:00
|
|
|
value->bv_val, value->bv_len );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-06-05 06:59:38 +08:00
|
|
|
|
|
|
|
keys[0] = ber_bvdup( &digest );
|
|
|
|
keys[1] = NULL;
|
|
|
|
|
|
|
|
ber_bvfree( value );
|
|
|
|
|
|
|
|
*keysp = keys;
|
2000-08-23 05:26:25 +08:00
|
|
|
|
2000-06-05 06:59:38 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-07-19 01:46:34 +08:00
|
|
|
/* Substrings Index generation function */
|
|
|
|
int caseIgnoreIA5SubstringsIndexer(
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
2000-07-19 01:46:34 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
struct berval **values,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
2000-08-22 10:23:52 +08:00
|
|
|
ber_len_t i, nkeys;
|
2000-07-19 01:46:34 +08:00
|
|
|
size_t slen, mlen;
|
|
|
|
struct berval **keys;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
2001-01-18 00:35:53 +08:00
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-07-19 01:46:34 +08:00
|
|
|
struct berval digest;
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-07-19 01:46:34 +08:00
|
|
|
|
2000-09-15 11:26:22 +08:00
|
|
|
/* we should have at least one value at this point */
|
|
|
|
assert( values != NULL && values[0] != NULL );
|
|
|
|
|
2000-07-19 01:46:34 +08:00
|
|
|
nkeys=0;
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
|
|
|
/* count number of indices to generate */
|
|
|
|
if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
|
2000-08-22 10:23:52 +08:00
|
|
|
if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
|
|
|
|
nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
|
|
|
|
( SLAP_INDEX_SUBSTR_MINLEN - 1);
|
|
|
|
} else {
|
|
|
|
nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_ANY ) {
|
2000-08-22 10:23:52 +08:00
|
|
|
if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
|
|
|
|
nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
|
2000-08-22 10:23:52 +08:00
|
|
|
if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
|
|
|
|
nkeys += SLAP_INDEX_SUBSTR_MAXLEN -
|
|
|
|
( SLAP_INDEX_SUBSTR_MINLEN - 1);
|
|
|
|
} else {
|
|
|
|
nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 );
|
|
|
|
}
|
2000-07-19 01:46:34 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nkeys == 0 ) {
|
|
|
|
/* no keys to generate */
|
|
|
|
*keysp = NULL;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
|
|
|
|
|
|
|
|
slen = strlen( syntax->ssyn_oid );
|
|
|
|
mlen = strlen( mr->smr_oid );
|
|
|
|
|
|
|
|
nkeys=0;
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
|
|
|
int j,max;
|
|
|
|
struct berval *value;
|
|
|
|
|
2000-07-19 06:59:34 +08:00
|
|
|
if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue;
|
2000-07-19 01:46:34 +08:00
|
|
|
|
|
|
|
value = ber_bvdup( values[i] );
|
|
|
|
ldap_pvt_str2upper( value->bv_val );
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
|
2000-08-22 10:23:52 +08:00
|
|
|
( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) )
|
|
|
|
{
|
|
|
|
char pre = SLAP_INDEX_SUBSTR_PREFIX;
|
|
|
|
max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1);
|
|
|
|
|
|
|
|
for( j=0; j<max; j++ ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-08-22 10:23:52 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-08 07:46:07 +08:00
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
&value->bv_val[j],
|
|
|
|
SLAP_INDEX_SUBSTR_MAXLEN );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-08-22 10:23:52 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
|
|
|
|
? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
|
|
|
|
|
2000-07-19 01:46:34 +08:00
|
|
|
for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) {
|
|
|
|
char pre;
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
|
2000-07-19 01:46:34 +08:00
|
|
|
pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
value->bv_val, j );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
|
2000-07-19 01:46:34 +08:00
|
|
|
pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
&value->bv_val[value->bv_len-j], j );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ber_bvfree( value );
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( nkeys > 0 ) {
|
|
|
|
keys[nkeys] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
} else {
|
|
|
|
ch_free( keys );
|
|
|
|
*keysp = NULL;
|
|
|
|
}
|
|
|
|
|
2000-07-19 01:46:34 +08:00
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int caseIgnoreIA5SubstringsFilter(
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
2000-07-19 01:46:34 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
void * assertValue,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
SubstringsAssertion *sa = assertValue;
|
|
|
|
char pre;
|
2000-08-22 10:23:52 +08:00
|
|
|
ber_len_t nkeys = 0;
|
2000-07-19 01:46:34 +08:00
|
|
|
size_t slen, mlen, klen;
|
|
|
|
struct berval **keys;
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_CONTEXT HASHcontext;
|
2001-01-18 00:35:53 +08:00
|
|
|
unsigned char HASHdigest[HASH_BYTES];
|
2000-07-19 01:46:34 +08:00
|
|
|
struct berval *value;
|
|
|
|
struct berval digest;
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
|
2000-07-19 01:46:34 +08:00
|
|
|
sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
|
|
|
|
{
|
|
|
|
nkeys++;
|
|
|
|
}
|
2000-08-22 10:23:52 +08:00
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
|
2000-08-22 10:23:52 +08:00
|
|
|
ber_len_t i;
|
|
|
|
for( i=0; sa->sa_any[i] != NULL; i++ ) {
|
|
|
|
if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) {
|
|
|
|
/* don't bother accounting for stepping */
|
|
|
|
nkeys += sa->sa_any[i]->bv_len -
|
|
|
|
( SLAP_INDEX_SUBSTR_MAXLEN - 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
|
2000-07-19 01:46:34 +08:00
|
|
|
sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
|
|
|
|
{
|
|
|
|
nkeys++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nkeys == 0 ) {
|
|
|
|
*keysp = NULL;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
digest.bv_val = HASHdigest;
|
|
|
|
digest.bv_len = sizeof(HASHdigest);
|
2000-07-19 01:46:34 +08:00
|
|
|
|
|
|
|
slen = strlen( syntax->ssyn_oid );
|
|
|
|
mlen = strlen( mr->smr_oid );
|
|
|
|
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) );
|
|
|
|
nkeys = 0;
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if((flags & SLAP_INDEX_SUBSTR_INITIAL) && sa->sa_initial != NULL &&
|
2000-07-19 01:46:34 +08:00
|
|
|
sa->sa_initial->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
|
|
|
|
{
|
|
|
|
pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
|
|
|
|
value = ber_bvdup( sa->sa_initial );
|
|
|
|
ldap_pvt_str2upper( value->bv_val );
|
|
|
|
|
|
|
|
klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
|
|
|
|
? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
|
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
value->bv_val, klen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
|
|
|
|
ber_bvfree( value );
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if((flags & SLAP_INDEX_SUBSTR_ANY) && sa->sa_any != NULL ) {
|
2000-08-22 10:23:52 +08:00
|
|
|
ber_len_t i, j;
|
|
|
|
pre = SLAP_INDEX_SUBSTR_PREFIX;
|
|
|
|
klen = SLAP_INDEX_SUBSTR_MAXLEN;
|
|
|
|
|
|
|
|
for( i=0; sa->sa_any[i] != NULL; i++ ) {
|
|
|
|
if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
value = ber_bvdup( sa->sa_any[i] );
|
|
|
|
ldap_pvt_str2upper( value->bv_val );
|
|
|
|
|
2000-08-23 06:34:37 +08:00
|
|
|
for(j=0;
|
|
|
|
j <= value->bv_len - SLAP_INDEX_SUBSTR_MAXLEN;
|
|
|
|
j += SLAP_INDEX_SUBSTR_STEP )
|
|
|
|
{
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-08-22 10:23:52 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-08-22 10:23:52 +08:00
|
|
|
&value->bv_val[j], klen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-08-22 10:23:52 +08:00
|
|
|
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
|
|
|
ber_bvfree( value );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if((flags & SLAP_INDEX_SUBSTR_FINAL) && sa->sa_final != NULL &&
|
2000-07-19 01:46:34 +08:00
|
|
|
sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN )
|
|
|
|
{
|
|
|
|
pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
|
|
|
|
value = ber_bvdup( sa->sa_final );
|
|
|
|
ldap_pvt_str2upper( value->bv_val );
|
|
|
|
|
|
|
|
klen = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len
|
|
|
|
? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len;
|
|
|
|
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Init( &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
if( prefix != NULL && prefix->bv_len > 0 ) {
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
prefix->bv_val, prefix->bv_len );
|
|
|
|
}
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
&pre, sizeof( pre ) );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
syntax->ssyn_oid, slen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
mr->smr_oid, mlen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Update( &HASHcontext,
|
2000-07-19 01:46:34 +08:00
|
|
|
&value->bv_val[value->bv_len-klen], klen );
|
2000-09-23 04:47:46 +08:00
|
|
|
HASH_Final( HASHdigest, &HASHcontext );
|
2000-07-19 01:46:34 +08:00
|
|
|
|
|
|
|
ber_bvfree( value );
|
|
|
|
keys[nkeys++] = ber_bvdup( &digest );
|
|
|
|
}
|
|
|
|
|
2000-08-23 05:26:25 +08:00
|
|
|
if( nkeys > 0 ) {
|
|
|
|
keys[nkeys] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
} else {
|
|
|
|
ch_free( keys );
|
|
|
|
*keysp = NULL;
|
|
|
|
}
|
2000-07-19 01:46:34 +08:00
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2001-01-18 05:02:11 +08:00
|
|
|
static int
|
|
|
|
numericStringValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
ber_len_t i;
|
|
|
|
|
|
|
|
for(i=0; i < in->bv_len; i++) {
|
|
|
|
if( !SLAP_NUMERIC(in->bv_val[i]) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-05-29 12:58:40 +08:00
|
|
|
static int
|
2000-06-16 04:33:56 +08:00
|
|
|
numericStringNormalize(
|
2000-05-29 12:58:40 +08:00
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val,
|
|
|
|
struct berval **normalized )
|
|
|
|
{
|
2001-01-18 05:02:11 +08:00
|
|
|
/* removal all spaces */
|
2000-05-29 12:58:40 +08:00
|
|
|
struct berval *newval;
|
|
|
|
char *p, *q;
|
|
|
|
|
|
|
|
newval = ch_malloc( sizeof( struct berval ) );
|
2001-01-18 05:02:11 +08:00
|
|
|
newval->bv_val = ch_malloc( val->bv_len + 1 );
|
2000-05-29 12:58:40 +08:00
|
|
|
|
|
|
|
p = val->bv_val;
|
2001-01-18 05:02:11 +08:00
|
|
|
q = newval->bv_val;
|
2000-05-29 12:58:40 +08:00
|
|
|
|
|
|
|
while ( *p ) {
|
2000-06-21 01:05:15 +08:00
|
|
|
if ( ASCII_SPACE( *p ) ) {
|
2000-05-29 12:58:40 +08:00
|
|
|
/* Ignore whitespace */
|
|
|
|
p++;
|
|
|
|
} else {
|
|
|
|
*q++ = *p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-07-25 03:54:04 +08:00
|
|
|
/* we should have copied no more then is in val */
|
|
|
|
assert( (q - newval->bv_val) <= (p - val->bv_val) );
|
2000-05-29 12:58:40 +08:00
|
|
|
|
|
|
|
/* null terminate */
|
|
|
|
*q = '\0';
|
|
|
|
|
|
|
|
newval->bv_len = q - newval->bv_val;
|
|
|
|
*normalized = newval;
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-06-20 11:55:40 +08:00
|
|
|
static int
|
|
|
|
objectIdentifierFirstComponentMatch(
|
|
|
|
int *matchp,
|
2000-08-23 05:26:25 +08:00
|
|
|
slap_mask_t flags,
|
2000-06-20 11:55:40 +08:00
|
|
|
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 */
|
2000-06-21 01:05:15 +08:00
|
|
|
for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) {
|
2000-06-20 11:55:40 +08:00
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* grab next word */
|
|
|
|
oid.bv_val = &value->bv_val[i];
|
|
|
|
oid.bv_len = value->bv_len - i;
|
2000-06-21 01:05:15 +08:00
|
|
|
for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) {
|
2000-06-20 11:55:40 +08:00
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
oid.bv_len = i;
|
|
|
|
|
|
|
|
/* insert attributeTypes, objectclass check here */
|
2000-06-21 01:05:15 +08:00
|
|
|
if( OID_LEADCHAR(asserted->bv_val[0]) ) {
|
2000-06-26 13:13:41 +08:00
|
|
|
rc = objectIdentifierMatch( &match, flags, syntax, mr, &oid, asserted );
|
2000-06-20 11:55:40 +08:00
|
|
|
|
|
|
|
} else {
|
|
|
|
char *stored = ch_malloc( oid.bv_len + 1 );
|
2000-07-28 09:07:07 +08:00
|
|
|
AC_MEMCPY( stored, oid.bv_val, oid.bv_len );
|
2000-06-20 11:55:40 +08:00
|
|
|
stored[oid.bv_len] = '\0';
|
|
|
|
|
|
|
|
if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) {
|
|
|
|
MatchingRule *asserted_mr = mr_find( asserted->bv_val );
|
|
|
|
MatchingRule *stored_mr = mr_find( stored );
|
|
|
|
|
|
|
|
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_find( asserted->bv_val );
|
|
|
|
AttributeType *stored_at = at_find( stored );
|
|
|
|
|
|
|
|
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_find( asserted->bv_val );
|
|
|
|
ObjectClass *stored_oc = oc_find( stored );
|
|
|
|
|
|
|
|
if( asserted_oc == NULL ) {
|
|
|
|
rc = SLAPD_COMPARE_UNDEFINED;
|
|
|
|
} else {
|
|
|
|
match = asserted_oc != stored_oc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ch_free( stored );
|
|
|
|
}
|
|
|
|
|
2001-01-16 03:17:29 +08:00
|
|
|
#ifdef NEW_LOGGING
|
2001-01-18 00:35:53 +08:00
|
|
|
LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
|
|
|
|
"objectIdentifierFirstComponentMatch: %d\n %s\n %s\n",
|
|
|
|
match, value->bv_val, asserted->bv_val ));
|
2001-01-16 03:17:29 +08:00
|
|
|
#else
|
2000-06-20 11:55:40 +08:00
|
|
|
Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch "
|
|
|
|
"%d\n\t\"%s\"\n\t\"%s\"\n",
|
2001-07-22 07:02:06 +08:00
|
|
|
match, value->bv_val, asserted->bv_val );
|
2001-01-16 03:17:29 +08:00
|
|
|
#endif
|
|
|
|
|
2000-06-20 11:55:40 +08:00
|
|
|
|
|
|
|
if( rc == LDAP_SUCCESS ) *matchp = match;
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2001-09-02 01:10:43 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2001-10-20 18:15:09 +08:00
|
|
|
#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)
|
|
|
|
{
|
|
|
|
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];
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* base indicates the index of the most significant
|
|
|
|
* byte that might be nonzero. When it goes off the
|
|
|
|
* end, we now there is nothing left to do.
|
|
|
|
*/
|
|
|
|
while (base < n) {
|
|
|
|
unsigned int carry;
|
|
|
|
|
|
|
|
carry = 0;
|
|
|
|
for (i = base; i<n; i++ ) {
|
|
|
|
copy[i] += carry*256;
|
|
|
|
carry = copy[i] % 10;
|
|
|
|
copy[i] /= 10;
|
|
|
|
}
|
|
|
|
if (p <= buf+1) {
|
|
|
|
/*
|
|
|
|
* Way too large, we need to leave
|
|
|
|
* room for sign if negative
|
|
|
|
*/
|
2001-11-07 06:36:28 +08:00
|
|
|
free(copy);
|
|
|
|
return NULL;
|
2001-10-20 18:15:09 +08:00
|
|
|
}
|
|
|
|
*--p = digit[carry];
|
|
|
|
if (copy[base] == 0)
|
|
|
|
base++;
|
|
|
|
}
|
|
|
|
free(copy);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( a->type == V_ASN1_NEG_INTEGER ) {
|
|
|
|
*--p = '-';
|
|
|
|
}
|
|
|
|
|
|
|
|
return ber_bvstrdup(p);
|
|
|
|
}
|
|
|
|
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
/* Get a DN in RFC2253 format from a X509_NAME internal struct */
|
2001-10-20 18:15:09 +08:00
|
|
|
static struct berval *
|
|
|
|
dn_openssl2ldap(X509_NAME *name)
|
|
|
|
{
|
|
|
|
char issuer_dn[1024];
|
|
|
|
BIO *bio;
|
|
|
|
|
|
|
|
bio = BIO_new(BIO_s_mem());
|
|
|
|
if ( !bio ) {
|
2001-10-23 03:55:21 +08:00
|
|
|
#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
|
2001-10-20 18:15:09 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
/*
|
|
|
|
* Given a certificate in DER format, extract the corresponding
|
|
|
|
* assertion value for certificateExactMatch
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
certificateExactConvert(
|
|
|
|
struct berval * in,
|
|
|
|
struct berval ** out )
|
|
|
|
{
|
|
|
|
X509 *xcert;
|
|
|
|
unsigned char *p = in->bv_val;
|
|
|
|
struct berval *serial;
|
|
|
|
struct berval *issuer_dn;
|
|
|
|
struct berval *bv_tmp;
|
|
|
|
|
|
|
|
xcert = d2i_X509(NULL, &p, in->bv_len);
|
|
|
|
if ( !xcert ) {
|
2001-10-23 03:55:21 +08:00
|
|
|
#ifdef NEW_LOGGING
|
|
|
|
LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
|
|
|
|
"certificateExactConvert: error parsing cert: %s\n",
|
|
|
|
ERR_error_string(ERR_get_error(),NULL)));
|
|
|
|
#else
|
|
|
|
Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: "
|
|
|
|
"error parsing cert: %s\n",
|
|
|
|
ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
|
|
|
|
#endif
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
serial = asn1_integer2str(xcert->cert_info->serialNumber);
|
2001-10-23 17:05:04 +08:00
|
|
|
if ( !serial ) {
|
|
|
|
X509_free(xcert);
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
|
2001-10-23 17:05:04 +08:00
|
|
|
if ( !issuer_dn ) {
|
|
|
|
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 ) {
|
|
|
|
X509_free(xcert);
|
|
|
|
ber_bvfree(serial);
|
|
|
|
ber_bvfree(bv_tmp);
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
ber_bvfree(bv_tmp);
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
|
|
|
|
X509_free(xcert);
|
|
|
|
|
|
|
|
*out = ch_malloc(sizeof(struct berval));
|
|
|
|
(*out)->bv_len = serial->bv_len + 3 + issuer_dn->bv_len + 1;
|
|
|
|
(*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, " $ ", 3);
|
|
|
|
p += 3;
|
|
|
|
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));
|
|
|
|
#else
|
|
|
|
Debug( LDAP_DEBUG_ARGS, "certificateExactConvert "
|
|
|
|
"\n\t\"%s\"\n",
|
|
|
|
(*out)->bv_val, NULL, NULL );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
ber_bvfree(serial);
|
|
|
|
ber_bvfree(issuer_dn);
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2001-10-20 18:15:09 +08:00
|
|
|
static int
|
|
|
|
serial_and_issuer_parse(
|
|
|
|
struct berval *assertion,
|
|
|
|
struct berval **serial,
|
|
|
|
struct berval **issuer_dn
|
|
|
|
)
|
|
|
|
{
|
|
|
|
char *begin;
|
|
|
|
char *end;
|
|
|
|
char *p;
|
|
|
|
char *q;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
/* p now points at the $ sign, now use begin and end to delimit the
|
|
|
|
serial number */
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
while (ASCII_SPACE(*begin))
|
|
|
|
begin++;
|
|
|
|
end = p-1;
|
|
|
|
while (ASCII_SPACE(*end))
|
|
|
|
end--;
|
2001-10-20 18:15:09 +08:00
|
|
|
|
|
|
|
q = ch_malloc( (end-begin+1)+1 );
|
|
|
|
AC_MEMCPY( q, begin, end-begin+1 );
|
|
|
|
q[end-begin+1] = '\0';
|
|
|
|
*serial = ber_bvstr(q);
|
|
|
|
|
|
|
|
/* now extract the issuer, remember p was at the dollar sign */
|
|
|
|
begin = p+1;
|
|
|
|
end = assertion->bv_val+assertion->bv_len-1;
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
while (ASCII_SPACE(*begin))
|
|
|
|
begin++;
|
2001-10-20 18:15:09 +08:00
|
|
|
/* should we trim spaces at the end too? is it safe always? */
|
|
|
|
|
|
|
|
q = ch_malloc( (end-begin+1)+1 );
|
|
|
|
AC_MEMCPY( q, begin, end-begin+1 );
|
|
|
|
q[end-begin+1] = '\0';
|
2001-10-23 17:05:04 +08:00
|
|
|
*issuer_dn = ber_bvstr(dn_normalize(q));
|
2001-10-20 18:15:09 +08:00
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
certificateExactMatch(
|
|
|
|
int *matchp,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *value,
|
|
|
|
void *assertedValue )
|
|
|
|
{
|
|
|
|
X509 *xcert;
|
|
|
|
unsigned char *p = value->bv_val;
|
|
|
|
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 ) {
|
2001-10-23 03:55:21 +08:00
|
|
|
#ifdef NEW_LOGGING
|
|
|
|
LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
|
|
|
|
"certificateExactMatch: error parsing cert: %s\n",
|
|
|
|
ERR_error_string(ERR_get_error(),NULL)));
|
|
|
|
#else
|
|
|
|
Debug( LDAP_DEBUG_ARGS, "certificateExactMatch: "
|
|
|
|
"error parsing cert: %s\n",
|
|
|
|
ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
|
|
|
|
#endif
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2001-10-20 18:15:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
serial = asn1_integer2str(xcert->cert_info->serialNumber);
|
|
|
|
issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
|
|
|
|
|
|
|
|
X509_free(xcert);
|
|
|
|
|
|
|
|
serial_and_issuer_parse(assertedValue,
|
|
|
|
&asserted_serial,
|
|
|
|
&asserted_issuer_dn);
|
|
|
|
|
|
|
|
ret = integerMatch(
|
|
|
|
matchp,
|
|
|
|
flags,
|
|
|
|
slap_schema.si_syn_integer,
|
|
|
|
slap_schema.si_mr_integerMatch,
|
|
|
|
serial,
|
|
|
|
asserted_serial);
|
|
|
|
if ( ret == LDAP_SUCCESS ) {
|
|
|
|
if ( *matchp == 0 ) {
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
/* We need to normalize everything for dnMatch */
|
2001-10-20 18:15:09 +08:00
|
|
|
ret = dnMatch(
|
|
|
|
matchp,
|
|
|
|
flags,
|
|
|
|
slap_schema.si_syn_distinguishedName,
|
|
|
|
slap_schema.si_mr_distinguishedNameMatch,
|
|
|
|
issuer_dn,
|
|
|
|
asserted_issuer_dn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
#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));
|
|
|
|
#else
|
|
|
|
Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
|
|
|
|
"%d\n\t\"%s $ %s\"\n",
|
|
|
|
*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,
|
|
|
|
NULL );
|
|
|
|
#endif
|
|
|
|
|
2001-10-20 18:15:09 +08:00
|
|
|
ber_bvfree(serial);
|
|
|
|
ber_bvfree(issuer_dn);
|
|
|
|
ber_bvfree(asserted_serial);
|
|
|
|
ber_bvfree(asserted_issuer_dn);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2001-10-23 21:39:07 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Index generation function
|
|
|
|
* We just index the serials, in most scenarios the issuer DN is one of
|
|
|
|
* a very small set of values.
|
|
|
|
*/
|
|
|
|
int certificateExactIndexer(
|
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
struct berval **values,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct berval **keys;
|
|
|
|
X509 *xcert;
|
|
|
|
unsigned char *p;
|
|
|
|
struct berval * serial;
|
|
|
|
|
|
|
|
/* we should have at least one value at this point */
|
|
|
|
assert( values != NULL && values[0] != NULL );
|
|
|
|
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
|
|
|
/* empty -- just count them */
|
|
|
|
}
|
|
|
|
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * (i+1) );
|
|
|
|
|
|
|
|
for( i=0; values[i] != NULL; i++ ) {
|
|
|
|
p = values[i]->bv_val;
|
|
|
|
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)));
|
|
|
|
#else
|
|
|
|
Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
|
|
|
|
"error parsing cert: %s\n",
|
|
|
|
ERR_error_string(ERR_get_error(),NULL),
|
|
|
|
NULL, NULL );
|
|
|
|
#endif
|
|
|
|
/* Do we leak keys on error? */
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
serial = asn1_integer2str(xcert->cert_info->serialNumber);
|
|
|
|
X509_free(xcert);
|
|
|
|
integerNormalize( slap_schema.si_syn_integer,
|
|
|
|
serial,
|
|
|
|
&keys[i] );
|
|
|
|
ber_bvfree(serial);
|
|
|
|
#ifdef NEW_LOGGING
|
|
|
|
LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
|
|
|
|
"certificateExactIndexer: returning: %s\n",
|
|
|
|
keys[i]->bv_val));
|
|
|
|
#else
|
|
|
|
Debug( LDAP_DEBUG_ARGS, "certificateExactIndexer: "
|
|
|
|
"returning: %s\n",
|
|
|
|
keys[i]->bv_val,
|
|
|
|
NULL, NULL );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
keys[i] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Index generation function */
|
|
|
|
/* We think this is always called with a value in matching rule syntax */
|
|
|
|
int certificateExactFilter(
|
|
|
|
slap_mask_t use,
|
|
|
|
slap_mask_t flags,
|
|
|
|
Syntax *syntax,
|
|
|
|
MatchingRule *mr,
|
|
|
|
struct berval *prefix,
|
|
|
|
void * assertValue,
|
|
|
|
struct berval ***keysp )
|
|
|
|
{
|
|
|
|
struct berval **keys;
|
|
|
|
struct berval *asserted_serial;
|
|
|
|
struct berval *asserted_issuer_dn;
|
|
|
|
|
|
|
|
serial_and_issuer_parse(assertValue,
|
|
|
|
&asserted_serial,
|
|
|
|
&asserted_issuer_dn);
|
|
|
|
|
|
|
|
keys = ch_malloc( sizeof( struct berval * ) * 2 );
|
|
|
|
integerNormalize( syntax, asserted_serial, &keys[0] );
|
|
|
|
keys[1] = NULL;
|
|
|
|
*keysp = keys;
|
|
|
|
|
|
|
|
ber_bvfree(asserted_serial);
|
|
|
|
ber_bvfree(asserted_issuer_dn);
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2001-10-20 18:15:09 +08:00
|
|
|
#endif
|
|
|
|
|
2000-06-15 15:58:04 +08:00
|
|
|
static int
|
|
|
|
check_time_syntax (struct berval *val,
|
|
|
|
int start,
|
|
|
|
int *parts)
|
|
|
|
{
|
|
|
|
static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
|
2000-09-07 03:17:33 +08:00
|
|
|
static int mdays[2][12] = {
|
|
|
|
/* non-leap years */
|
|
|
|
{ 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
|
|
|
|
/* leap years */
|
|
|
|
{ 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
|
|
|
|
};
|
2000-06-15 15:58:04 +08:00
|
|
|
char *p, *e;
|
2000-09-07 03:17:33 +08:00
|
|
|
int part, c, tzoffset, leapyear = 0 ;
|
2000-06-15 15:58:04 +08:00
|
|
|
|
2000-09-07 03:17:33 +08:00
|
|
|
if( val->bv_len == 0 ) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
|
|
|
|
p = (char *)val->bv_val;
|
|
|
|
e = p + val->bv_len;
|
|
|
|
|
|
|
|
/* Ignore initial whitespace */
|
2000-06-21 01:05:15 +08:00
|
|
|
while ( ( p < e ) && ASCII_SPACE( *p ) ) {
|
2000-06-15 15:58:04 +08:00
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
2000-09-07 03:17:33 +08:00
|
|
|
if (e - p < 13 - (2 * start)) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
|
2000-09-07 03:17:33 +08:00
|
|
|
for (part = 0; part < 9; part++) {
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[part] = 0;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
|
|
|
|
for (part = start; part < 7; part++) {
|
|
|
|
c = *p;
|
2000-09-07 03:17:33 +08:00
|
|
|
if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
|
2000-06-15 15:58:04 +08:00
|
|
|
part++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
c -= '0';
|
2000-09-07 03:17:33 +08:00
|
|
|
if (p == e) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
|
|
|
if (c < 0 || c > 9) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[part] = c;
|
|
|
|
|
|
|
|
c = *p++ - '0';
|
2000-09-07 03:17:33 +08:00
|
|
|
if (p == e) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
|
|
|
if (c < 0 || c > 9) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[part] *= 10;
|
|
|
|
parts[part] += c;
|
|
|
|
|
2000-09-07 03:17:33 +08:00
|
|
|
if (part == 2 || part == 3) {
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[part]--;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
|
|
|
if (parts[part] < 0) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
|
|
|
if (parts[part] > ceiling[part]) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
2000-09-07 03:17:33 +08:00
|
|
|
|
|
|
|
/* leapyear check for the Gregorian calendar (year>1581) */
|
|
|
|
if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
|
|
|
|
((parts[0] % 4 == 0) && (parts[1] == 0)))
|
|
|
|
{
|
|
|
|
leapyear = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parts[3] > mdays[leapyear][parts[2]]) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
2000-06-15 15:58:04 +08:00
|
|
|
c = *p++;
|
|
|
|
if (c == 'Z') {
|
2000-09-07 03:17:33 +08:00
|
|
|
tzoffset = 0; /* UTC */
|
2000-06-15 15:58:04 +08:00
|
|
|
} else if (c != '+' && c != '-') {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
} else {
|
2000-09-07 03:17:33 +08:00
|
|
|
if (c == '-') {
|
|
|
|
tzoffset = -1;
|
|
|
|
} else /* c == '+' */ {
|
|
|
|
tzoffset = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p > e - 4) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
|
|
|
|
2000-06-15 15:58:04 +08:00
|
|
|
for (part = 7; part < 9; part++) {
|
|
|
|
c = *p++ - '0';
|
2000-09-07 03:17:33 +08:00
|
|
|
if (c < 0 || c > 9) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[part] = c;
|
|
|
|
|
|
|
|
c = *p++ - '0';
|
2000-09-07 03:17:33 +08:00
|
|
|
if (c < 0 || c > 9) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[part] *= 10;
|
|
|
|
parts[part] += c;
|
2000-09-07 03:17:33 +08:00
|
|
|
if (parts[part] < 0 || parts[part] > ceiling[part]) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ignore trailing whitespace */
|
2000-06-21 01:05:15 +08:00
|
|
|
while ( ( p < e ) && ASCII_SPACE( *p ) ) {
|
2000-06-15 15:58:04 +08:00
|
|
|
p++;
|
|
|
|
}
|
2000-09-07 03:17:33 +08:00
|
|
|
if (p != e) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LDAP_INVALID_SYNTAX;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
|
2000-09-07 03:17:33 +08:00
|
|
|
switch ( tzoffset ) {
|
2001-01-18 00:35:53 +08:00
|
|
|
case -1: /* negativ offset to UTC, ie west of Greenwich */
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[4] += parts[7];
|
|
|
|
parts[5] += parts[8];
|
2000-09-07 03:17:33 +08:00
|
|
|
for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
|
|
|
|
if (part != 3) {
|
2000-06-15 15:58:04 +08:00
|
|
|
c = ceiling[part];
|
2000-09-07 03:17:33 +08:00
|
|
|
} else {
|
|
|
|
c = mdays[leapyear][parts[2]];
|
2000-06-15 15:58:04 +08:00
|
|
|
}
|
|
|
|
if (parts[part] > c) {
|
|
|
|
parts[part] -= c + 1;
|
|
|
|
parts[part - 1]++;
|
|
|
|
}
|
|
|
|
}
|
2000-09-07 03:17:33 +08:00
|
|
|
break;
|
|
|
|
case 1: /* positive offset to UTC, ie east of Greenwich */
|
2000-06-15 15:58:04 +08:00
|
|
|
parts[4] -= parts[7];
|
|
|
|
parts[5] -= parts[8];
|
2000-09-07 03:17:33 +08:00
|
|
|
for (part = 6; --part > 0; ) {
|
|
|
|
if (part != 3) {
|
2000-06-15 15:58:04 +08:00
|
|
|
c = ceiling[part];
|
2000-09-07 03:17:33 +08:00
|
|
|
} else {
|
|
|
|
/* first arg to % needs to be non negativ */
|
|
|
|
c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
|
2000-06-15 15:58:04 +08:00
|
|
|
}
|
|
|
|
if (parts[part] < 0) {
|
|
|
|
parts[part] += c + 1;
|
|
|
|
parts[part - 1]--;
|
|
|
|
}
|
|
|
|
}
|
2000-09-07 03:17:33 +08:00
|
|
|
break;
|
|
|
|
case 0: /* already UTC */
|
|
|
|
break;
|
2000-06-15 15:58:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
utcTimeNormalize(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val,
|
|
|
|
struct berval **normalized )
|
|
|
|
{
|
|
|
|
struct berval *out;
|
|
|
|
int parts[9], rc;
|
|
|
|
|
|
|
|
rc = check_time_syntax(val, 1, parts);
|
|
|
|
if (rc != LDAP_SUCCESS) {
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
*normalized = NULL;
|
|
|
|
out = ch_malloc( sizeof(struct berval) );
|
2000-09-07 03:17:33 +08:00
|
|
|
if( out == NULL ) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LBER_ERROR_MEMORY;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
|
|
|
|
out->bv_val = ch_malloc( 14 );
|
|
|
|
if ( out->bv_val == NULL ) {
|
|
|
|
ch_free( out );
|
|
|
|
return LBER_ERROR_MEMORY;
|
|
|
|
}
|
|
|
|
|
2001-11-18 00:18:07 +08:00
|
|
|
sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02dZ",
|
2000-09-07 03:17:33 +08:00
|
|
|
parts[1], parts[2] + 1, parts[3] + 1,
|
|
|
|
parts[4], parts[5], parts[6] );
|
2000-06-15 15:58:04 +08:00
|
|
|
out->bv_len = 13;
|
|
|
|
*normalized = out;
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
utcTimeValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
int parts[9];
|
|
|
|
|
|
|
|
return check_time_syntax(in, 1, parts);
|
|
|
|
}
|
|
|
|
|
2000-06-30 10:18:58 +08:00
|
|
|
static int
|
|
|
|
generalizedTimeValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *in )
|
|
|
|
{
|
|
|
|
int parts[9];
|
|
|
|
|
|
|
|
return check_time_syntax(in, 0, parts);
|
|
|
|
}
|
|
|
|
|
2000-06-15 15:58:04 +08:00
|
|
|
static int
|
|
|
|
generalizedTimeNormalize(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val,
|
|
|
|
struct berval **normalized )
|
|
|
|
{
|
|
|
|
struct berval *out;
|
|
|
|
int parts[9], rc;
|
|
|
|
|
|
|
|
rc = check_time_syntax(val, 0, parts);
|
|
|
|
if (rc != LDAP_SUCCESS) {
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
*normalized = NULL;
|
|
|
|
out = ch_malloc( sizeof(struct berval) );
|
2000-09-07 03:17:33 +08:00
|
|
|
if( out == NULL ) {
|
2000-06-15 15:58:04 +08:00
|
|
|
return LBER_ERROR_MEMORY;
|
2000-09-07 03:17:33 +08:00
|
|
|
}
|
2000-06-15 15:58:04 +08:00
|
|
|
|
|
|
|
out->bv_val = ch_malloc( 16 );
|
|
|
|
if ( out->bv_val == NULL ) {
|
|
|
|
ch_free( out );
|
|
|
|
return LBER_ERROR_MEMORY;
|
|
|
|
}
|
|
|
|
|
2001-11-18 00:18:07 +08:00
|
|
|
sprintf( out->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
|
2000-09-07 03:17:33 +08:00
|
|
|
parts[0], parts[1], parts[2] + 1, parts[3] + 1,
|
|
|
|
parts[4], parts[5], parts[6] );
|
2000-06-15 15:58:04 +08:00
|
|
|
out->bv_len = 15;
|
|
|
|
*normalized = out;
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-09-04 01:35:39 +08:00
|
|
|
static int
|
|
|
|
nisNetgroupTripleValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val )
|
|
|
|
{
|
|
|
|
char *p, *e;
|
|
|
|
int commas = 0;
|
|
|
|
|
|
|
|
if ( val->bv_len == 0 ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
p = (char *)val->bv_val;
|
|
|
|
e = p + val->bv_len;
|
|
|
|
|
|
|
|
if ( *p != '(' /*')'*/ ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( p++; ( p < e ) && ( *p != ')' ); p++ ) {
|
|
|
|
if ( *p == ',' ) {
|
|
|
|
commas++;
|
|
|
|
if ( commas > 2 ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if ( !ATTR_CHAR( *p ) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
p++;
|
|
|
|
|
|
|
|
if (p != e) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
bootParameterValidate(
|
|
|
|
Syntax *syntax,
|
|
|
|
struct berval *val )
|
|
|
|
{
|
|
|
|
char *p, *e;
|
|
|
|
|
|
|
|
if ( val->bv_len == 0 ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
p = (char *)val->bv_val;
|
|
|
|
e = p + val->bv_len;
|
|
|
|
|
|
|
|
/* key */
|
|
|
|
for (; ( p < e ) && ( *p != '=' ); p++ ) {
|
|
|
|
if ( !ATTR_CHAR( *p ) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( *p != '=' ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* server */
|
|
|
|
for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
|
|
|
|
if ( !ATTR_CHAR( *p ) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( *p != ':' ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* path */
|
|
|
|
for ( p++; p < e; p++ ) {
|
|
|
|
if ( !ATTR_CHAR( *p ) ) {
|
|
|
|
return LDAP_INVALID_SYNTAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
struct syntax_defs_rec {
|
|
|
|
char *sd_desc;
|
2000-01-31 09:49:44 +08:00
|
|
|
int sd_flags;
|
2000-01-30 03:43:19 +08:00
|
|
|
slap_syntax_validate_func *sd_validate;
|
2000-05-25 06:20:03 +08:00
|
|
|
slap_syntax_transform_func *sd_normalize;
|
|
|
|
slap_syntax_transform_func *sd_pretty;
|
|
|
|
#ifdef SLAPD_BINARY_CONVERSION
|
2000-01-30 03:43:19 +08:00
|
|
|
slap_syntax_transform_func *sd_ber2str;
|
|
|
|
slap_syntax_transform_func *sd_str2ber;
|
2000-05-25 06:20:03 +08:00
|
|
|
#endif
|
2000-01-30 03:43:19 +08:00
|
|
|
};
|
|
|
|
|
2000-05-19 09:06:43 +08:00
|
|
|
#define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
|
|
|
|
#define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
|
2000-05-19 01:21:42 +08:00
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
struct syntax_defs_rec syntax_defs[] = {
|
2000-05-19 01:21:42 +08:00
|
|
|
{"( 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},
|
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
|
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-19 01:21:42 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' " X_NOT_H_R ")",
|
|
|
|
SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
|
2000-10-14 09:37:48 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_NOT_H_R ")",
|
|
|
|
SLAP_SYNTAX_BER, berValidate, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
|
2001-11-17 02:10:37 +08:00
|
|
|
0, bitStringValidate, bitStringNormalize, NULL },
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
|
2000-06-30 03:00:17 +08:00
|
|
|
0, booleanValidate, NULL, NULL},
|
2000-05-19 01:21:42 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
|
|
|
|
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.9 DESC 'Certificate List' "
|
|
|
|
X_BINARY X_NOT_H_R ")",
|
|
|
|
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
|
2000-05-19 08:33:09 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
|
|
|
|
X_BINARY X_NOT_H_R ")",
|
2000-05-19 01:21:42 +08:00
|
|
|
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
|
2000-11-05 05:09:23 +08:00
|
|
|
0, countryStringValidate, IA5StringNormalize, NULL},
|
2000-05-29 08:27:49 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
|
2001-12-06 15:32:53 +08:00
|
|
|
0, dnValidate, dnNormalize, dnPretty},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
|
2000-05-18 01:25:48 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
|
2000-05-25 06:20:03 +08:00
|
|
|
0, UTF8StringValidate, UTF8StringNormalize, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
|
2000-05-18 01:25:48 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
|
2000-11-05 05:09:23 +08:00
|
|
|
0, printablesStringValidate, IA5StringNormalize, NULL},
|
2000-05-19 01:21:42 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
|
|
|
|
SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
|
2000-06-15 15:58:04 +08:00
|
|
|
0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
|
2000-05-25 06:20:03 +08:00
|
|
|
0, IA5StringValidate, IA5StringNormalize, NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
|
2001-11-04 06:03:20 +08:00
|
|
|
0, integerValidate, integerNormalize, NULL},
|
2000-05-19 01:21:42 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
|
2000-08-18 01:55:33 +08:00
|
|
|
SLAP_SYNTAX_BLOB, blobValidate, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
|
2000-09-12 08:32:08 +08:00
|
|
|
0, nameUIDValidate, nameUIDNormalize, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
|
2001-01-18 05:02:11 +08:00
|
|
|
0, numericStringValidate, numericStringNormalize, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
|
2000-05-23 10:33:56 +08:00
|
|
|
0, oidValidate, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
|
2000-11-05 05:09:23 +08:00
|
|
|
0, IA5StringValidate, IA5StringNormalize, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
|
2000-05-19 08:33:09 +08:00
|
|
|
0, blobValidate, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
|
2000-11-05 05:11:52 +08:00
|
|
|
0, UTF8StringValidate, UTF8StringNormalize, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
|
2000-11-05 05:09:23 +08:00
|
|
|
0, printableStringValidate, IA5StringNormalize, NULL},
|
2000-05-19 01:21:42 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
|
|
|
|
X_BINARY X_NOT_H_R ")",
|
|
|
|
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
|
2000-11-05 05:09:23 +08:00
|
|
|
0, printableStringValidate, IA5StringNormalize, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 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' )",
|
2001-11-04 06:03:20 +08:00
|
|
|
0, printablesStringValidate, IA5StringNormalize, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
|
2000-06-15 15:58:04 +08:00
|
|
|
0, utcTimeValidate, utcTimeNormalize, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-05-18 02:10:38 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
|
2000-01-31 09:49:44 +08:00
|
|
|
0, NULL, NULL, NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-08-25 03:54:16 +08:00
|
|
|
/* RFC 2307 NIS Syntaxes */
|
2000-09-12 08:32:08 +08:00
|
|
|
{"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
|
2000-08-25 03:54:16 +08:00
|
|
|
0, nisNetgroupTripleValidate, NULL, NULL},
|
|
|
|
{"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
|
|
|
|
0, bootParameterValidate, NULL, NULL},
|
|
|
|
|
2001-10-20 18:15:09 +08:00
|
|
|
#ifdef HAVE_TLS
|
|
|
|
/* From PKIX */
|
2001-10-21 01:31:52 +08:00
|
|
|
/* These OIDs are not published yet, but will be in the next
|
|
|
|
* I-D for PKIX LDAPv3 schema as have been advanced by David
|
|
|
|
* Chadwick in private mail.
|
|
|
|
*/
|
|
|
|
{"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )",
|
2001-10-20 18:15:09 +08:00
|
|
|
0, NULL, NULL, NULL},
|
|
|
|
#endif
|
|
|
|
|
2000-02-02 02:05:49 +08:00
|
|
|
/* OpenLDAP Experimental Syntaxes */
|
2000-05-28 03:33:08 +08:00
|
|
|
{"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
|
2001-12-02 12:48:06 +08:00
|
|
|
SLAP_SYNTAX_HIDE,
|
|
|
|
UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
|
2000-08-27 03:55:08 +08:00
|
|
|
NULL, NULL},
|
2001-12-02 12:48:06 +08:00
|
|
|
|
|
|
|
/* needs updating */
|
2000-05-31 05:34:55 +08:00
|
|
|
{"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
|
2001-12-02 12:48:06 +08:00
|
|
|
SLAP_SYNTAX_HIDE, NULL, NULL, NULL},
|
2000-02-02 02:05:49 +08:00
|
|
|
|
2000-08-27 03:52:21 +08:00
|
|
|
/* OpenLDAP Void Syntax */
|
2000-10-17 07:47:46 +08:00
|
|
|
{"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
|
2000-08-27 03:52:21 +08:00
|
|
|
SLAP_SYNTAX_HIDE, inValidate, NULL, NULL},
|
2000-01-31 09:49:44 +08:00
|
|
|
{NULL, 0, NULL, NULL, NULL}
|
2000-01-30 03:43:19 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct mrule_defs_rec {
|
2000-01-31 09:49:44 +08:00
|
|
|
char * mrd_desc;
|
2000-08-29 06:20:19 +08:00
|
|
|
slap_mask_t mrd_usage;
|
2000-01-31 09:49:44 +08:00
|
|
|
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;
|
2000-07-25 05:29:30 +08:00
|
|
|
|
|
|
|
char * mrd_associated;
|
2000-01-30 03:43:19 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
2000-07-03 00:36:21 +08:00
|
|
|
* Other matching rules in X.520 that we do not use (yet):
|
2000-01-30 03:43:19 +08:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
* 2.5.13.32 wordMatch
|
|
|
|
* 2.5.13.33 keywordMatch
|
|
|
|
* 2.5.13.35 certificateMatch
|
|
|
|
* 2.5.13.36 certificatePairExactMatch
|
|
|
|
* 2.5.13.37 certificatePairMatch
|
|
|
|
* 2.5.13.38 certificateListExactMatch
|
|
|
|
* 2.5.13.39 certificateListMatch
|
|
|
|
* 2.5.13.40 algorithmIdentifierMatch
|
|
|
|
* 2.5.13.41 storedPrefixMatch
|
|
|
|
* 2.5.13.42 attributeCertificateMatch
|
|
|
|
* 2.5.13.43 readerAndKeyIDMatch
|
|
|
|
* 2.5.13.44 attributeIntegrityMatch
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct mrule_defs_rec mrule_defs[] = {
|
2000-07-25 05:29:30 +08:00
|
|
|
/*
|
|
|
|
* EQUALITY matching rules must be listed after associated APPROX
|
|
|
|
* matching rules. So, we list all APPROX matching rules first.
|
|
|
|
*/
|
|
|
|
{"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
|
|
|
|
SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
|
|
|
|
NULL, NULL,
|
2001-01-18 05:02:11 +08:00
|
|
|
directoryStringApproxMatch,
|
|
|
|
directoryStringApproxIndexer,
|
2000-10-25 04:25:37 +08:00
|
|
|
directoryStringApproxFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL},
|
|
|
|
|
|
|
|
{"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
|
|
|
|
SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT,
|
|
|
|
NULL, NULL,
|
2001-01-18 05:02:11 +08:00
|
|
|
IA5StringApproxMatch,
|
|
|
|
IA5StringApproxIndexer,
|
2000-10-25 04:25:37 +08:00
|
|
|
IA5StringApproxFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL},
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Other matching rules
|
|
|
|
*/
|
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 2.5.13.0 NAME 'objectIdentifierMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
|
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.1 NAME 'distinguishedNameMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
dnMatch, dnIndexer, dnFilter,
|
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.2 NAME 'caseIgnoreMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
|
2001-12-06 11:24:31 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
2001-07-28 06:54:43 +08:00
|
|
|
caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
directoryStringApproxMatchOID },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_ORDERING,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
caseIgnoreOrderingMatch, NULL, NULL,
|
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_SUBSTR | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
2001-07-28 06:54:43 +08:00
|
|
|
caseExactIgnoreSubstringsMatch,
|
|
|
|
caseExactIgnoreSubstringsIndexer,
|
|
|
|
caseExactIgnoreSubstringsFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.5 NAME 'caseExactMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
2001-07-28 06:54:43 +08:00
|
|
|
caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
directoryStringApproxMatchOID },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_ORDERING,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
caseExactOrderingMatch, NULL, NULL,
|
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_SUBSTR | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
2001-07-28 06:54:43 +08:00
|
|
|
caseExactIgnoreSubstringsMatch,
|
|
|
|
caseExactIgnoreSubstringsIndexer,
|
|
|
|
caseExactIgnoreSubstringsFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.8 NAME 'numericStringMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
|
2001-12-06 11:24:31 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
2000-10-04 10:23:42 +08:00
|
|
|
caseIgnoreIA5Match,
|
|
|
|
caseIgnoreIA5Indexer,
|
|
|
|
caseIgnoreIA5Filter,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_SUBSTR | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
caseIgnoreIA5SubstringsMatch,
|
|
|
|
caseIgnoreIA5SubstringsIndexer,
|
|
|
|
caseIgnoreIA5SubstringsFilter,
|
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
|
2001-12-06 11:24:31 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
caseIgnoreListMatch, NULL, NULL,
|
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-05-17 02:11:50 +08:00
|
|
|
{"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
|
|
|
|
SLAP_MR_SUBSTR | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
caseIgnoreListSubstringsMatch, NULL, NULL,
|
|
|
|
NULL},
|
2000-05-17 02:11:50 +08:00
|
|
|
|
2000-06-30 03:00:17 +08:00
|
|
|
{"( 2.5.13.13 NAME 'booleanMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
|
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
booleanMatch, NULL, NULL,
|
|
|
|
NULL},
|
2000-06-30 03:00:17 +08:00
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 2.5.13.14 NAME 'integerMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
|
2000-06-27 01:54:45 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
2000-09-12 02:34:14 +08:00
|
|
|
integerMatch, integerIndexer, integerFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.16 NAME 'bitStringMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
|
2000-06-27 01:54:45 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
2001-11-17 02:10:37 +08:00
|
|
|
bitStringMatch, bitStringIndexer, bitStringFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.17 NAME 'octetStringMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
octetStringMatch, octetStringIndexer, octetStringFilter,
|
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.20 NAME 'telephoneNumberMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
|
2001-12-06 11:24:31 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
2001-05-03 08:59:47 +08:00
|
|
|
telephoneNumberMatch,
|
|
|
|
telephoneNumberIndexer,
|
|
|
|
telephoneNumberFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_SUBSTR | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
2001-05-03 08:59:47 +08:00
|
|
|
telephoneNumberSubstringsMatch,
|
|
|
|
telephoneNumberSubstringsIndexer,
|
|
|
|
telephoneNumberSubstringsFilter,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.22 NAME 'presentationAddressMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
|
2000-06-27 01:54:45 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
2001-05-10 07:43:06 +08:00
|
|
|
NULL, NULL, NULL,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.23 NAME 'uniqueMemberMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
|
2000-06-27 01:54:45 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
uniqueMemberMatch, NULL, NULL,
|
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.24 NAME 'protocolInformationMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
|
2000-06-27 01:54:45 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
protocolInformationMatch, NULL, NULL,
|
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.27 NAME 'generalizedTimeMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
generalizedTimeMatch, NULL, NULL,
|
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_ORDERING,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
generalizedTimeOrderingMatch, NULL, NULL,
|
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
integerFirstComponentMatch, NULL, NULL,
|
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
objectIdentifierFirstComponentMatch, NULL, NULL,
|
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2001-10-20 18:15:09 +08:00
|
|
|
#ifdef HAVE_TLS
|
|
|
|
{"( 2.5.13.34 NAME 'certificateExactMatch' "
|
2001-10-21 01:31:52 +08:00
|
|
|
"SYNTAX 1.2.826.0.1.3344810.7.1 )",
|
2001-10-20 18:15:09 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
It now sort of works, but needs some normalization work and proper
error reporting to client and syslog. And indexing, of course.
Now, the problem is that matching rules get called from different
places that are inconsistent in what an assertedValue is. When doing
a modify, a full certificate value is passed (to verify it isn't
already there). When doing a search or compare, the passed value is
in the syntax of the matching rule.
Consistency would require that the caller extracts an asserted value
from the full value before calling smr_match. It can do this by
calling smr_convert (it was unused, was it meant to be used for
this?).
Unfortunately, the caller is typically value_find, value_match, etc.
that have themselves little knowledge of what they are dealing with,
so their interface needs to be extended, new flag values or new
arguments, so that they know if they have a value in attribute type
syntax or in matching rule syntax.
2001-10-22 14:54:30 +08:00
|
|
|
certificateExactConvert, NULL,
|
2001-10-23 21:39:07 +08:00
|
|
|
certificateExactMatch,
|
|
|
|
certificateExactIndexer, certificateExactFilter,
|
2001-10-20 18:15:09 +08:00
|
|
|
NULL},
|
|
|
|
#endif
|
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
{"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT,
|
2000-07-03 00:36:21 +08:00
|
|
|
NULL, NULL,
|
2000-07-25 05:29:30 +08:00
|
|
|
caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter,
|
|
|
|
IA5StringApproxMatchOID },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
|
2001-12-06 11:24:31 +08:00
|
|
|
SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD,
|
2000-07-03 00:36:21 +08:00
|
|
|
NULL, NULL,
|
2000-09-29 08:24:43 +08:00
|
|
|
caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter,
|
2000-07-25 05:29:30 +08:00
|
|
|
IA5StringApproxMatchOID },
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
{"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
|
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
|
2000-02-15 04:57:34 +08:00
|
|
|
SLAP_MR_SUBSTR,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
caseIgnoreIA5SubstringsMatch,
|
|
|
|
caseIgnoreIA5SubstringsIndexer,
|
|
|
|
caseIgnoreIA5SubstringsFilter,
|
|
|
|
NULL},
|
2000-01-30 03:43:19 +08:00
|
|
|
|
2000-08-27 02:49:50 +08:00
|
|
|
{"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
|
2000-07-03 00:36:21 +08:00
|
|
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
|
|
|
|
SLAP_MR_SUBSTR,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
caseExactIA5SubstringsMatch,
|
|
|
|
caseExactIA5SubstringsIndexer,
|
|
|
|
caseExactIA5SubstringsFilter,
|
|
|
|
NULL},
|
2000-07-03 00:36:21 +08:00
|
|
|
|
2001-12-02 12:48:06 +08:00
|
|
|
/* needs updating */
|
2000-05-31 05:34:55 +08:00
|
|
|
{"( 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,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
authPasswordMatch, NULL, NULL,
|
|
|
|
NULL},
|
2000-05-31 05:34:55 +08:00
|
|
|
|
|
|
|
{"( 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,
|
2000-07-25 05:29:30 +08:00
|
|
|
NULL, NULL,
|
|
|
|
OpenLDAPaciMatch, NULL, NULL,
|
|
|
|
NULL},
|
2000-05-31 05:34:55 +08:00
|
|
|
|
2001-09-02 01:10:43 +08:00
|
|
|
{"( 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,
|
|
|
|
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,
|
|
|
|
NULL},
|
|
|
|
|
2000-07-25 05:29:30 +08:00
|
|
|
{NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL}
|
2000-01-30 03:43:19 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
int
|
|
|
|
schema_init( void )
|
|
|
|
{
|
|
|
|
int res;
|
|
|
|
int i;
|
|
|
|
|
2000-05-16 04:04:36 +08:00
|
|
|
/* we should only be called once (from main) */
|
|
|
|
assert( schema_init_done == 0 );
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
|
|
|
|
res = register_syntax( syntax_defs[i].sd_desc,
|
2001-07-22 07:02:06 +08:00
|
|
|
syntax_defs[i].sd_flags,
|
|
|
|
syntax_defs[i].sd_validate,
|
|
|
|
syntax_defs[i].sd_normalize,
|
2000-05-25 06:20:03 +08:00
|
|
|
syntax_defs[i].sd_pretty
|
|
|
|
#ifdef SLAPD_BINARY_CONVERSION
|
|
|
|
,
|
2001-07-22 07:02:06 +08:00
|
|
|
syntax_defs[i].sd_ber2str,
|
2000-05-25 06:20:03 +08:00
|
|
|
syntax_defs[i].sd_str2ber
|
|
|
|
#endif
|
|
|
|
);
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
if ( res ) {
|
|
|
|
fprintf( stderr, "schema_init: Error registering syntax %s\n",
|
|
|
|
syntax_defs[i].sd_desc );
|
2000-05-25 07:27:33 +08:00
|
|
|
return LDAP_OTHER;
|
2000-01-30 03:43:19 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
|
2000-02-15 04:57:34 +08:00
|
|
|
if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) {
|
|
|
|
fprintf( stderr,
|
|
|
|
"schema_init: Ingoring unusable matching rule %s\n",
|
|
|
|
mrule_defs[i].mrd_desc );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2000-01-30 03:43:19 +08:00
|
|
|
res = register_matching_rule(
|
|
|
|
mrule_defs[i].mrd_desc,
|
2000-02-15 04:57:34 +08:00
|
|
|
mrule_defs[i].mrd_usage,
|
2000-01-30 03:43:19 +08:00
|
|
|
mrule_defs[i].mrd_convert,
|
|
|
|
mrule_defs[i].mrd_normalize,
|
2001-07-22 07:02:06 +08:00
|
|
|
mrule_defs[i].mrd_match,
|
2000-01-31 09:49:44 +08:00
|
|
|
mrule_defs[i].mrd_indexer,
|
2000-07-25 05:29:30 +08:00
|
|
|
mrule_defs[i].mrd_filter,
|
|
|
|
mrule_defs[i].mrd_associated );
|
2000-01-30 03:43:19 +08:00
|
|
|
|
|
|
|
if ( res ) {
|
|
|
|
fprintf( stderr,
|
|
|
|
"schema_init: Error registering matching rule %s\n",
|
|
|
|
mrule_defs[i].mrd_desc );
|
2000-05-25 07:27:33 +08:00
|
|
|
return LDAP_OTHER;
|
2000-01-30 03:43:19 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
schema_init_done = 1;
|
2000-05-25 07:27:33 +08:00
|
|
|
return LDAP_SUCCESS;
|
2000-01-30 03:43:19 +08:00
|
|
|
}
|
2001-11-07 09:03:49 +08:00
|
|
|
|
|
|
|
void
|
|
|
|
schema_destroy( void )
|
|
|
|
{
|
|
|
|
oc_destroy();
|
|
|
|
at_destroy();
|
|
|
|
mr_destroy();
|
|
|
|
syn_destroy();
|
|
|
|
}
|