From 05463503e8e8fc5aefc4e58e1b517e98bf8536d4 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Wed, 28 Apr 2004 20:10:21 +0000 Subject: [PATCH] ITS#3118: fix objectIdentifierFirstComponentMatch for schema elements --- servers/slapd/oc.c | 24 ++-- servers/slapd/proto-slap.h | 2 - servers/slapd/schema_init.c | 2 +- servers/slapd/schema_prep.c | 212 ++++++++++++++++++++++++++++++---- servers/slapd/slap.h | 18 ++- tests/scripts/test000-rootdse | 3 +- 6 files changed, 215 insertions(+), 46 deletions(-) diff --git a/servers/slapd/oc.c b/servers/slapd/oc.c index 52aa6e2e69..78ebaa7c60 100644 --- a/servers/slapd/oc.c +++ b/servers/slapd/oc.c @@ -33,7 +33,7 @@ int is_object_subclass( if( sub == NULL || sup == NULL ) return 0; -#if 1 +#if 0 #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ARGS, "is_object_subclass(%s,%s) %d\n", @@ -143,8 +143,7 @@ oc_index_cmp( { const struct oindexrec *oir1 = v_oir1, *oir2 = v_oir2; int i = oir1->oir_name.bv_len - oir2->oir_name.bv_len; - if (i) - return i; + if (i) return i; return strcasecmp( oir1->oir_name.bv_val, oir2->oir_name.bv_val ); } @@ -156,8 +155,7 @@ oc_index_name_cmp( const struct berval *name = v_name; const struct oindexrec *oir = v_oir; int i = name->bv_len - oir->oir_name.bv_len; - if (i) - return i; + if (i) return i; return strncasecmp( name->bv_val, oir->oir_name.bv_val, name->bv_len ); } @@ -358,8 +356,7 @@ oc_destroy( void ) static int oc_insert( ObjectClass *soc, - const char **err -) + const char **err ) { struct oindexrec *oir; char **names; @@ -378,7 +375,7 @@ oc_insert( assert( oir->oir_oc ); if ( avl_insert( &oc_index, (caddr_t) oir, - oc_index_cmp, avl_dup_error ) ) + oc_index_cmp, avl_dup_error ) ) { *err = soc->soc_oid; ldap_memfree(oir); @@ -401,7 +398,7 @@ oc_insert( assert( oir->oir_oc ); if ( avl_insert( &oc_index, (caddr_t) oir, - oc_index_cmp, avl_dup_error ) ) + oc_index_cmp, avl_dup_error ) ) { *err = *names; ldap_memfree(oir); @@ -422,8 +419,7 @@ int oc_add( LDAPObjectClass *oc, int user, - const char **err -) + const char **err ) { ObjectClass *soc; int code; @@ -501,16 +497,14 @@ oc_schema_info( Entry *e ) return -1; } - nval.bv_val = oc->soc_oid; - nval.bv_len = strlen(oc->soc_oid); + nval = oc->soc_cname; #if 0 Debug( LDAP_DEBUG_TRACE, "Merging oc [%ld] %s (%s)\n", (long) val.bv_len, val.bv_val, nval.bv_val ); #endif - if( attr_merge_one( e, ad_objectClasses, &val, &nval ) ) - { + if( attr_merge_one( e, ad_objectClasses, &val, &nval ) ) { return -1; } ldap_memfree( val.bv_val ); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 4f34534816..7eddb20a4b 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -1059,8 +1059,6 @@ LDAP_SLAPD_V( int ) schema_init_done; LDAP_SLAPD_F (int) slap_schema_init LDAP_P((void)); LDAP_SLAPD_F (void) schema_destroy LDAP_P(( void )); -LDAP_SLAPD_F( slap_syntax_validate_func ) numericoidValidate; - LDAP_SLAPD_F( slap_mr_indexer_func ) octetStringIndexer; LDAP_SLAPD_F( slap_mr_filter_func ) octetStringFilter; diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 4f501a0f71..ae59168b88 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -1502,7 +1502,7 @@ telephoneNumberNormalize( return LDAP_SUCCESS; } -int +static int numericoidValidate( Syntax *syntax, struct berval *in ) diff --git a/servers/slapd/schema_prep.c b/servers/slapd/schema_prep.c index 1baba5dcfb..fa91ccdc31 100644 --- a/servers/slapd/schema_prep.c +++ b/servers/slapd/schema_prep.c @@ -32,33 +32,181 @@ int schema_init_done = 0; struct slap_internal_schema slap_schema; -static int objectClassValidate( +static int +oidValidate( Syntax *syntax, struct berval *in ) { - ObjectClass *oc; - int rc = numericoidValidate( syntax, in ); - if ( rc ) return rc; + struct berval val = *in; - oc = oc_bvfind( in ); - if( oc == NULL ) return LDAP_INVALID_SYNTAX; + if( val.bv_len == 0 ) { + /* disallow empty strings */ + return LDAP_INVALID_SYNTAX; + } - return LDAP_SUCCESS; + if( DESC_LEADCHAR( val.bv_val[0] ) ) { + val.bv_val++; + val.bv_len--; + if ( val.bv_len == 0 ) return LDAP_SUCCESS; + + while( DESC_CHAR( val.bv_val[0] ) ) { + val.bv_val++; + val.bv_len--; + + if ( val.bv_len == 0 ) return LDAP_SUCCESS; + } + + } else { + while( OID_LEADCHAR( val.bv_val[0] ) ) { + if ( val.bv_len == 1 ) { + return LDAP_SUCCESS; + } + + if ( val.bv_val[0] == '0' ) { + break; + } + + val.bv_val++; + val.bv_len--; + + while ( OID_LEADCHAR( val.bv_val[0] )) { + val.bv_val++; + val.bv_len--; + + if ( val.bv_len == 0 ) { + return LDAP_SUCCESS; + } + } + + if( !OID_SEPARATOR( val.bv_val[0] )) { + break; + } + + val.bv_val++; + val.bv_len--; + } + } + + return LDAP_INVALID_SYNTAX; } + static int objectClassPretty( struct slap_syntax *syntax, struct berval * in, struct berval * out, void *ctx ) { - ObjectClass *oc = oc_bvfind( in ); + ObjectClass *oc; + + if( oidValidate( NULL, in )) return LDAP_INVALID_SYNTAX; + + oc = oc_bvfind( in ); if( oc == NULL ) return LDAP_INVALID_SYNTAX; ber_dupbv_x( out, &oc->soc_cname, ctx ); return LDAP_SUCCESS; } +static int +attributeTypeMatch( + int *matchp, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + void *assertedValue ) +{ + struct berval *a = (struct berval *) assertedValue; + AttributeType *at = at_bvfind( value ); + AttributeType *asserted = at_bvfind( a ); + + if( asserted == NULL ) { + if( OID_LEADCHAR( *a->bv_val ) ) { + /* OID form, return FALSE */ + *matchp = 1; + return LDAP_SUCCESS; + } + + /* desc form, return undefined */ + return LDAP_INVALID_SYNTAX; + } + + if ( at == NULL ) { + /* unrecognized stored value */ + return LDAP_INVALID_SYNTAX; + } + + *matchp = ( asserted != at ); + return LDAP_SUCCESS; +} + +static int +matchingRuleMatch( + int *matchp, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + void *assertedValue ) +{ + struct berval *a = (struct berval *) assertedValue; + MatchingRule *mrv = mr_bvfind( value ); + MatchingRule *asserted = mr_bvfind( a ); + + if( asserted == NULL ) { + if( OID_LEADCHAR( *a->bv_val ) ) { + /* OID form, return FALSE */ + *matchp = 1; + return LDAP_SUCCESS; + } + + /* desc form, return undefined */ + return LDAP_INVALID_SYNTAX; + } + + if ( mrv == NULL ) { + /* unrecognized stored value */ + return LDAP_INVALID_SYNTAX; + } + + *matchp = ( asserted != mrv ); + return LDAP_SUCCESS; +} + +static int +objectClassMatch( + int *matchp, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + void *assertedValue ) +{ + struct berval *a = (struct berval *) assertedValue; + ObjectClass *oc = oc_bvfind( value ); + ObjectClass *asserted = oc_bvfind( a ); + + if( asserted == NULL ) { + if( OID_LEADCHAR( *a->bv_val ) ) { + /* OID form, return FALSE */ + *matchp = 1; + return LDAP_SUCCESS; + } + + /* desc form, return undefined */ + return LDAP_INVALID_SYNTAX; + } + + if ( oc == NULL ) { + /* unrecognized stored value */ + return LDAP_INVALID_SYNTAX; + } + + *matchp = ( asserted != oc ); + return LDAP_SUCCESS; +} + static int objectSubClassMatch( int *matchp, @@ -293,7 +441,7 @@ static struct slap_schema_ad_map { "EQUALITY objectIdentifierMatch " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", NULL, SLAP_AT_FINAL, - objectClassValidate, objectClassPretty, + oidValidate, objectClassPretty, NULL, NULL, objectSubClassMatch, objectSubClassIndexer, objectSubClassFilter, offsetof(struct slap_internal_schema, si_ad_objectClass) }, @@ -305,7 +453,7 @@ static struct slap_schema_ad_map { "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 " "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", NULL, 0, - objectClassValidate, objectClassPretty, + oidValidate, objectClassPretty, NULL, NULL, objectSubClassMatch, objectSubClassIndexer, objectSubClassFilter, offsetof(struct slap_internal_schema, si_ad_structuralObjectClass) }, @@ -585,32 +733,32 @@ static struct slap_schema_ad_map { "EQUALITY objectIdentifierFirstComponentMatch " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.16 USAGE directoryOperation )", subentryAttribute, SLAP_AT_HIDE, - NULL, NULL, - NULL, NULL, NULL, NULL, NULL, + oidValidate, NULL, + NULL, NULL, objectClassMatch, NULL, NULL, offsetof(struct slap_internal_schema, si_ad_ditContentRules) }, { "matchingRules", "( 2.5.21.4 NAME 'matchingRules' " "DESC 'RFC2252: matching rules' " "EQUALITY objectIdentifierFirstComponentMatch " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.30 USAGE directoryOperation )", subentryAttribute, 0, - NULL, NULL, - NULL, NULL, NULL, NULL, NULL, + oidValidate, NULL, + NULL, NULL, matchingRuleMatch, NULL, NULL, offsetof(struct slap_internal_schema, si_ad_matchingRules) }, { "attributeTypes", "( 2.5.21.5 NAME 'attributeTypes' " "DESC 'RFC2252: attribute types' " "EQUALITY objectIdentifierFirstComponentMatch " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation )", subentryAttribute, 0, - NULL, NULL, - NULL, NULL, NULL, NULL, NULL, + oidValidate, NULL, + NULL, NULL, attributeTypeMatch, NULL, NULL, offsetof(struct slap_internal_schema, si_ad_attributeTypes) }, { "objectClasses", "( 2.5.21.6 NAME 'objectClasses' " "DESC 'RFC2252: object classes' " "EQUALITY objectIdentifierFirstComponentMatch " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation )", subentryAttribute, 0, - NULL, NULL, - NULL, NULL, NULL, NULL, NULL, + oidValidate, NULL, + NULL, NULL, objectClassMatch, NULL, NULL, offsetof(struct slap_internal_schema, si_ad_objectClasses) }, { "nameForms", "( 2.5.21.7 NAME 'nameForms' " "DESC 'RFC2252: name forms ' " @@ -625,8 +773,8 @@ static struct slap_schema_ad_map { "EQUALITY objectIdentifierFirstComponentMatch " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.31 USAGE directoryOperation )", subentryAttribute, 0, - NULL, NULL, - NULL, NULL, NULL, NULL, NULL, + oidValidate, NULL, + NULL, NULL, matchingRuleMatch, NULL, NULL, offsetof(struct slap_internal_schema, si_ad_matchingRuleUse) }, { "ldapSyntaxes", "( 1.3.6.1.4.1.1466.101.120.16 NAME 'ldapSyntaxes' " @@ -860,6 +1008,25 @@ static struct slap_schema_syn_map { 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) }, + + { "1.3.6.1.4.1.1466.115.121.1.3", + offsetof(struct slap_internal_schema, si_syn_attributeTypeDesc) }, + { "1.3.6.1.4.1.1466.115.121.1.16", + offsetof(struct slap_internal_schema, si_syn_ditContentRuleDesc) }, + { "1.3.6.1.4.1.1466.115.121.1.54", + offsetof(struct slap_internal_schema, si_syn_ldapSyntaxDesc) }, + { "1.3.6.1.4.1.1466.115.121.1.30", + offsetof(struct slap_internal_schema, si_syn_matchingRuleDesc) }, + { "1.3.6.1.4.1.1466.115.121.1.31", + offsetof(struct slap_internal_schema, si_syn_matchingRuleUseDesc) }, + { "1.3.6.1.4.1.1466.115.121.1.35", + offsetof(struct slap_internal_schema, si_syn_nameFormDesc) }, + { "1.3.6.1.4.1.1466.115.121.1.37", + offsetof(struct slap_internal_schema, si_syn_objectClassDesc) }, + + { "1.3.6.1.4.1.1466.115.121.1.17", + offsetof(struct slap_internal_schema, si_syn_ditStructureRuleDesc) }, + { NULL, 0 } }; @@ -979,8 +1146,7 @@ slap_schema_load( void ) } /* install custom rule routines */ - if( ( (*adp)->ad_type->sat_equality != NULL && - syntax == (*adp)->ad_type->sat_equality->smr_syntax ) || + if( syntax != NULL || ad_map[i].ssam_mr_convert || ad_map[i].ssam_mr_normalize || ad_map[i].ssam_mr_match || @@ -990,7 +1156,7 @@ slap_schema_load( void ) MatchingRule *mr = ch_malloc( sizeof( MatchingRule ) ); *mr = *(*adp)->ad_type->sat_equality; - if ( syntax == mr->smr_syntax ) { + if ( syntax != NULL ) { mr->smr_syntax = (*adp)->ad_type->sat_syntax; } if ( ad_map[i].ssam_mr_convert ) { diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 4fbff3bed5..e01c80dbec 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -789,14 +789,14 @@ struct slap_internal_schema { AttributeDescription *si_ad_subtreeSpecification; /* subschema subentry attribute descriptions */ - AttributeDescription *si_ad_ditStructureRules; - AttributeDescription *si_ad_ditContentRules; - AttributeDescription *si_ad_nameForms; - AttributeDescription *si_ad_objectClasses; AttributeDescription *si_ad_attributeTypes; + AttributeDescription *si_ad_ditContentRules; + AttributeDescription *si_ad_ditStructureRules; AttributeDescription *si_ad_ldapSyntaxes; AttributeDescription *si_ad_matchingRules; AttributeDescription *si_ad_matchingRuleUse; + AttributeDescription *si_ad_nameForms; + AttributeDescription *si_ad_objectClasses; /* Aliases & Referrals */ AttributeDescription *si_ad_aliasedObjectName; @@ -845,6 +845,16 @@ struct slap_internal_schema { Syntax *si_syn_distinguishedName; Syntax *si_syn_integer; Syntax *si_syn_octetString; + + /* Schema Syntaxes */ + Syntax *si_syn_attributeTypeDesc; + Syntax *si_syn_ditContentRuleDesc; + Syntax *si_syn_ditStructureRuleDesc; + Syntax *si_syn_ldapSyntaxDesc; + Syntax *si_syn_matchingRuleDesc; + Syntax *si_syn_matchingRuleUseDesc; + Syntax *si_syn_nameFormDesc; + Syntax *si_syn_objectClassDesc; }; typedef struct slap_attr_assertion { diff --git a/tests/scripts/test000-rootdse b/tests/scripts/test000-rootdse index 90935a3604..3e19695ccc 100755 --- a/tests/scripts/test000-rootdse +++ b/tests/scripts/test000-rootdse @@ -43,7 +43,8 @@ done if test $RC = 0 ; then echo "Using ldapsearch to retrieve the cn=Subschema..." $LDAPSEARCH -b "cn=Subschema" -s base -h $LOCALHOST -p $PORT1 \ - '(objectClasses=2.5.6.0)' cn objectClass >> $SEARCHOUT 2>&1 + '(&(objectClasses=top)(objectClasses=2.5.6.0))' cn objectClass \ + >> $SEARCHOUT 2>&1 RC=$? fi -- 2.39.5