]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/schema.c
Add LDAPsubentry (without OID).
[openldap] / servers / slapd / schema.c
index 829e4f639674fe5e2897e8430fe90fa822fcba7c..44c86656d8bc2ddbf87eae3596e314a35f6a0590 100644 (file)
@@ -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 function should be externalized...
  */
-static int
-oc_check_operational( char *type )
+int
+oc_check_operational_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_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 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 );
        }
 
@@ -924,8 +998,6 @@ int
 schema_init( void )
 {
        int             res;
-       int             code;
-       const char      *err;
        int             i;
        static int      schema_init_done = 0;
 
@@ -938,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++ ) {
@@ -950,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;
@@ -1048,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 */
@@ -1082,8 +1159,22 @@ 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 = "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 );
 }
@@ -1118,3 +1209,35 @@ oc_print( ObjectClass *oc )
 }
 
 #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;
+}