Commit e2ec62f0 authored by Pierangelo Masarati's avatar Pierangelo Masarati
Browse files

add matchingRuleUse to schema; use a berval instead of _oidlen in syntax and matching rule

parent c76b3625
...@@ -208,6 +208,42 @@ at_destroy( void ) ...@@ -208,6 +208,42 @@ at_destroy( void )
ad_destroy(slap_schema.si_at_undefined->sat_ad); ad_destroy(slap_schema.si_at_undefined->sat_ad);
} }
int
at_start( AttributeType **at )
{
assert( at );
*at = attr_list;
return (*at != NULL);
}
int
at_next( AttributeType **at )
{
assert( at );
#if 1 /* pedantic check */
{
AttributeType *tmp;
for ( tmp = attr_list; tmp; tmp = tmp->sat_next ) {
if ( tmp == *at ) {
break;
}
}
assert( tmp );
}
#endif
*at = (*at)->sat_next;
return (*at != NULL);
}
static int static int
at_insert( at_insert(
AttributeType *sat, AttributeType *sat,
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "slap.h" #include "slap.h"
#include "ldap_pvt.h" #include "ldap_pvt.h"
#include "../../libraries/libldap/ldap-int.h"
struct mindexrec { struct mindexrec {
struct berval mir_name; struct berval mir_name;
...@@ -23,6 +24,7 @@ struct mindexrec { ...@@ -23,6 +24,7 @@ struct mindexrec {
static Avlnode *mr_index = NULL; static Avlnode *mr_index = NULL;
static MatchingRule *mr_list = NULL; static MatchingRule *mr_list = NULL;
static MatchingRuleUse *mru_list = NULL;
static int static int
mr_index_cmp( mr_index_cmp(
...@@ -76,6 +78,7 @@ mr_destroy( void ) ...@@ -76,6 +78,7 @@ mr_destroy( void )
avl_free(mr_index, ldap_memfree); avl_free(mr_index, ldap_memfree);
for (m=mr_list; m; m=n) { for (m=mr_list; m; m=n) {
n = m->smr_next; n = m->smr_next;
ch_free( m->smr_str.bv_val );
ldap_matchingrule_free((LDAPMatchingRule *)m); ldap_matchingrule_free((LDAPMatchingRule *)m);
} }
} }
...@@ -149,6 +152,11 @@ mr_add( ...@@ -149,6 +152,11 @@ mr_add(
smr = (MatchingRule *) ch_calloc( 1, sizeof(MatchingRule) ); smr = (MatchingRule *) ch_calloc( 1, sizeof(MatchingRule) );
AC_MEMCPY( &smr->smr_mrule, mr, sizeof(LDAPMatchingRule)); AC_MEMCPY( &smr->smr_mrule, mr, sizeof(LDAPMatchingRule));
/*
* note: smr_bvoid uses the same memory of smr_mrule.mr_oid;
* smr_oidlen is #defined as smr_bvoid.bv_len
*/
smr->smr_bvoid.bv_val = smr->smr_mrule.mr_oid;
smr->smr_oidlen = strlen( mr->mr_oid ); smr->smr_oidlen = strlen( mr->mr_oid );
smr->smr_usage = def->mrd_usage; smr->smr_usage = def->mrd_usage;
smr->smr_convert = def->mrd_convert; smr->smr_convert = def->mrd_convert;
...@@ -173,7 +181,6 @@ mr_add( ...@@ -173,7 +181,6 @@ mr_add(
return code; return code;
} }
int int
register_matching_rule( register_matching_rule(
slap_mrule_defs_rec *def ) slap_mrule_defs_rec *def )
...@@ -252,18 +259,287 @@ register_matching_rule( ...@@ -252,18 +259,287 @@ register_matching_rule(
return( 0 ); return( 0 );
} }
void
mru_destroy( void )
{
MatchingRuleUse *m, *n;
for (m=mru_list; m; m=n) {
n = m->smru_next;
if ( m->smru_str.bv_val ) {
ch_free( m->smru_str.bv_val );
}
/* memory borrowed from m->smru_mr */
m->smru_oid = NULL;
m->smru_names = NULL;
m->smru_desc = NULL;
/* free what's left (basically
* smru_mruleuse.mru_applies_oids) */
ldap_matchingruleuse_free((LDAPMatchingRuleUse *)m);
}
}
/*
* Appends a string to an array of char *,
* and returns the newly allocated char **.
* Maybe we can find a substitute, or borrow
* a helper from somewhere else
*/
static char **
ch_append( char **array, char *value )
{
int cnt;
char **tmp;
if ( array == NULL ) {
cnt = 0;
} else {
for ( cnt = 0; array[ cnt ]; cnt++ )
/* NO OP */ ;
}
tmp = LDAP_REALLOC( array, ( cnt + 2 ) * sizeof( char * ) );
tmp[ cnt++ ] = ch_strdup( value );
tmp[ cnt ] = NULL;
return tmp;
}
int
matching_rule_use_init( void )
{
MatchingRule *mr;
MatchingRuleUse **mru_ptr = &mru_list;
#define MR_TYPE_MASK ( SLAP_MR_TYPE_MASK & ~SLAP_MR_EXT )
#define MR_TYPE_SUBTYPE_MASK ( MR_TYPE_MASK | SLAP_MR_SUBTYPE_MASK )
#if 0 /* all types regardless of EXT */
#define MR_TYPE(x) ( (x) & MR_TYPE_MASK )
#define MR_TYPE_SUBTYPE(x) ( (x) & MR_TYPE_SUBTYPE_MASK )
#else /* only those marked as EXT (as per RFC 2252) */
#define MR_TYPE(x) ( ( (x) & SLAP_MR_EXT ) ? ( (x) & MR_TYPE_MASK ) : SLAP_MR_NONE )
#define MR_TYPE_SUBTYPE(x) ( ( (x) & SLAP_MR_EXT ) ? ( (x) & MR_TYPE_SUBTYPE_MASK ) : SLAP_MR_NONE )
#endif
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, INFO, "matching_rule_use_init\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "matching_rule_use_init\n", 0, 0, 0 );
#endif
for ( mr = mr_list; mr; mr = mr->smr_next ) {
slap_mask_t um = MR_TYPE( mr->smr_usage );
slap_mask_t usm = MR_TYPE_SUBTYPE( mr->smr_usage );
AttributeType *at;
MatchingRuleUse _mru, *mru = &_mru;
mr->smr_mru = NULL;
/* hide rules marked as HIDE */
if ( mr->smr_usage & SLAP_MR_HIDE ) {
continue;
}
/* hide rules with no type */
if ( um == SLAP_MR_NONE ) {
continue;
}
memset( mru, 0, sizeof( MatchingRuleUse ) );
/*
* Note: we're using the same values of the corresponding
* MatchingRule structure; maybe we'd copy them ...
*/
mru->smru_mr = mr;
mru->smru_obsolete = mr->smr_obsolete;
mru->smru_applies_oids = NULL;
mru->smru_next = NULL;
mru->smru_oid = mr->smr_oid;
mru->smru_names = mr->smr_names;
mru->smru_desc = mr->smr_desc;
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, INFO, " %s (%s): ",
mru->smru_oid,
mru->smru_names ? mru->smru_names[ 0 ] : "", 0 );
#else
Debug( LDAP_DEBUG_TRACE, " %s (%s): ",
mru->smru_oid,
mru->smru_names ? mru->smru_names[ 0 ] : "", 0 );
#endif
switch ( um ) {
case SLAP_MR_EQUALITY:
at = NULL;
if ( usm == SLAP_MR_EQUALITY_APPROX ) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, INFO, "APPROX%s\n",
( mr->smr_usage & SLAP_MR_EXT ) ? " (EXT)" : "",
0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "APPROX%s\n",
( mr->smr_usage & SLAP_MR_EXT ) ? " (EXT)" : "",
0, 0 );
#endif
for ( at_start( &at ); at; at_next( &at ) ) {
if ( mr == at->sat_approx ) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, INFO, " %s (%s)\n",
at->sat_oid,
at->sat_cname.bv_val, 0 );
#else
Debug( LDAP_DEBUG_TRACE, " %s (%s)\n",
at->sat_oid,
at->sat_cname.bv_val, 0 );
#endif
mru->smru_applies_oids
= ch_append( mru->smru_applies_oids, at->sat_oid );
}
}
} else {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, INFO, "EQUALITY%s\n",
( mr->smr_usage & SLAP_MR_EXT ) ? " (EXT)" : "",
0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "EQUALITY%s\n",
( mr->smr_usage & SLAP_MR_EXT ) ? " (EXT)" : "",
0, 0 );
#endif
for ( at_start( &at ); at; at_next( &at ) ) {
if ( mr == at->sat_equality ) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, INFO, " %s (%s)\n",
at->sat_oid,
at->sat_cname.bv_val, 0 );
#else
Debug( LDAP_DEBUG_TRACE, " %s (%s)\n",
at->sat_oid,
at->sat_cname.bv_val, 0 );
#endif
mru->smru_applies_oids
= ch_append( mru->smru_applies_oids, at->sat_oid );
}
}
}
break;
case SLAP_MR_ORDERING:
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, INFO, "ORDERING%s\n",
( mr->smr_usage & SLAP_MR_EXT ) ? " (EXT)" : "",
0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "ORDERING%s\n",
( mr->smr_usage & SLAP_MR_EXT ) ? " (EXT)" : "",
0, 0 );
#endif
at = NULL;
for ( at_start( &at ); at; at_next( &at ) ) {
if ( mr == at->sat_ordering ) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, INFO, " %s (%s)\n",
at->sat_oid,
at->sat_cname.bv_val, 0 );
#else
Debug( LDAP_DEBUG_TRACE, " %s (%s)\n",
at->sat_oid,
at->sat_cname.bv_val, 0 );
#endif
mru->smru_applies_oids
= ch_append( mru->smru_applies_oids, at->sat_oid );
}
}
break;
case SLAP_MR_SUBSTR:
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, INFO, "SUBSTR%s\n",
( mr->smr_usage & SLAP_MR_EXT ) ? " (EXT)" : "",
0, 0 );
#else
Debug( LDAP_DEBUG_TRACE, "SUBSTR%s\n",
( mr->smr_usage & SLAP_MR_EXT ) ? " (EXT)" : "",
0, 0 );
#endif
at = NULL;
for ( at_start( &at ); at; at_next( &at ) ) {
if ( mr == at->sat_substr ) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, INFO, " %s (%s)\n",
at->sat_oid,
at->sat_cname.bv_val, 0 );
#else
Debug( LDAP_DEBUG_TRACE, " %s (%s)\n",
at->sat_oid,
at->sat_cname.bv_val, 0 );
#endif
mru->smru_applies_oids
= ch_append( mru->smru_applies_oids, at->sat_oid );
}
}
break;
default:
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR, " unknown matching rule type "
"(type mask %d, subtype mask %d%s)\n", um, usm,
( mr->smr_usage & SLAP_MR_EXT ) ? ", EXT" : "" );
#else
Debug( LDAP_DEBUG_ANY, " unknown matching rule type "
"(type mask %d, subtype mask %d%s)\n", um, usm,
( mr->smr_usage & SLAP_MR_EXT ) ? ", EXT" : "" );
#endif
fprintf ( stderr, " %d (%d)\n", um, usm );
assert( 0 );
}
/*
* Note: the matchingRules that are not used
* by any attributeType are not listed as
* matchingRuleUse
*/
if ( mru->smru_applies_oids != NULL ) {
#ifdef NEW_LOGGING
{
char *str = ldap_matchingruleuse2str( &mru->smru_mruleuse );
LDAP_LOG( OPERATION, INFO, "matchingRuleUse: %s\n", str, 0, 0 );
ldap_memfree( str );
}
#else
{
char *str = ldap_matchingruleuse2str( &mru->smru_mruleuse );
Debug( LDAP_DEBUG_TRACE, "matchingRuleUse: %s\n", str, 0, 0 );
ldap_memfree( str );
}
#endif
mru = (MatchingRuleUse *)LDAP_MALLOC( sizeof( MatchingRuleUse ) );
mr->smr_mru = mru;
*mru = _mru;
*mru_ptr = mru;
mru_ptr = &mru->smru_next;
}
}
return( 0 );
}
#if defined( SLAPD_SCHEMA_DN ) #if defined( SLAPD_SCHEMA_DN )
int mr_schema_info( Entry *e ) int mr_schema_info( Entry *e )
{ {
struct berval vals[2];
MatchingRule *mr; MatchingRule *mr;
AttributeDescription *ad_matchingRules = slap_schema.si_ad_matchingRules; AttributeDescription *ad_matchingRules = slap_schema.si_ad_matchingRules;
vals[1].bv_val = NULL;
for ( mr = mr_list; mr; mr = mr->smr_next ) { for ( mr = mr_list; mr; mr = mr->smr_next ) {
if ( mr->smr_usage & SLAP_MR_HIDE ) { if ( mr->smr_usage & SLAP_MR_HIDE ) {
/* skip hidden rules */ /* skip hidden rules */
...@@ -275,21 +551,44 @@ int mr_schema_info( Entry *e ) ...@@ -275,21 +551,44 @@ int mr_schema_info( Entry *e )
continue; continue;
} }
if ( ldap_matchingrule2bv( &mr->smr_mrule, vals ) == NULL ) { if ( mr->smr_str.bv_val == NULL ) {
return -1; if ( ldap_matchingrule2bv( &mr->smr_mrule, &mr->smr_str ) == NULL ) {
return -1;
}
} }
#if 0 #if 0
Debug( LDAP_DEBUG_TRACE, "Merging mr [%ld] %s\n", Debug( LDAP_DEBUG_TRACE, "Merging mr [%lu] %s\n",
(long) vals[0].bv_len, vals[0].bv_val, 0 ); mr->smr_str.bv_len, mr->smr_str.bv_val, 0 );
#endif #endif
attr_merge( e, ad_matchingRules, vals ); attr_merge_one( e, ad_matchingRules, &mr->smr_str );
ldap_memfree( vals[0].bv_val );
} }
return 0; return 0;
} }
int mru_schema_info( Entry *e ) int mru_schema_info( Entry *e )
{ {
MatchingRuleUse *mru;
AttributeDescription *ad_matchingRuleUse
= slap_schema.si_ad_matchingRuleUse;
for ( mru = mru_list; mru; mru = mru->smru_next ) {
assert( !( mru->smru_usage & SLAP_MR_HIDE ) );
if ( mru->smru_str.bv_val == NULL ) {
if ( ldap_matchingruleuse2bv( &mru->smru_mruleuse, &mru->smru_str )
== NULL ) {
return -1;
}
}
#if 0
Debug( LDAP_DEBUG_TRACE, "Merging mru [%lu] %s\n",
mru->smru_str.bv_len, mru->smru_str.bv_val, 0 );
#endif
attr_merge_one( e, ad_matchingRuleUse, &mru->smru_str );
}
return 0; return 0;
} }
......
...@@ -115,6 +115,9 @@ LDAP_SLAPD_F (int) is_at_syntax LDAP_P(( ...@@ -115,6 +115,9 @@ LDAP_SLAPD_F (int) is_at_syntax LDAP_P((
AttributeType *at, AttributeType *at,
const char *oid )); const char *oid ));
LDAP_SLAPD_F (int) at_start LDAP_P(( AttributeType **at ));
LDAP_SLAPD_F (int) at_next LDAP_P(( AttributeType **at ));
/* /*
* attr.c * attr.c
*/ */
...@@ -621,6 +624,9 @@ LDAP_SLAPD_F (void) mr_destroy LDAP_P(( void )); ...@@ -621,6 +624,9 @@ LDAP_SLAPD_F (void) mr_destroy LDAP_P(( void ));
LDAP_SLAPD_F (int) register_matching_rule LDAP_P(( LDAP_SLAPD_F (int) register_matching_rule LDAP_P((
slap_mrule_defs_rec *def )); slap_mrule_defs_rec *def ));
LDAP_SLAPD_F (void) mru_destroy LDAP_P(( void ));
LDAP_SLAPD_F (int) matching_rule_use_init LDAP_P(( void ));
LDAP_SLAPD_F (int) mr_schema_info( Entry *e ); LDAP_SLAPD_F (int) mr_schema_info( Entry *e );
LDAP_SLAPD_F (int) mru_schema_info( Entry *e ); LDAP_SLAPD_F (int) mru_schema_info( Entry *e );
......
...@@ -513,7 +513,7 @@ Directory String - ...@@ -513,7 +513,7 @@ Directory String -
In later versions, more CHOICEs were added. In all cases the string In later versions, more CHOICEs were added. In all cases the string
must be non-empty. must be non-empty.
In LDPAv3, a directory string is a UTF-8 encoded UCS string. In LDAPv3, a directory string is a UTF-8 encoded UCS string.
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.
...@@ -4803,5 +4803,6 @@ schema_destroy( void ) ...@@ -4803,5 +4803,6 @@ schema_destroy( void )
for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ ) for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ )
*mr_ptr[i].mr = NULL; *mr_ptr[i].mr = NULL;
mr_destroy(); mr_destroy();
mru_destroy();
syn_destroy(); syn_destroy();
} }
...@@ -811,7 +811,7 @@ slap_schema_load( void ) ...@@ -811,7 +811,7 @@ slap_schema_load( void )
*synp = syn_find( syn_map[i].sssm_name ); *synp = syn_find( syn_map[i].sssm_name );
if( *synp == NULL ) { if( *synp == NULL ) {
fprintf( stderr, "slap_schema_check: " fprintf( stderr, "slap_schema_load: "
"No syntax \"%s\" defined in schema\n", "No syntax \"%s\" defined in schema\n",
syn_map[i].sssm_name ); syn_map[i].sssm_name );
return LDAP_INVALID_SYNTAX; return LDAP_INVALID_SYNTAX;
...@@ -827,7 +827,7 @@ slap_schema_load( void ) ...@@ -827,7 +827,7 @@ slap_schema_load( void )
*mrp = mr_find( mr_map[i].ssmm_name ); *mrp = mr_find( mr_map[i].ssmm_name );
if( *mrp == NULL ) { if( *mrp == NULL ) {
fprintf( stderr, "slap_schema_check: " fprintf( stderr, "slap_schema_load: "
"No matching rule \"%s\" defined in schema\n", "No matching rule \"%s\" defined in schema\n",
mr_map[i].ssmm_name ); mr_map[i].ssmm_name );
return LDAP_INAPPROPRIATE_MATCHING; return LDAP_INAPPROPRIATE_MATCHING;
...@@ -877,7 +877,7 @@ slap_schema_load( void ) ...@@ -877,7 +877,7 @@ slap_schema_load( void )
rc = slap_str2ad( ad_map[i].ssam_name, adp, &text ); rc = slap_str2ad( ad_map[i].ssam_name, adp, &text );
if( rc != LDAP_SUCCESS ) { if( rc != LDAP_SUCCESS ) {
fprintf( stderr, "slap_schema_check: " fprintf( stderr, "slap_schema_load: "
"No attribute \"%s\" defined in schema\n", "No attribute \"%s\" defined in schema\n",
ad_map[i].ssam_name ); ad_map[i].ssam_name );
return rc; return rc;
...@@ -961,7 +961,7 @@ slap_schema_load( void ) ...@@ -961,7 +961,7 @@ slap_schema_load( void )
*ocp = oc_find( oc_map[i].ssom_name ); *ocp = oc_find( oc_map[i].ssom_name );
if( *ocp == NULL ) { if( *ocp == NULL ) {
fprintf( stderr, "slap_schema_check: " fprintf( stderr, "slap_schema_load: "
"No objectClass \"%s\" defined in schema\n", "No objectClass \"%s\" defined in schema\n",
oc_map[i].ssom_name ); oc_map[i].ssom_name );
return LDAP_OBJECT_CLASS_VIOLATION; return LDAP_OBJECT_CLASS_VIOLATION;
...@@ -988,6 +988,13 @@ slap_schema_check( void ) ...@@ -988,6 +988,13 @@ slap_schema_check( void )
/* we should only be called once after schema_init() was called */ /* we should only be called once after schema_init() was called */
assert( schema_init_done == 1 ); assert( schema_init_done == 1 );
/*
* cycle thru attributeTypes to build matchingRuleUse
*/
if ( matching_rule_use_init() ) {
return LDAP_OTHER;
}
++schema_init_done; ++schema_init_done;
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
......
...@@ -278,7 +278,16 @@ typedef struct slap_syntax { ...@@ -278,7 +278,16 @@ typedef struct slap_syntax {
#define ssyn_oid ssyn_syn.syn_oid #define ssyn_oid ssyn_syn.syn_oid
#define ssyn_desc ssyn_syn.syn_desc #define ssyn_desc ssyn_syn.syn_desc
#define ssyn_extensions ssyn_syn.syn_extensions #define ssyn_extensions ssyn_syn.syn_extensions
/*
* Note: the former
ber_len_t ssyn_oidlen; ber_len_t ssyn_oidlen;
* has been replaced by a struct berval that uses the value
* provided by ssyn_syn.syn_oid; a macro that expands to
* the bv_len field of the berval is provided for backward
* compatibility. CAUTION: NEVER FREE THE BERVAL
*/
struct berval ssyn_bvoid;
#define ssyn_oidlen ssyn_bvoid.bv_len
unsigned int ssyn_flags; unsigned int ssyn_flags;