]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/schema.c
Per ITS#419, don't require SLAPD_RLOOKUPS when HAVE_TCPD
[openldap] / servers / slapd / schema.c
index 4c6fe9307e8899f74aa01e8267a3c49464cceb0b..f5e32c07b48657ec8855f0f748b9a45f5b2edffb 100644 (file)
@@ -1,4 +1,9 @@
 /* schema.c - routines to enforce schema definitions */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 
 #include "portable.h"
 
@@ -8,7 +13,6 @@
 #include <ac/string.h>
 #include <ac/socket.h>
 
-#include "ldap_defaults.h"
 #include "slap.h"
 
 static char *  oc_check_required(Entry *e, char *ocname);
@@ -24,9 +28,11 @@ int
 oc_schema_check( Entry *e )
 {
        Attribute       *a, *aoc;
+       ObjectClass *oc;
        int             i;
        int             ret = 0;
 
+
        /* find the object class attribute - could error out here */
        if ( (aoc = attr_find( e->e_attrs, "objectclass" )) == NULL ) {
                Debug( LDAP_DEBUG_ANY, "No object class for entry (%s)\n",
@@ -36,13 +42,21 @@ oc_schema_check( Entry *e )
 
        /* check that the entry has required attrs for each oc */
        for ( i = 0; aoc->a_vals[i] != NULL; i++ ) {
-               char *s = oc_check_required( e, aoc->a_vals[i]->bv_val );
-
-               if (s != NULL) {
+               if ( (oc = oc_find( aoc->a_vals[i]->bv_val )) == NULL ) {
                        Debug( LDAP_DEBUG_ANY,
-                           "Entry (%s), oc \"%s\" requires attr \"%s\"\n",
-                           e->e_dn, aoc->a_vals[i]->bv_val, s );
-                       ret = 1;
+                               "Objectclass \"%s\" not defined\n",
+                               aoc->a_vals[i]->bv_val, 0, 0 );
+               }
+               else
+               {
+                       char *s = oc_check_required( e, aoc->a_vals[i]->bv_val );
+
+                       if (s != NULL) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "Entry (%s), oc \"%s\" requires attr \"%s\"\n",
+                                       e->e_dn, aoc->a_vals[i]->bv_val, s );
+                               ret = 1;
+                       }
                }
        }
 
@@ -134,8 +148,8 @@ static char *oc_usermod_attrs[] = {
 
 static char *oc_operational_attrs[] = {
        /*
-        * these are operational attributes that *could* be
-        * modified by users if we supported such.
+        * these are operational attributes 
+        * most could be user modifiable
         */
        "objectClasses",
        "attributeTypes",
@@ -150,6 +164,8 @@ static char *oc_operational_attrs[] = {
        "supportedControl",
        "supportedSASLMechanisms",
        "supportedLDAPversion",
+       "supportedACIMechanisms",
+       "subschemaSubentry",            /* NO USER MOD */
        NULL
 
 };
@@ -158,6 +174,7 @@ static char *oc_operational_attrs[] = {
 static char *oc_no_usermod_attrs[] = {
        /*
         * Operational and 'no user modification' attributes
+        * which are STORED in the directory server.
         */
 
        /* RFC2252, 3.2.1 */
@@ -165,7 +182,6 @@ static char *oc_no_usermod_attrs[] = {
        "createTimestamp",
        "modifiersName",
        "modifyTimestamp",
-       "subschemaSubentry",
 
        NULL
 };
@@ -175,7 +191,7 @@ static char *oc_no_usermod_attrs[] = {
  * check to see if attribute is 'operational' or not.
  */
 int
-oc_check_operational_attr( char *type )
+oc_check_operational_attr( const char *type )
 {
        return charray_inlist( oc_operational_attrs, type )
                || charray_inlist( oc_usermod_attrs, type )
@@ -186,7 +202,7 @@ oc_check_operational_attr( char *type )
  * check to see if attribute can be user modified or not.
  */
 int
-oc_check_usermod_attr( char *type )
+oc_check_usermod_attr( const char *type )
 {
        return charray_inlist( oc_usermod_attrs, type );
 }
@@ -195,7 +211,7 @@ oc_check_usermod_attr( char *type )
  * check to see if attribute is 'no user modification' or not.
  */
 int
-oc_check_no_usermod_attr( char *type )
+oc_check_no_usermod_attr( const char *type )
 {
        return charray_inlist( oc_no_usermod_attrs, type );
 }
@@ -208,6 +224,7 @@ oc_check_allowed( char *type, struct berval **ocl )
        AttributeType   *at;
        int             i, j;
        char            **pp;
+       char            *p, *t;
 
        Debug( LDAP_DEBUG_TRACE,
               "oc_check_allowed type \"%s\"\n", type, 0, 0 );
@@ -226,6 +243,23 @@ oc_check_allowed( char *type, struct berval **ocl )
                return( 0 );
        }
 
+       /*
+        * The "type" we have received is actually an AttributeDescription.
+        * Let's find out the corresponding type.
+        */
+       p = strchr( type, ';' );
+       if ( p ) {
+               t = ch_malloc( p-type+1 );
+               strncpy( t, type, p-type );
+               t[p-type] = '\0';
+               Debug( LDAP_DEBUG_TRACE,
+                      "oc_check_allowed type \"%s\" from \"%s\"\n",
+                      t, type, 0 );
+
+       } else {
+               t = type;
+       }
+
        /* check that the type appears as req or opt in at least one oc */
        for ( i = 0; ocl[i] != NULL; i++ ) {
                /* if we know about the oc */
@@ -235,14 +269,18 @@ oc_check_allowed( char *type, struct berval **ocl )
                                oc->soc_required[j] != NULL; j++ ) {
                                at = oc->soc_required[j];
                                if ( at->sat_oid &&
-                                    strcmp(at->sat_oid, type ) == 0 ) {
+                                    strcmp(at->sat_oid, t ) == 0 ) {
+                                       if ( t != type )
+                                               ldap_memfree( t );
                                        return( 0 );
                                }
                                pp = at->sat_names;
                                if ( pp == NULL )
                                        continue;
                                while ( *pp ) {
-                                       if ( strcasecmp( *pp, type ) == 0 ) {
+                                       if ( strcasecmp( *pp, t ) == 0 ) {
+                                               if ( t != type )
+                                                       ldap_memfree( t );
                                                return( 0 );
                                        }
                                        pp++;
@@ -253,15 +291,19 @@ oc_check_allowed( char *type, struct berval **ocl )
                                oc->soc_allowed[j] != NULL; j++ ) {
                                at = oc->soc_allowed[j];
                                if ( at->sat_oid &&
-                                    strcmp(at->sat_oid, type ) == 0 ) {
+                                    strcmp( at->sat_oid, t ) == 0 ) {
+                                       if ( t != type )
+                                               ldap_memfree( t );
                                        return( 0 );
                                }
                                pp = at->sat_names;
                                if ( pp == NULL )
                                        continue;
                                while ( *pp ) {
-                                       if ( strcasecmp( *pp, type ) == 0 ||
+                                       if ( strcasecmp( *pp, t ) == 0 ||
                                             strcmp( *pp, "*" ) == 0 ) {
+                                               if ( t != type )
+                                                       ldap_memfree( t );
                                                return( 0 );
                                        }
                                        pp++;
@@ -269,12 +311,18 @@ oc_check_allowed( char *type, struct berval **ocl )
                        }
                        /* maybe the next oc allows it */
 
+#ifdef OC_UNDEFINED_IMPLES_EXTENSIBLE
                /* we don't know about the oc. assume it allows it */
                } else {
+                       if ( t != type )
+                               ldap_memfree( t );
                        return( 0 );
+#endif
                }
        }
 
+       if ( t != type )
+               ldap_memfree( t );
        /* not allowed by any oc */
        return( 1 );
 }
@@ -429,13 +477,14 @@ oc_add_sups(
                        code = oc_add_sups(soc,soc1->soc_sup_oids, err);
                        if ( code )
                                return code;
-                       
-                       if ( code = oc_create_required(soc,
-                               soc1->soc_at_oids_must,err) )
+
+                       code = oc_create_required(soc,soc1->soc_at_oids_must,err);
+                       if ( code )
                                return code;
-                       if ( code = oc_create_allowed(soc,
-                               soc1->soc_at_oids_may,err) )
+                       code = oc_create_allowed(soc,soc1->soc_at_oids_may,err);
+                       if ( code )
                                return code;
+
                        nsups++;
                        sups1++;
                }
@@ -506,11 +555,11 @@ oc_add(
 
        soc = (ObjectClass *) ch_calloc( 1, sizeof(ObjectClass) );
        memcpy( &soc->soc_oclass, oc, sizeof(LDAP_OBJECT_CLASS));
-       if ( code = oc_add_sups(soc,soc->soc_sup_oids,err) )
+       if ( (code = oc_add_sups(soc,soc->soc_sup_oids,err)) != 0 )
                return code;
-       if ( code = oc_create_required(soc,soc->soc_at_oids_must,err) )
+       if ( (code = oc_create_required(soc,soc->soc_at_oids_must,err)) != 0 )
                return code;
-       if ( code = oc_create_allowed(soc,soc->soc_at_oids_may,err) )
+       if ( (code = oc_create_allowed(soc,soc->soc_at_oids_may,err)) != 0 )
                return code;
        code = oc_insert(soc,err);
        return code;
@@ -554,6 +603,17 @@ syn_find( const char *synname )
        return( NULL );
 }
 
+Syntax *
+syn_find_desc( const char *syndesc, int *len )
+{
+       Syntax          *synp;
+
+       for (synp = syn_list; synp; synp = synp->ssyn_next)
+               if ((*len = dscompare( synp->ssyn_syn.syn_desc, syndesc, '{')))
+                       return synp;
+       return( NULL );
+}
+
 static int
 syn_insert(
     Syntax             *ssyn,
@@ -874,47 +934,48 @@ struct syntax_defs_rec {
 };
 
 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.3 DESC 'AttributeTypeDescription' )", NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' )", NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'BitString' )", NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'CertificateList' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'CertificatePair' )", 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.14 DESC 'Delivery Method' )", 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.21 DESC 'Enhanced Guide' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )", 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.14 DESC 'DeliveryMethod' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'DirectoryString' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DITContentRuleDescription' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DITStructureRuleDescription' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'EnhancedGuide' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'FacsimileTelephoneNumber' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'GeneralizedTime' )", 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.32 DESC 'Mail Preference' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )", 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.36 DESC 'Numeric String' )", 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.26 DESC 'IA5String' )", 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.28 DESC 'JPEG' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'MatchingRuleDescription' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'MatchingRuleUseDescription' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'MailPreference' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'NameAndOptionalUID' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'NameFormDescription' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'NumericString' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'ObjectClassDescription' )", 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.39 DESC 'Other Mailbox' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )", 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.49 DESC 'Supported Algorithm' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )", NULL},
-       {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )", NULL},
-       {"( 1.3.6.1.1.1.0.0 DESC 'NIS netgroup triple' )", NULL},
-       {"( 1.3.6.1.1.1.0.1 DESC 'Boot parameter' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'OtherMailbox' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'OctetString' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'PostalAddress' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'ProtocolInformation' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'PresentationAddress' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'PrintableString' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'SupportedAlgorithm' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'TelephoneNumber' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'TeletexTerminalIdentifier' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'TelexNumber' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTCTime' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAPSyntaxDescription' )", NULL},
+       {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'SubstringAssertion' )", NULL},
+       {"( 1.3.6.1.1.1.0.0 DESC 'NISnetgrouptriple' )", NULL},
+       {"( 1.3.6.1.1.1.0.1 DESC 'Bootparameter' )", NULL},
        {NULL, NULL}
 };
 
@@ -1005,7 +1066,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++ ) {
@@ -1017,7 +1078,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;
@@ -1040,8 +1101,8 @@ syn_schema_info( Entry *e )
                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 );
+                       Debug( LDAP_DEBUG_TRACE, "Merging syn [%ld] %s\n",
+                              (long) val.bv_len, val.bv_val, 0 );
                        attr_merge( e, "ldapSyntaxes", vals );
                        ldap_memfree( val.bv_val );
                } else {
@@ -1065,8 +1126,8 @@ mr_schema_info( Entry *e )
                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 );
+                       Debug( LDAP_DEBUG_TRACE, "Merging mr [%ld] %s\n",
+                              (long) val.bv_len, val.bv_val, 0 );
                        attr_merge( e, "matchingRules", vals );
                        ldap_memfree( val.bv_val );
                } else {
@@ -1090,8 +1151,8 @@ oc_schema_info( Entry *e )
                val.bv_val = ldap_objectclass2str( &oc->soc_oclass );
                if ( val.bv_val ) {
                        val.bv_len = strlen( val.bv_val );
-                       Debug( LDAP_DEBUG_TRACE, "Merging oc [%d] %s\n",
-                              val.bv_len, val.bv_val, 0 );
+                       Debug( LDAP_DEBUG_TRACE, "Merging oc [%ld] %s\n",
+                              (long) val.bv_len, val.bv_val, 0 );
                        attr_merge( e, "objectClasses", vals );
                        ldap_memfree( val.bv_val );
                } else {
@@ -1116,18 +1177,22 @@ 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 = ch_strdup( SLAPD_SCHEMA_DN );
-       (void) dn_normalize_case( e->e_ndn );
+       (void) dn_normalize( 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 */
@@ -1150,8 +1215,24 @@ schema_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
                return;
        }
        
+       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, 0, NULL );
+               e, attrs, attrsonly, NULL );
        send_search_result( conn, op, LDAP_SUCCESS,
                NULL, NULL, NULL, NULL, 1 );
 
@@ -1165,24 +1246,21 @@ 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" );
        }
 }
@@ -1192,7 +1270,7 @@ oc_print( ObjectClass *oc )
 
 int is_entry_objectclass(
        Entry*  e,
-       char*   oc)
+       const char*     oc)
 {
        Attribute *attr;
        struct berval bv;
@@ -1210,7 +1288,7 @@ int is_entry_objectclass(
                return 0;
        }
 
-       bv.bv_val = oc;
+       bv.bv_val = (char *) oc;
        bv.bv_len = strlen( bv.bv_val );
 
        if( value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {