Commit 840f3644 authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

SLAP_NVALUES: a couple of basic normalizers... but not working yet.

parent ca0ee4d9
...@@ -607,6 +607,20 @@ int slap_mods_check( ...@@ -607,6 +607,20 @@ int slap_mods_check(
} }
} }
/*
* a rough single value check... an additional check is needed
* to catch add of single value to existing single valued attribute
*/
if ((ml->sml_op == LDAP_MOD_ADD || ml->sml_op == LDAP_MOD_REPLACE)
&& nvals > 1 && is_at_single_value( ad->ad_type ))
{
snprintf( textbuf, textlen,
"%s: multiple values provided",
ml->sml_type.bv_val );
*text = textbuf;
return LDAP_CONSTRAINT_VIOLATION;
}
#ifdef SLAP_NVALUES #ifdef SLAP_NVALUES
if( nvals && ad->ad_type->sat_equality && if( nvals && ad->ad_type->sat_equality &&
ad->ad_type->sat_equality->smr_normalize ) ad->ad_type->sat_equality->smr_normalize )
...@@ -639,20 +653,6 @@ int slap_mods_check( ...@@ -639,20 +653,6 @@ int slap_mods_check(
ml->sml_nvalues[nvals].bv_len = 0; ml->sml_nvalues[nvals].bv_len = 0;
} }
#endif #endif
/*
* a rough single value check... an additional check is needed
* to catch add of single value to existing single valued attribute
*/
if ((ml->sml_op == LDAP_MOD_ADD || ml->sml_op == LDAP_MOD_REPLACE)
&& nvals > 1 && is_at_single_value( ad->ad_type ))
{
snprintf( textbuf, textlen,
"%s: multiple value provided",
ml->sml_type.bv_val );
*text = textbuf;
return LDAP_CONSTRAINT_VIOLATION;
}
} }
} }
......
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
/* TO BE DELETED */ /* TO BE DELETED */
#define SLAP_MR_DN_FOLD (0) #define SLAP_MR_DN_FOLD (0)
#define SLAP_MR_ASSOCIATED(mr, with) \
((mr) == (with) || (mr)->smr_associated == (with))
#define xUTF8StringNormalize NULL #define xUTF8StringNormalize NULL
#define xIA5StringNormalize NULL #define xIA5StringNormalize NULL
#define xtelephoneNumberNormalize NULL #define xtelephoneNumberNormalize NULL
...@@ -40,6 +43,23 @@ ...@@ -40,6 +43,23 @@
#define xnumericStringNormalize NULL #define xnumericStringNormalize NULL
#define xnameUIDNormalize NULL #define xnameUIDNormalize NULL
/* (new) normalization routines */
#define caseExactIA5Normalize IA5StringNormalize
#define caseIgnoreIA5Normalize IA5StringNormalize
#define caseExactNormalize UTF8StringNormalize
#define caseIgnoreNormalize UTF8StringNormalize
#define distinguishedNameNormalize NULL
#define integerNormalize NULL
#define integerFirstComponentNormalize NULL
#define numericStringNormalize NULL
#define objectIdentifierNormalize NULL
#define objectIdentifierFirstComponentNormalize NULL
#define generalizedTimeNormalize NULL
#define uniqueMemberNormalize NULL
#define bitStringNormalize NULL
#define telephoneNumberNormalize NULL
#define distinguishedNameMatch dnMatch #define distinguishedNameMatch dnMatch
#define distinguishedNameIndexer octetStringIndexer #define distinguishedNameIndexer octetStringIndexer
#define distinguishedNameFilter octetStringFilter #define distinguishedNameFilter octetStringFilter
...@@ -117,22 +137,6 @@ ...@@ -117,22 +137,6 @@
/* validatation routines */ /* validatation routines */
#define berValidate blobValidate #define berValidate blobValidate
/* (new) normalization routines */
#define caseExactNormalize NULL
#define caseExactIA5Normalize NULL
#define caseIgnoreNormalize NULL
#define caseIgnoreIA5Normalize NULL
#define distinguishedNameNormalize NULL
#define integerNormalize NULL
#define integerFirstComponentNormalize NULL
#define numericStringNormalize NULL
#define objectIdentifierNormalize NULL
#define objectIdentifierFirstComponentNormalize NULL
#define generalizedTimeNormalize NULL
#define uniqueMemberNormalize NULL
#define bitStringNormalize NULL
#define telephoneNumberNormalize NULL
/* approx matching rules */ /* approx matching rules */
#ifdef SLAP_NVALUES #ifdef SLAP_NVALUES
#define directoryStringApproxMatchOID NULL #define directoryStringApproxMatchOID NULL
...@@ -150,6 +154,23 @@ ...@@ -150,6 +154,23 @@
#ifndef SLAP_NVALUES #ifndef SLAP_NVALUES
/* (new) normalization routines */
#define caseExactNormalize NULL
#define caseExactIA5Normalize NULL
#define caseIgnoreNormalize NULL
#define caseIgnoreIA5Normalize NULL
#define distinguishedNameNormalize NULL
#define integerNormalize NULL
#define integerFirstComponentNormalize NULL
#define numericStringNormalize NULL
#define objectIdentifierNormalize NULL
#define objectIdentifierFirstComponentNormalize NULL
#define generalizedTimeNormalize NULL
#define uniqueMemberNormalize NULL
#define bitStringNormalize NULL
#define telephoneNumberNormalize NULL
/* matching routines */ /* matching routines */
#define bitStringMatch octetStringMatch #define bitStringMatch octetStringMatch
#define bitStringIndexer octetStringIndexer #define bitStringIndexer octetStringIndexer
...@@ -569,9 +590,10 @@ LDAP/X.500 string syntax / matching rules have a few oddities. This ...@@ -569,9 +590,10 @@ LDAP/X.500 string syntax / matching rules have a few oddities. This
comment attempts to detail how slapd(8) treats them. comment attempts to detail how slapd(8) treats them.
Summary: Summary:
StringSyntax X.500 LDAP Matching StringSyntax X.500 LDAP Matching/Comments
DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
PrintableString subset subset i/e + ignore insignificant spaces PrintableString subset subset i/e + ignore insignificant spaces
PrintableString subset subset i/e + ignore insignificant spaces
NumericString subset subset ignore all spaces NumericString subset subset ignore all spaces
IA5String ASCII ASCII i/e + ignore insignificant spaces IA5String ASCII ASCII i/e + ignore insignificant spaces
TeletexString T.61 T.61 i/e + ignore insignificant spaces TeletexString T.61 T.61 i/e + ignore insignificant spaces
...@@ -588,6 +610,7 @@ Directory String - ...@@ -588,6 +610,7 @@ Directory String -
must be non-empty. must be non-empty.
In LDAPv3, a directory string is a UTF-8 encoded UCS string. In LDAPv3, a directory string is a UTF-8 encoded UCS string.
A directory string cannot be zero length.
For matching, there are both case ignore and exact rules. Both For matching, there are both case ignore and exact rules. Both
also require that "insignificant" spaces be ignored. also require that "insignificant" spaces be ignored.
...@@ -643,7 +666,10 @@ UTF8StringValidate( ...@@ -643,7 +666,10 @@ UTF8StringValidate(
int len; int len;
unsigned char *u = in->bv_val; unsigned char *u = in->bv_val;
if( !in->bv_len ) return LDAP_INVALID_SYNTAX; if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
/* directory strings cannot be empty */
return LDAP_INVALID_SYNTAX;
}
for( count = in->bv_len; count > 0; count-=len, u+=len ) { for( count = in->bv_len; count > 0; count-=len, u+=len ) {
/* get the length indicated by the first byte */ /* get the length indicated by the first byte */
...@@ -683,12 +709,79 @@ UTF8StringValidate( ...@@ -683,12 +709,79 @@ UTF8StringValidate(
if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX; if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX;
} }
if( count != 0 ) return LDAP_INVALID_SYNTAX; if( count != 0 ) {
return LDAP_INVALID_SYNTAX;
}
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
#ifndef SLAP_NVALUES #ifdef SLAP_NVALUES
static int
UTF8StringNormalize(
slap_mask_t use,
Syntax *syntax,
MatchingRule *mr,
struct berval *val,
struct berval *normalized )
{
struct berval tmp, nvalue;
int flags;
int i, wasspace;
if( val->bv_val == NULL ) {
/* assume we're dealing with a syntax (e.g., UTF8String)
* which allows empty strings
*/
normalized->bv_len = 0;
normalized->bv_val = NULL;
return LDAP_SUCCESS;
}
flags = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactMatch )
? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD;
flags |= ( use & SLAP_MR_EQUALITY_APPROX == SLAP_MR_EQUALITY_APPROX )
? LDAP_UTF8_APPROX : 0;
val = UTF8bvnormalize( val, &tmp, flags );
if( val == NULL ) {
return LDAP_OTHER;
}
/* collapse spaces (in place) */
nvalue.bv_len = 0;
nvalue.bv_val = tmp.bv_val;
wasspace=1; /* trim leading spaces */
for( i=0; i<tmp.bv_len; i++) {
if ( ASCII_SPACE( tmp.bv_val[i] )) {
if( wasspace++ == 0 ) {
/* trim repeated spaces */
nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
}
} else {
wasspace = 0;
nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
}
}
if( nvalue.bv_len ) {
if( wasspace ) {
/* last character was a space, trim it */
--nvalue.bv_len;
}
nvalue.bv_val[nvalue.bv_len] = '\0';
} else {
/* string of all spaces is treated as one space */
nvalue.bv_val[0] = ' ';
nvalue.bv_val[1] = '\0';
nvalue.bv_len = 1;
}
return LDAP_SUCCESS;
}
#else
static int static int
xUTF8StringNormalize( xUTF8StringNormalize(
...@@ -2288,15 +2381,26 @@ IA5StringValidate( ...@@ -2288,15 +2381,26 @@ IA5StringValidate(
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
#ifndef SLAP_NVALUES #ifdef SLAP_NVALUES
static int
IA5StringNormalize(
slap_mask_t use,
Syntax *syntax,
MatchingRule *mr,
struct berval *val,
struct berval *normalized )
#else
static int static int
xIA5StringNormalize( xIA5StringNormalize(
Syntax *syntax, Syntax *syntax,
struct berval *val, struct berval *val,
struct berval *normalized ) struct berval *normalized )
#endif
{ {
char *p, *q; char *p, *q;
#ifdef SLAP_NVALUES
int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
#endif
assert( val->bv_len ); assert( val->bv_len );
...@@ -2318,6 +2422,13 @@ xIA5StringNormalize( ...@@ -2318,6 +2422,13 @@ xIA5StringNormalize(
while ( ASCII_SPACE( *p ) ) { while ( ASCII_SPACE( *p ) ) {
p++; p++;
} }
#ifdef SLAP_NVALUES
} else if ( casefold ) {
/* Most IA5 rules require casefolding */
*q++ = TOLOWER(*p++);
#endif
} else { } else {
*q++ = *p++; *q++ = *p++;
} }
...@@ -2351,6 +2462,8 @@ xIA5StringNormalize( ...@@ -2351,6 +2462,8 @@ xIA5StringNormalize(
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
#ifndef SLAP_NVALUES
static int static int
caseExactIA5Match( caseExactIA5Match(
int *matchp, int *matchp,
...@@ -4839,7 +4952,7 @@ static slap_mrule_defs_rec mrule_defs[] = { ...@@ -4839,7 +4952,7 @@ static slap_mrule_defs_rec mrule_defs[] = {
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
SLAP_MR_ORDERING, NULL, SLAP_MR_ORDERING, NULL,
NULL, NULL,
generalizedTimeOrderingMatch, generalizedTimeOrderingMatch, generalizedTimeNormalize, generalizedTimeOrderingMatch,
NULL, NULL, NULL, NULL,
NULL}, NULL},
......
...@@ -796,6 +796,8 @@ static struct slap_schema_mr_map { ...@@ -796,6 +796,8 @@ static struct slap_schema_mr_map {
char *ssmm_name; char *ssmm_name;
size_t ssmm_offset; size_t ssmm_offset;
} mr_map[] = { } mr_map[] = {
{ "caseExactIA5Match",
offsetof(struct slap_internal_schema, si_mr_caseExactIA5Match) },
{ "caseExactMatch", { "caseExactMatch",
offsetof(struct slap_internal_schema, si_mr_caseExactMatch) }, offsetof(struct slap_internal_schema, si_mr_caseExactMatch) },
{ "caseExactSubstringsMatch", { "caseExactSubstringsMatch",
...@@ -814,12 +816,14 @@ static struct slap_schema_syn_map { ...@@ -814,12 +816,14 @@ static struct slap_schema_syn_map {
char *sssm_name; char *sssm_name;
size_t sssm_offset; size_t sssm_offset;
} syn_map[] = { } syn_map[] = {
{ "1.3.6.1.4.1.1466.115.121.1.40", { "1.3.6.1.4.1.1466.115.121.1.15",
offsetof(struct slap_internal_schema, si_syn_octetString) }, offsetof(struct slap_internal_schema, si_syn_directoryString) },
{ "1.3.6.1.4.1.1466.115.121.1.12", { "1.3.6.1.4.1.1466.115.121.1.12",
offsetof(struct slap_internal_schema, si_syn_distinguishedName) }, offsetof(struct slap_internal_schema, si_syn_distinguishedName) },
{ "1.3.6.1.4.1.1466.115.121.1.27", { "1.3.6.1.4.1.1466.115.121.1.27",
offsetof(struct slap_internal_schema, si_syn_integer) }, offsetof(struct slap_internal_schema, si_syn_integer) },
{ "1.3.6.1.4.1.1466.115.121.1.40",
offsetof(struct slap_internal_schema, si_syn_octetString) },
{ NULL, 0 } { NULL, 0 }
}; };
......
...@@ -792,13 +792,15 @@ struct slap_internal_schema { ...@@ -792,13 +792,15 @@ struct slap_internal_schema {
MatchingRule *si_mr_distinguishedNameMatch; MatchingRule *si_mr_distinguishedNameMatch;
MatchingRule *si_mr_caseExactMatch; MatchingRule *si_mr_caseExactMatch;
MatchingRule *si_mr_caseExactSubstringsMatch; MatchingRule *si_mr_caseExactSubstringsMatch;
MatchingRule *si_mr_caseExactIA5Match;
MatchingRule *si_mr_integerMatch; MatchingRule *si_mr_integerMatch;
MatchingRule *si_mr_integerFirstComponentMatch; MatchingRule *si_mr_integerFirstComponentMatch;
/* Syntaxes */ /* Syntaxes */
Syntax *si_syn_octetString; Syntax *si_syn_directoryString;
Syntax *si_syn_distinguishedName; Syntax *si_syn_distinguishedName;
Syntax *si_syn_integer; Syntax *si_syn_integer;
Syntax *si_syn_octetString;
}; };
typedef struct slap_attr_assertion { typedef struct slap_attr_assertion {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment