1 /* oc.c - object class routines */
4 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
13 #include <ac/string.h>
14 #include <ac/socket.h>
19 int is_object_subclass(
29 if( sup->soc_sups == NULL ) {
33 for( i=0; sup->soc_sups[i] != NULL; i++ ) {
34 if( is_object_subclass( sup->soc_sups[i], sup ) ) {
42 int is_entry_objectclass(
44 #ifdef SLAPD_SCHEMA_NOT_COMPAT
52 #ifdef SLAPD_SCHEMA_NOT_COMPAT
54 AttributeDescription *objectClass = slap_schema.si_ad_objectClass;
55 assert(!( e == NULL || oc == NULL ));
58 static const char *objectClass = "objectclass";
59 assert(!( e == NULL || oc == NULL || *oc == '\0' ));
62 if( e == NULL || oc == NULL
63 #ifndef SLAPD_SCHEMA_NOT_COMPAT
71 * find objectClass attribute
73 attr = attr_find(e->e_attrs, objectClass);
76 /* no objectClass attribute */
77 Debug( LDAP_DEBUG_ANY, "is_entry_objectclass(\"%s\", \"%s\") "
78 "no objectClass attribute\n",
79 e->e_dn == NULL ? "" : e->e_dn, oc, 0 );
84 #ifdef SLAPD_SCHEMA_NOT_COMPAT
85 for( i=0; attr->a_vals[i]; i++ ) {
86 ObjectClass *objectClass = oc_find( attr->a_vals[i]->bv_val );
88 if( objectClass == oc ) {
96 bv.bv_val = (char *) oc;
97 bv.bv_len = strlen( bv.bv_val );
99 if( value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
100 /* entry is not of this objectclass */
109 #ifndef SLAPD_SCHEMA_NOT_COMPAT
110 /* these shouldn't be hardcoded */
112 static char *oc_op_usermod_attrs[] = {
114 * these are operational attributes which are
115 * not defined as NO-USER_MODIFICATION and
116 * which slapd supports modification of.
119 * Likely candidate, "aci"
124 static char *oc_op_attrs[] = {
126 * these are operational attributes
127 * most could be user modifiable
138 "supportedExtension",
140 "supportedSASLMechanisms",
141 "supportedLDAPversion",
142 "supportedACIMechanisms",
143 "subschemaSubentry", /* NO USER MOD */
148 /* this list should be extensible */
149 static char *oc_op_no_usermod_attrs[] = {
151 * Operational and 'no user modification' attributes
152 * which are STORED in the directory server.
166 * check to see if attribute is 'operational' or not.
169 oc_check_op_attr( const char *type )
171 #ifndef SLAPD_SCHEMA_NOT_COMPAT
172 return charray_inlist( oc_op_attrs, type )
173 || charray_inlist( oc_op_usermod_attrs, type )
174 || charray_inlist( oc_op_no_usermod_attrs, type );
176 AttributeType *at = at_find( type );
178 if( at == NULL ) return 0;
180 return at->sat_usage != LDAP_SCHEMA_USER_APPLICATIONS;
185 * check to see if attribute can be user modified or not.
188 oc_check_op_usermod_attr( const char *type )
190 #ifndef SLAPD_SCHEMA_NOT_COMPAT
191 return charray_inlist( oc_op_usermod_attrs, type );
193 /* not (yet) in schema */
199 * check to see if attribute is 'no user modification' or not.
202 oc_check_op_no_usermod_attr( const char *type )
204 #ifndef SLAPD_SCHEMA_NOT_COMPAT
205 return charray_inlist( oc_op_no_usermod_attrs, type );
207 AttributeType *at = at_find( type );
209 if( at == NULL ) return 0;
211 return at->sat_no_user_mod;
222 static Avlnode *oc_index = NULL;
223 static ObjectClass *oc_list = NULL;
227 struct oindexrec *oir1,
228 struct oindexrec *oir2
231 assert( oir1->oir_name );
232 assert( oir1->oir_oc );
233 assert( oir2->oir_name );
234 assert( oir2->oir_oc );
236 return (strcasecmp( oir1->oir_name, oir2->oir_name ));
242 struct oindexrec *oir
245 assert( oir->oir_name );
246 assert( oir->oir_oc );
248 return (strcasecmp( name, oir->oir_name ));
252 oc_find( const char *ocname )
254 struct oindexrec *oir;
256 oir = (struct oindexrec *) avl_find( oc_index, ocname,
257 (AVL_CMP) oc_index_name_cmp );
260 assert( oir->oir_name );
261 assert( oir->oir_oc );
263 return( oir->oir_oc );
278 AttributeType **satp;
284 sat = at_find(*attrs1);
287 return SLAP_SCHERR_ATTR_NOT_FOUND;
289 if ( at_find_in_list(sat, soc->soc_required) < 0) {
290 if ( at_append_to_list(sat, &soc->soc_required) ) {
292 return SLAP_SCHERR_OUTOFMEM;
297 /* Now delete duplicates from the allowed list */
298 for ( satp = soc->soc_required; *satp; satp++ ) {
299 i = at_find_in_list(*satp,soc->soc_allowed);
301 at_delete_from_list(i, &soc->soc_allowed);
321 sat = at_find(*attrs1);
324 return SLAP_SCHERR_ATTR_NOT_FOUND;
326 if ( at_find_in_list(sat, soc->soc_required) < 0 &&
327 at_find_in_list(sat, soc->soc_allowed) < 0 ) {
328 if ( at_append_to_list(sat, &soc->soc_allowed) ) {
330 return SLAP_SCHERR_OUTOFMEM;
353 if ( !soc->soc_sups ) {
354 /* We are at the first recursive level */
363 soc->soc_sups = (ObjectClass **)ch_calloc(nsups,
364 sizeof(ObjectClass *));
369 soc1 = oc_find(*sups1);
372 return SLAP_SCHERR_CLASS_NOT_FOUND;
376 soc->soc_sups[nsups] = soc1;
378 code = oc_add_sups(soc,soc1->soc_sup_oids, err);
382 code = oc_create_required(soc,soc1->soc_at_oids_must,err);
385 code = oc_create_allowed(soc,soc1->soc_at_oids_may,err);
403 struct oindexrec *oir;
407 while ( *ocp != NULL ) {
408 ocp = &(*ocp)->soc_next;
412 if ( soc->soc_oid ) {
413 oir = (struct oindexrec *)
414 ch_calloc( 1, sizeof(struct oindexrec) );
415 oir->oir_name = soc->soc_oid;
418 assert( oir->oir_name );
419 assert( oir->oir_oc );
421 if ( avl_insert( &oc_index, (caddr_t) oir,
422 (AVL_CMP) oc_index_cmp,
423 (AVL_DUP) avl_dup_error ) )
426 ldap_memfree(oir->oir_name);
428 return SLAP_SCHERR_DUP_CLASS;
431 /* FIX: temporal consistency check */
432 assert( oc_find(oir->oir_name) != NULL );
435 if ( (names = soc->soc_names) ) {
437 oir = (struct oindexrec *)
438 ch_calloc( 1, sizeof(struct oindexrec) );
439 oir->oir_name = ch_strdup(*names);
442 assert( oir->oir_name );
443 assert( oir->oir_oc );
445 if ( avl_insert( &oc_index, (caddr_t) oir,
446 (AVL_CMP) oc_index_cmp,
447 (AVL_DUP) avl_dup_error ) )
450 ldap_memfree(oir->oir_name);
452 return SLAP_SCHERR_DUP_CLASS;
455 /* FIX: temporal consistency check */
456 assert( oc_find(oir->oir_name) != NULL );
467 LDAP_OBJECT_CLASS *oc,
474 soc = (ObjectClass *) ch_calloc( 1, sizeof(ObjectClass) );
475 memcpy( &soc->soc_oclass, oc, sizeof(LDAP_OBJECT_CLASS));
476 if ( (code = oc_add_sups(soc,soc->soc_sup_oids,err)) != 0 )
478 if ( (code = oc_create_required(soc,soc->soc_at_oids_must,err)) != 0 )
480 if ( (code = oc_create_allowed(soc,soc->soc_at_oids_may,err)) != 0 )
482 code = oc_insert(soc,err);
489 oc_print( ObjectClass *oc )
494 printf( "objectclass %s\n", ldap_objectclass2name( &oc->soc_oclass ) );
495 if ( oc->soc_required != NULL ) {
497 for ( i = 0; oc->soc_required[i] != NULL; i++, mid = "," )
499 ldap_attributetype2name( &oc->soc_required[i]->sat_atype ) );
502 if ( oc->soc_allowed != NULL ) {
504 for ( i = 0; oc->soc_allowed[i] != NULL; i++, mid = "," )
506 ldap_attributetype2name( &oc->soc_allowed[i]->sat_atype ) );
514 #if defined( SLAPD_SCHEMA_DN )
517 oc_schema_info( Entry *e )
520 struct berval *vals[2];
523 #ifdef SLAPD_SCHEMA_NOT_COMPAT
524 AttributeDescription *ad_objectClasses = slap_schema.si_ad_objectClasses;
526 char *ad_objectClasses = "objectClasses";
532 for ( oc = oc_list; oc; oc = oc->soc_next ) {
533 val.bv_val = ldap_objectclass2str( &oc->soc_oclass );
534 if ( val.bv_val == NULL ) {
537 val.bv_len = strlen( val.bv_val );
539 Debug( LDAP_DEBUG_TRACE, "Merging oc [%ld] %s\n",
540 (long) val.bv_len, val.bv_val, 0 );
542 attr_merge( e, ad_objectClasses, vals );
543 ldap_memfree( val.bv_val );