mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
433d9388be
Add syntax normalizer, separate from matching rule normalizer. with mr normalizer defaulting to syntax normalizer. This allows for more consistent handling of some syntaxes, such as directoryString (where all matches should ignore leading, trailing, and other extra spaces).
309 lines
5.5 KiB
C
309 lines
5.5 KiB
C
/* value.c - routines for dealing with values */
|
|
/* $OpenLDAP$ */
|
|
/*
|
|
* Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
|
|
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
|
|
*/
|
|
|
|
#include "portable.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <ac/ctype.h>
|
|
#include <ac/socket.h>
|
|
#include <ac/string.h>
|
|
#include <ac/time.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include "slap.h"
|
|
|
|
int
|
|
value_add(
|
|
struct berval ***vals,
|
|
struct berval **addvals
|
|
)
|
|
{
|
|
int n, nn, i, j;
|
|
|
|
for ( nn = 0; addvals != NULL && addvals[nn] != NULL; nn++ )
|
|
; /* NULL */
|
|
|
|
if ( *vals == NULL ) {
|
|
*vals = (struct berval **) ch_malloc( (nn + 1)
|
|
* sizeof(struct berval *) );
|
|
n = 0;
|
|
} else {
|
|
for ( n = 0; (*vals)[n] != NULL; n++ )
|
|
; /* NULL */
|
|
*vals = (struct berval **) ch_realloc( (char *) *vals,
|
|
(n + nn + 1) * sizeof(struct berval *) );
|
|
}
|
|
|
|
for ( i = 0, j = 0; i < nn; i++ ) {
|
|
if ( addvals[i]->bv_len > 0 ) {
|
|
(*vals)[n + j] = ber_bvdup( addvals[i] );
|
|
if( (*vals)[n + j++] == NULL ) break;
|
|
}
|
|
}
|
|
(*vals)[n + j] = NULL;
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
#ifdef SLAPD_SCHEMA_NOT_COMPAT
|
|
/* not used */
|
|
#else
|
|
int
|
|
value_add_fast(
|
|
struct berval ***vals,
|
|
struct berval **addvals,
|
|
int nvals,
|
|
int naddvals,
|
|
int *maxvals
|
|
)
|
|
{
|
|
int need, i, j;
|
|
|
|
if ( *maxvals == 0 ) {
|
|
*maxvals = 1;
|
|
}
|
|
need = nvals + naddvals + 1;
|
|
while ( *maxvals < need ) {
|
|
*maxvals *= 2;
|
|
*vals = (struct berval **) ch_realloc( (char *) *vals,
|
|
*maxvals * sizeof(struct berval *) );
|
|
}
|
|
|
|
for ( i = 0, j = 0; i < naddvals; i++ ) {
|
|
if ( addvals[i]->bv_len > 0 ) {
|
|
(*vals)[nvals + j] = ber_bvdup( addvals[i] );
|
|
if( (*vals)[nvals + j] != NULL ) j++;
|
|
}
|
|
}
|
|
(*vals)[nvals + j] = NULL;
|
|
|
|
return( 0 );
|
|
}
|
|
#endif
|
|
|
|
#ifdef SLAPD_SCHEMA_NOT_COMPAT
|
|
int
|
|
value_normalize(
|
|
AttributeDescription *ad,
|
|
unsigned usage,
|
|
struct berval *in,
|
|
struct berval **out,
|
|
const char **text )
|
|
{
|
|
int rc;
|
|
MatchingRule *mr;
|
|
|
|
switch( usage & SLAP_MR_TYPE_MASK ) {
|
|
case SLAP_MR_NONE:
|
|
case SLAP_MR_EQUALITY:
|
|
mr = ad->ad_type->sat_equality;
|
|
break;
|
|
case SLAP_MR_ORDERING:
|
|
mr = ad->ad_type->sat_ordering;
|
|
break;
|
|
case SLAP_MR_SUBSTR:
|
|
mr = ad->ad_type->sat_substr;
|
|
break;
|
|
case SLAP_MR_EXT:
|
|
default:
|
|
assert( 0 );
|
|
*text = "internal error";
|
|
return LDAP_OTHER;
|
|
}
|
|
|
|
if( mr == NULL ) {
|
|
*text = "inappropriate matching request";
|
|
return LDAP_INAPPROPRIATE_MATCHING;
|
|
}
|
|
|
|
/* we only support equality matching of binary attributes */
|
|
if( slap_ad_is_binary( ad ) && usage != SLAP_MR_EQUALITY ) {
|
|
*text = "inappropriate binary matching";
|
|
return LDAP_INAPPROPRIATE_MATCHING;
|
|
}
|
|
|
|
if( mr->smr_normalize ) {
|
|
rc = (mr->smr_normalize)( usage,
|
|
ad->ad_type->sat_syntax,
|
|
mr, in, out );
|
|
|
|
if( rc != LDAP_SUCCESS ) {
|
|
*text = "unable to normalize value";
|
|
return LDAP_INVALID_SYNTAX;
|
|
}
|
|
|
|
} else if ( mr->smr_syntax->ssyn_normalize ) {
|
|
rc = (mr->smr_syntax->ssyn_normalize)(
|
|
ad->ad_type->sat_syntax,
|
|
in, out );
|
|
|
|
if( rc != LDAP_SUCCESS ) {
|
|
*text = "unable to normalize value";
|
|
return LDAP_INVALID_SYNTAX;
|
|
}
|
|
|
|
} else {
|
|
*out = ber_bvdup( in );
|
|
}
|
|
|
|
return LDAP_SUCCESS;
|
|
}
|
|
|
|
#else
|
|
void
|
|
value_normalize(
|
|
char *s,
|
|
int syntax
|
|
)
|
|
{
|
|
char *d, *save;
|
|
|
|
if ( ! (syntax & SYNTAX_CIS) ) {
|
|
return;
|
|
}
|
|
|
|
if ( syntax & SYNTAX_DN ) {
|
|
(void) dn_normalize( s );
|
|
return;
|
|
}
|
|
|
|
save = s;
|
|
for ( d = s; *s; s++ ) {
|
|
if ( (syntax & SYNTAX_TEL) && (*s == ' ' || *s == '-') ) {
|
|
continue;
|
|
}
|
|
*d++ = TOUPPER( (unsigned char) *s );
|
|
}
|
|
*d = '\0';
|
|
}
|
|
#endif
|
|
|
|
#ifdef SLAPD_SCHEMA_NOT_COMPAT
|
|
int
|
|
value_match(
|
|
int *match,
|
|
AttributeDescription *ad,
|
|
MatchingRule *mr,
|
|
struct berval *v1, /* (unnormalized) stored value */
|
|
struct berval *v2, /* (normalized) asserted value */
|
|
const char ** text )
|
|
{
|
|
int rc;
|
|
int usage = 0;
|
|
struct berval *nv1 = NULL;
|
|
|
|
if( ad->ad_type->sat_syntax->ssyn_normalize ) {
|
|
rc = ad->ad_type->sat_syntax->ssyn_normalize(
|
|
ad->ad_type->sat_syntax, v1, &nv1 );
|
|
|
|
if( rc != LDAP_SUCCESS ) {
|
|
return LDAP_INAPPROPRIATE_MATCHING;
|
|
}
|
|
}
|
|
|
|
if( !mr->smr_match ) {
|
|
return LDAP_INAPPROPRIATE_MATCHING;
|
|
}
|
|
|
|
rc = (mr->smr_match)( match, usage,
|
|
ad->ad_type->sat_syntax,
|
|
mr,
|
|
nv1 != NULL ? nv1 : v1,
|
|
v2 );
|
|
|
|
ber_bvfree( nv1 );
|
|
return rc;
|
|
}
|
|
|
|
#else
|
|
int
|
|
value_cmp(
|
|
struct berval *v1,
|
|
struct berval *v2,
|
|
int syntax,
|
|
int normalize /* 1 => arg 1; 2 => arg 2; 3 => both */
|
|
)
|
|
{
|
|
int rc;
|
|
|
|
if ( normalize & 1 ) {
|
|
v1 = ber_bvdup( v1 );
|
|
value_normalize( v1->bv_val, syntax );
|
|
}
|
|
if ( normalize & 2 ) {
|
|
v2 = ber_bvdup( v2 );
|
|
value_normalize( v2->bv_val, syntax );
|
|
}
|
|
|
|
switch ( syntax ) {
|
|
case SYNTAX_CIS:
|
|
case (SYNTAX_CIS | SYNTAX_TEL):
|
|
case (SYNTAX_CIS | SYNTAX_DN):
|
|
rc = strcasecmp( v1->bv_val, v2->bv_val );
|
|
break;
|
|
|
|
case SYNTAX_CES:
|
|
rc = strcmp( v1->bv_val, v2->bv_val );
|
|
break;
|
|
|
|
default: /* Unknown syntax */
|
|
case SYNTAX_BIN:
|
|
rc = (v1->bv_len == v2->bv_len
|
|
? memcmp( v1->bv_val, v2->bv_val, v1->bv_len )
|
|
: v1->bv_len > v2->bv_len ? 1 : -1);
|
|
break;
|
|
}
|
|
|
|
if ( normalize & 1 ) {
|
|
ber_bvfree( v1 );
|
|
}
|
|
if ( normalize & 2 ) {
|
|
ber_bvfree( v2 );
|
|
}
|
|
|
|
return( rc );
|
|
}
|
|
#endif
|
|
|
|
#ifdef SLAPD_SCHEMA_NOT_COMPAT
|
|
int value_find(
|
|
AttributeDescription *ad,
|
|
MatchingRule *mr,
|
|
struct berval **vals,
|
|
struct berval *val,
|
|
const char ** text )
|
|
#else
|
|
int
|
|
value_find(
|
|
struct berval **vals,
|
|
struct berval *v,
|
|
int syntax,
|
|
int normalize )
|
|
#endif
|
|
{
|
|
int i;
|
|
|
|
for ( i = 0; vals[i] != NULL; i++ ) {
|
|
#ifdef SLAPD_SCHEMA_NOT_COMPAT
|
|
int rc;
|
|
int match;
|
|
rc = value_match( &match, ad, mr, vals[i], val, text );
|
|
|
|
if( rc == LDAP_SUCCESS && match == 0 )
|
|
#else
|
|
if ( value_cmp( vals[i], v, syntax, normalize ) == 0 )
|
|
#endif
|
|
{
|
|
return LDAP_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return LDAP_NO_SUCH_ATTRIBUTE;
|
|
}
|