X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fschema.c;h=ad022a60bbfa062a185d49523edc49e0a59850a2;hb=6147119dc8526a758a7c576940fe8483e2b93915;hp=746833f796a67027edf244676b1127128244c636;hpb=fe002638757f5b6b2e5af81f9e79ce78aa061ff1;p=openldap diff --git a/servers/slapd/schema.c b/servers/slapd/schema.c index 746833f796..ad022a60bb 100644 --- a/servers/slapd/schema.c +++ b/servers/slapd/schema.c @@ -1,4 +1,8 @@ /* schema.c - routines to enforce schema definitions */ +/* + * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ #include "portable.h" @@ -14,6 +18,7 @@ static char * oc_check_required(Entry *e, char *ocname); static int oc_check_allowed(char *type, struct berval **ocl); + /* * oc_check - check that entry e conforms to the schema required by * its object class(es). returns 0 if so, non-zero otherwise. @@ -123,20 +128,84 @@ oc_check_required( Entry *e, char *ocname ) return( NULL ); } +static char *oc_usermod_attrs[] = { + /* + * OpenLDAP doesn't support any user modification of + * operational attributes. + */ + NULL +}; + +static char *oc_operational_attrs[] = { + /* + * these are operational attributes + * most could be user modifiable + */ + "objectClasses", + "attributeTypes", + "matchingRules", + "matchingRuleUse", + "dITStructureRules", + "dITContentRules", + "nameForms", + "ldapSyntaxes", + "namingContexts", + "supportedExtension", + "supportedControl", + "supportedSASLMechanisms", + "supportedLDAPversion", + "subschemaSubentry", /* NO USER MOD */ + NULL + +}; + +/* this list should be extensible */ +static char *oc_no_usermod_attrs[] = { + /* + * Operational and 'no user modification' attributes + * which are STORED in the directory server. + */ + + /* RFC2252, 3.2.1 */ + "creatorsName", + "createTimestamp", + "modifiersName", + "modifyTimestamp", + + NULL +}; + + /* * check to see if attribute is 'operational' or not. - * this list should be extensible... */ int -oc_check_operational( char *type ) +oc_check_operational_attr( char *type ) +{ + return charray_inlist( oc_operational_attrs, type ) + || charray_inlist( oc_usermod_attrs, type ) + || charray_inlist( oc_no_usermod_attrs, type ); +} + +/* + * check to see if attribute can be user modified or not. + */ +int +oc_check_usermod_attr( char *type ) { - return ( strcasecmp( type, "modifiersname" ) == 0 || - strcasecmp( type, "modifytimestamp" ) == 0 || - strcasecmp( type, "creatorsname" ) == 0 || - strcasecmp( type, "createtimestamp" ) == 0 ) - ? 1 : 0; + return charray_inlist( oc_usermod_attrs, type ); } +/* + * check to see if attribute is 'no user modification' or not. + */ +int +oc_check_no_usermod_attr( char *type ) +{ + return charray_inlist( oc_no_usermod_attrs, type ); +} + + static int oc_check_allowed( char *type, struct berval **ocl ) { @@ -153,7 +222,12 @@ oc_check_allowed( char *type, struct berval **ocl ) return( 0 ); } - if ( oc_check_operational( type ) ) { + /* + * All operational attributions are allowed by schema rules. + * However, we only check attributions which are stored in the + * the directory regardless if they are user or non-user modified. + */ + if ( oc_check_usermod_attr( type ) || oc_check_no_usermod_attr( type ) ) { return( 0 ); } @@ -936,7 +1010,7 @@ schema_init( void ) if ( res ) { fprintf( stderr, "schema_init: Error registering syntax %s\n", syntax_defs[i].sd_desc ); - exit( 1 ); + exit( EXIT_FAILURE ); } } for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) { @@ -948,7 +1022,7 @@ schema_init( void ) if ( res ) { fprintf( stderr, "schema_init: Error registering matching rule %s\n", mrule_defs[i].mrd_desc ); - exit( 1 ); + exit( EXIT_FAILURE ); } } schema_init_done = 1; @@ -1046,18 +1120,23 @@ schema_info( Connection *conn, Operation *op, char **attrs, int attrsonly ) e->e_attrs = NULL; e->e_dn = ch_strdup( SLAPD_SCHEMA_DN ); - e->e_ndn = dn_normalize_case( ch_strdup( SLAPD_SCHEMA_DN )); + e->e_ndn = ch_strdup( SLAPD_SCHEMA_DN ); + (void) dn_normalize_case( e->e_ndn ); e->e_private = NULL; - val.bv_val = ch_strdup( "top" ); - val.bv_len = strlen( val.bv_val ); - attr_merge( e, "objectClass", vals ); - ldap_memfree( val.bv_val ); + { + char *rdn = ch_strdup( SLAPD_SCHEMA_DN ); + val.bv_val = strchr( rdn, '=' ); - val.bv_val = ch_strdup( "subschema" ); - val.bv_len = strlen( val.bv_val ); - attr_merge( e, "objectClass", vals ); - ldap_memfree( val.bv_val ); + if( val.bv_val != NULL ) { + *val.bv_val = '\0'; + val.bv_len = strlen( ++val.bv_val ); + + attr_merge( e, rdn, vals ); + } + + free( rdn ); + } if ( syn_schema_info( e ) ) { /* Out of memory, do something about it */ @@ -1080,8 +1159,26 @@ schema_info( Connection *conn, Operation *op, char **attrs, int attrsonly ) return; } - send_search_entry( &backends[0], conn, op, e, attrs, attrsonly ); - send_ldap_search_result( conn, op, LDAP_SUCCESS, NULL, NULL, 1 ); + val.bv_val = "top"; + val.bv_len = sizeof("top")-1; + attr_merge( e, "objectClass", vals ); + + val.bv_val = "LDAPsubentry"; + val.bv_len = sizeof("LDAPsubentry")-1; + attr_merge( e, "objectClass", vals ); + + val.bv_val = "subschema"; + val.bv_len = sizeof("subschema")-1; + attr_merge( e, "objectClass", vals ); + + val.bv_val = "extensibleObject"; + val.bv_len = sizeof("extensibleObject")-1; + attr_merge( e, "objectClass", vals ); + + send_search_entry( &backends[0], conn, op, + e, attrs, attrsonly, NULL ); + send_search_result( conn, op, LDAP_SUCCESS, + NULL, NULL, NULL, NULL, 1 ); entry_free( e ); } @@ -1093,26 +1190,55 @@ static void oc_print( ObjectClass *oc ) { int i; + const char *mid; - if ( oc->soc_names && oc->soc_names[0] ) { - printf( "objectclass %s\n", oc->soc_names[0] ); - } else { - printf( "objectclass %s\n", oc->soc_oid ); - } + printf( "objectclass %s\n", ldap_objectclass2name( &oc->soc_oclass ) ); if ( oc->soc_required != NULL ) { - printf( "\trequires %s", oc->soc_required[0] ); - for ( i = 1; oc->soc_required[i] != NULL; i++ ) { - printf( ",%s", oc->soc_required[i] ); - } + mid = "\trequires "; + for ( i = 0; oc->soc_required[i] != NULL; i++, mid = "," ) + printf( "%s%s", mid, + ldap_attributetype2name( &oc->soc_required[i]->sat_atype ) ); printf( "\n" ); } if ( oc->soc_allowed != NULL ) { - printf( "\tallows %s", oc->soc_allowed[0] ); - for ( i = 1; oc->soc_allowed[i] != NULL; i++ ) { - printf( ",%s", oc->soc_allowed[i] ); - } + mid = "\tallows "; + for ( i = 0; oc->soc_allowed[i] != NULL; i++, mid = "," ) + printf( "%s%s", mid, + ldap_attributetype2name( &oc->soc_allowed[i]->sat_atype ) ); printf( "\n" ); } } #endif + + +int is_entry_objectclass( + Entry* e, + char* oc) +{ + Attribute *attr; + struct berval bv; + + if( e == NULL || oc == NULL || *oc == '\0' ) + return 0; + + /* + * find objectClass attribute + */ + attr = attr_find(e->e_attrs, "objectclass"); + + if( attr == NULL ) { + /* no objectClass attribute */ + return 0; + } + + bv.bv_val = oc; + bv.bv_len = strlen( bv.bv_val ); + + if( value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) { + /* entry is not of this objectclass */ + return 0; + } + + return 1; +}