From 87b86a52e4bc136e0c4cd279ca867de599a25b0b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Julio=20S=C3=A1nchez=20Fern=C3=A1ndez?= Date: Mon, 14 Jun 1999 19:10:07 +0000 Subject: [PATCH] Matching rules and syntaxes, initial step. schema_init, seeding of standard syntaxes and matching rules. --- servers/slapd/attr.c | 41 +++- servers/slapd/main.c | 5 + servers/slapd/proto-slap.h | 5 + servers/slapd/schema.c | 387 +++++++++++++++++++++++++++++++++++- servers/slapd/schemaparse.c | 8 +- servers/slapd/slap.h | 8 + 6 files changed, 449 insertions(+), 5 deletions(-) diff --git a/servers/slapd/attr.c b/servers/slapd/attr.c index e64b5f307f..163cac3f0d 100644 --- a/servers/slapd/attr.c +++ b/servers/slapd/attr.c @@ -476,13 +476,18 @@ at_add( { AttributeType *sat; AttributeType *sat1; + MatchingRule *mr; + Syntax *syn; int code; char *errattr; if ( at->at_names && at->at_names[0] ) { errattr = at->at_names[0]; - } else { + } else if ( at->at_oid ) { errattr = at->at_oid; + } else { + errattr = ""; + return SLAP_SCHERR_ATTR_INCOMPLETE; } sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) ); memcpy( &sat->sat_atype, at, sizeof(LDAP_ATTRIBUTE_TYPE)); @@ -500,6 +505,14 @@ at_add( } if ( at->at_syntax_oid ) { +#if 0 + if ( (syn = syn_find(sat->sat_syntax_oid)) ) { + sat->sat_syntax = syn; + } else { + *err = sat->sat_syntax_oid; + return SLAP_SCHERR_SYN_NOT_FOUND; + } +#endif if ( !strcmp(at->at_syntax_oid, "1.3.6.1.4.1.1466.115.121.1.15") ) { if ( at->at_equality_oid && @@ -524,6 +537,32 @@ at_add( sat->sat_syntax_compat = DEFAULT_SYNTAX; } +#if 0 + if ( sat->sat_equality_oid ) { + if ( (mr = mr_find(sat->sat_equality_oid)) ) { + sat->sat_equality = mr; + } else { + *err = sat->sat_equality_oid; + return SLAP_SCHERR_MR_NOT_FOUND; + } + } + if ( sat->sat_ordering_oid ) { + if ( (mr = mr_find(sat->sat_ordering_oid)) ) { + sat->sat_ordering = mr; + } else { + *err = sat->sat_ordering_oid; + return SLAP_SCHERR_MR_NOT_FOUND; + } + } + if ( sat->sat_substr_oid ) { + if ( (mr = mr_find(sat->sat_substr_oid)) ) { + sat->sat_substr = mr; + } else { + *err = sat->sat_substr_oid; + return SLAP_SCHERR_MR_NOT_FOUND; + } + } +#endif code = at_insert(sat,err); return code; } diff --git a/servers/slapd/main.c b/servers/slapd/main.c index e1e85ac113..fbc38f6ce0 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -268,6 +268,11 @@ main( int argc, char **argv ) goto destroy; } + if ( schema_init( ) != 0 ) { + rc = 1; + goto destroy; + } + if ( read_config( configfile ) != 0 ) { rc = 1; goto destroy; diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 4ae19d112e..89348359e1 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -240,7 +240,12 @@ void send_ldap_search_result LDAP_P(( Connection *conn, Operation *op, int err, int oc_schema_check LDAP_P(( Entry *e )); ObjectClass *oc_find LDAP_P((const char *ocname)); int oc_add LDAP_P((LDAP_OBJECT_CLASS *oc, const char **err)); +Syntax *syn_find LDAP_P((const char *synname)); +int syn_add LDAP_P((LDAP_SYNTAX *syn, slap_syntax_check_func *check, const char **err)); +MatchingRule *mr_find LDAP_P((const char *mrname)); +int mr_add LDAP_P((LDAP_MATCHING_RULE *mr, slap_mr_normalize_func *normalize, slap_mr_compare_func *compare, const char **err)); void schema_info LDAP_P((Connection *conn, Operation *op, char **attrs, int attrsonly)); +int schema_init LDAP_P((void)); /* diff --git a/servers/slapd/schema.c b/servers/slapd/schema.c index 9ca5fdb715..e9eee40396 100644 --- a/servers/slapd/schema.c +++ b/servers/slapd/schema.c @@ -228,11 +228,11 @@ oc_index_cmp( static int oc_index_name_cmp( - char *type, + char *name, struct oindexrec *oir ) { - return (strcasecmp( type, oir->oir_name )); + return (strcasecmp( name, oir->oir_name )); } ObjectClass * @@ -446,8 +446,379 @@ oc_add( return code; } +struct sindexrec { + char *sir_name; + Syntax *sir_syn; +}; + +static Avlnode *syn_index = NULL; +static Syntax *syn_list = NULL; + +static int +syn_index_cmp( + struct sindexrec *sir1, + struct sindexrec *sir2 +) +{ + return (strcmp( sir1->sir_name, sir2->sir_name )); +} + +static int +syn_index_name_cmp( + char *name, + struct sindexrec *sir +) +{ + return (strcmp( name, sir->sir_name )); +} + +Syntax * +syn_find( const char *synname ) +{ + struct sindexrec *sir = NULL; + + if ( (sir = (struct sindexrec *) avl_find( syn_index, synname, + (AVL_CMP) syn_index_name_cmp )) != NULL ) { + return( sir->sir_syn ); + } + return( NULL ); +} + +static int +syn_insert( + Syntax *ssyn, + const char **err +) +{ + Syntax **synp; + struct sindexrec *sir; + + synp = &syn_list; + while ( *synp != NULL ) { + synp = &(*synp)->ssyn_next; + } + *synp = ssyn; + + if ( ssyn->ssyn_oid ) { + sir = (struct sindexrec *) + ch_calloc( 1, sizeof(struct sindexrec) ); + sir->sir_name = ssyn->ssyn_oid; + sir->sir_syn = ssyn; + if ( avl_insert( &syn_index, (caddr_t) sir, + (AVL_CMP) syn_index_cmp, + (AVL_DUP) avl_dup_error ) ) { + *err = ssyn->ssyn_oid; + ldap_memfree(sir); + return SLAP_SCHERR_DUP_SYNTAX; + } + /* FIX: temporal consistency check */ + syn_find(sir->sir_name); + } + return 0; +} + +int +syn_add( + LDAP_SYNTAX *syn, + slap_syntax_check_func *check, + const char **err +) +{ + Syntax *ssyn; + int code; + + ssyn = (Syntax *) ch_calloc( 1, sizeof(Syntax) ); + memcpy( &ssyn->ssyn_syn, syn, sizeof(LDAP_SYNTAX)); + ssyn->ssyn_check = check; + code = syn_insert(ssyn,err); + return code; +} + +struct mindexrec { + char *mir_name; + MatchingRule *mir_mr; +}; + +static Avlnode *mr_index = NULL; +static MatchingRule *mr_list = NULL; + +static int +mr_index_cmp( + struct mindexrec *mir1, + struct mindexrec *mir2 +) +{ + return (strcmp( mir1->mir_name, mir2->mir_name )); +} + +static int +mr_index_name_cmp( + char *name, + struct mindexrec *mir +) +{ + return (strcmp( name, mir->mir_name )); +} + +MatchingRule * +mr_find( const char *mrname ) +{ + struct mindexrec *mir = NULL; + + if ( (mir = (struct mindexrec *) avl_find( mr_index, mrname, + (AVL_CMP) mr_index_name_cmp )) != NULL ) { + return( mir->mir_mr ); + } + return( NULL ); +} + +static int +mr_insert( + MatchingRule *smr, + const char **err +) +{ + MatchingRule **mrp; + struct mindexrec *mir; + char **names; + + mrp = &mr_list; + while ( *mrp != NULL ) { + mrp = &(*mrp)->smr_next; + } + *mrp = smr; + + if ( smr->smr_oid ) { + mir = (struct mindexrec *) + ch_calloc( 1, sizeof(struct mindexrec) ); + mir->mir_name = smr->smr_oid; + mir->mir_mr = smr; + if ( avl_insert( &mr_index, (caddr_t) mir, + (AVL_CMP) mr_index_cmp, + (AVL_DUP) avl_dup_error ) ) { + *err = smr->smr_oid; + ldap_memfree(mir); + return SLAP_SCHERR_DUP_RULE; + } + /* FIX: temporal consistency check */ + mr_find(mir->mir_name); + } + if ( (names = smr->smr_names) ) { + while ( *names ) { + mir = (struct mindexrec *) + ch_calloc( 1, sizeof(struct mindexrec) ); + mir->mir_name = ch_strdup(*names); + mir->mir_mr = smr; + if ( avl_insert( &mr_index, (caddr_t) mir, + (AVL_CMP) mr_index_cmp, + (AVL_DUP) avl_dup_error ) ) { + *err = *names; + ldap_memfree(mir); + return SLAP_SCHERR_DUP_RULE; + } + /* FIX: temporal consistency check */ + mr_find(mir->mir_name); + names++; + } + } + return 0; +} + +int +mr_add( + LDAP_MATCHING_RULE *mr, + slap_mr_normalize_func *normalize, + slap_mr_compare_func *compare, + const char **err +) +{ + MatchingRule *smr; + int code; + + smr = (MatchingRule *) ch_calloc( 1, sizeof(MatchingRule) ); + memcpy( &smr->smr_mrule, mr, sizeof(LDAP_MATCHING_RULE)); + smr->smr_normalize = normalize; + smr->smr_compare = compare; + code = mr_insert(smr,err); + return code; +} + +int +register_syntax( + char * desc, + slap_syntax_check_func *check ) +{ + LDAP_SYNTAX *syn; + int code; + const char *err; + + syn = ldap_str2syntax( desc, &code, &err); + if ( !syn ) { + Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s before %s in %s\n", + ldap_scherr2str(code), err, desc ); + return( -1 ); + } + code = syn_add( syn, check, &err ); + if ( code ) { + Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s for %s in %s\n", + scherr2str(code), err, desc ); + return( -1 ); + } + return( 0 ); +} + +int +register_matching_rule( + char * desc, + slap_mr_normalize_func *normalize, + slap_mr_compare_func *compare ) +{ + LDAP_MATCHING_RULE *mr; + int code; + const char *err; + + mr = ldap_str2matchingrule( desc, &code, &err); + if ( !mr ) { + Debug( LDAP_DEBUG_ANY, "Error in register_matching_rule: %s before %s in %s\n", + ldap_scherr2str(code), err, desc ); + return( -1 ); + } + code = mr_add( mr, normalize, compare, &err ); + if ( code ) { + Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s for %s in %s\n", + scherr2str(code), err, desc ); + return( -1 ); + } + return( 0 ); +} + +struct syntax_defs_rec { + char *sd_desc; + slap_syntax_check_func *sd_check; +}; + +struct syntax_defs_rec syntax_defs[] = { + {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'DN' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'INTEGER' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )", NULL}, + {NULL, NULL} +}; + +struct mrule_defs_rec { + char *mrd_desc; + slap_mr_normalize_func *mrd_normalize; + slap_mr_compare_func *mrd_compare; +}; + +struct mrule_defs_rec mrule_defs[] = { + {"( 2.5.13.0 NAME 'objectIdentifierMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", NULL, NULL}, + {"( 2.5.13.1 NAME 'distinguishedNameMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", NULL, NULL}, + {"( 2.5.13.2 NAME 'caseIgnoreMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", NULL, NULL}, + {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", NULL, NULL}, + {"( 2.5.13.8 NAME 'numericStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )", NULL, NULL}, + {"( 2.5.13.27 NAME 'generalizedTimeMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", NULL, NULL}, + {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", NULL, NULL}, + {"( 2.5.13.29 NAME 'integerFirstComponentMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", NULL, NULL}, + {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", NULL, NULL}, + {NULL, NULL, NULL} +}; + +int +schema_init( void ) +{ + int res; + int code; + const char *err; + int i; + + /* For now */ + return( 0 ); + for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) { + res = register_syntax( syntax_defs[i].sd_desc, + syntax_defs[i].sd_check ); + if ( res ) { + fprintf( stderr, "schema_init: Error registering syntax %s\n", + syntax_defs[i].sd_desc ); + exit( 1 ); + } + } + for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) { + res = register_matching_rule( mrule_defs[i].mrd_desc, + mrule_defs[i].mrd_normalize, + mrule_defs[i].mrd_compare ); + if ( res ) { + fprintf( stderr, "schema_init: Error registering matching rule %s\n", + mrule_defs[i].mrd_desc ); + exit( 1 ); + } + } +} + #if defined( SLAPD_SCHEMA_DN ) +static int +syn_schema_info( Entry *e ) +{ + struct berval val; + struct berval *vals[2]; + Syntax *syn; + + vals[0] = &val; + vals[1] = NULL; + + for ( syn = syn_list; syn; syn = syn->ssyn_next ) { + val.bv_val = ldap_syntax2str( &syn->ssyn_syn ); + if ( val.bv_val ) { + val.bv_len = strlen( val.bv_val ); + Debug( LDAP_DEBUG_TRACE, "Merging syn [%d] %s\n", + val.bv_len, val.bv_val, 0 ); + attr_merge( e, "ldapSyntaxes", vals ); + ldap_memfree( val.bv_val ); + } else { + return -1; + } + } + return 0; +} + +static int +mr_schema_info( Entry *e ) +{ + struct berval val; + struct berval *vals[2]; + MatchingRule *mr; + + vals[0] = &val; + vals[1] = NULL; + + for ( mr = mr_list; mr; mr = mr->smr_next ) { + val.bv_val = ldap_matchingrule2str( &mr->smr_mrule ); + if ( val.bv_val ) { + val.bv_len = strlen( val.bv_val ); + Debug( LDAP_DEBUG_TRACE, "Merging mr [%d] %s\n", + val.bv_len, val.bv_val, 0 ); + attr_merge( e, "matchingRules", vals ); + ldap_memfree( val.bv_val ); + } else { + return -1; + } + } + return 0; +} + static int oc_schema_info( Entry *e ) { @@ -464,7 +835,7 @@ oc_schema_info( Entry *e ) val.bv_len = strlen( val.bv_val ); Debug( LDAP_DEBUG_TRACE, "Merging oc [%d] %s\n", val.bv_len, val.bv_val, 0 ); - attr_merge( e, "objectclasses", vals ); + attr_merge( e, "objectClasses", vals ); ldap_memfree( val.bv_val ); } else { return -1; @@ -500,6 +871,16 @@ schema_info( Connection *conn, Operation *op, char **attrs, int attrsonly ) attr_merge( e, "objectclass", vals ); ldap_memfree( val.bv_val ); + if ( syn_schema_info( e ) ) { + /* Out of memory, do something about it */ + entry_free( e ); + return; + } + if ( mr_schema_info( e ) ) { + /* Out of memory, do something about it */ + entry_free( e ); + return; + } if ( at_schema_info( e ) ) { /* Out of memory, do something about it */ entry_free( e ); diff --git a/servers/slapd/schemaparse.c b/servers/slapd/schemaparse.c index 07de1d2997..49d95281f8 100644 --- a/servers/slapd/schemaparse.c +++ b/servers/slapd/schemaparse.c @@ -23,7 +23,13 @@ static char *err2text[] = { "Objectclass not found", "Attribute type not found", "Duplicate objectclass", - "Duplicate attributetype" + "Duplicate attributetype", + "Duplicate syntax", + "Duplicate matchingrule", + "OID or name required", + "Syntax or superior required", + "Matchingrule not found", + "Syntax not found" }; char * diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 85eac8096c..c162d76c4e 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -57,6 +57,12 @@ #define SLAP_SCHERR_ATTR_NOT_FOUND 3 #define SLAP_SCHERR_DUP_CLASS 4 #define SLAP_SCHERR_DUP_ATTR 5 +#define SLAP_SCHERR_DUP_SYNTAX 6 +#define SLAP_SCHERR_DUP_RULE 7 +#define SLAP_SCHERR_NO_NAME 8 +#define SLAP_SCHERR_ATTR_INCOMPLETE 9 +#define SLAP_SCHERR_MR_NOT_FOUND 10 +#define SLAP_SCHERR_SYN_NOT_FOUND 11 LDAP_BEGIN_DECL @@ -220,6 +226,7 @@ typedef int slap_syntax_check_func LDAP_P((struct berval * val)); typedef struct slap_syntax { LDAP_SYNTAX ssyn_syn; slap_syntax_check_func *ssyn_check; + struct slap_syntax *ssyn_next; } Syntax; #define ssyn_oid ssyn_syn.syn_oid #define ssyn_desc ssyn_syn.syn_desc @@ -232,6 +239,7 @@ typedef struct slap_matching_rule { slap_mr_normalize_func *smr_normalize; slap_mr_compare_func *smr_compare; Syntax smr_syntax; + struct slap_matching_rule *smr_next; } MatchingRule; #define smr_oid smr_mrule.mr_oid #define smr_names smr_mrule.mr_names -- 2.39.5