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, "OpenLDAPaci"
124 static char *oc_op_attrs[] = {
126 * these are operational attributes
127 * most could be user modifiable
138 "supportedExtension",
140 "supportedSASLMechanisms",
141 "supportedLDAPversion",
142 "subschemaSubentry", /* NO USER MOD */
147 /* this list should be extensible */
148 static char *oc_op_no_usermod_attrs[] = {
150 * Operational and 'no user modification' attributes
151 * which are STORED in the directory server.
165 * check to see if attribute is 'operational' or not.
168 oc_check_op_attr( const char *type )
170 #ifndef SLAPD_SCHEMA_NOT_COMPAT
171 return charray_inlist( oc_op_attrs, type )
172 || charray_inlist( oc_op_usermod_attrs, type )
173 || charray_inlist( oc_op_no_usermod_attrs, type );
175 AttributeType *at = at_find( type );
177 if( at == NULL ) return 0;
179 return at->sat_usage != LDAP_SCHEMA_USER_APPLICATIONS;
184 * check to see if attribute can be user modified or not.
187 oc_check_op_usermod_attr( const char *type )
189 #ifndef SLAPD_SCHEMA_NOT_COMPAT
190 return charray_inlist( oc_op_usermod_attrs, type );
192 /* not (yet) in schema */
198 * check to see if attribute is 'no user modification' or not.
201 oc_check_op_no_usermod_attr( const char *type )
203 #ifndef SLAPD_SCHEMA_NOT_COMPAT
204 return charray_inlist( oc_op_no_usermod_attrs, type );
206 AttributeType *at = at_find( type );
208 if( at == NULL ) return 0;
210 return at->sat_no_user_mod;
221 static Avlnode *oc_index = NULL;
222 static ObjectClass *oc_list = NULL;
226 struct oindexrec *oir1,
227 struct oindexrec *oir2
230 assert( oir1->oir_name );
231 assert( oir1->oir_oc );
232 assert( oir2->oir_name );
233 assert( oir2->oir_oc );
235 return (strcasecmp( oir1->oir_name, oir2->oir_name ));
241 struct oindexrec *oir
244 assert( oir->oir_name );
245 assert( oir->oir_oc );
247 return (strcasecmp( name, oir->oir_name ));
251 oc_find( const char *ocname )
253 struct oindexrec *oir;
255 oir = (struct oindexrec *) avl_find( oc_index, ocname,
256 (AVL_CMP) oc_index_name_cmp );
259 assert( oir->oir_name );
260 assert( oir->oir_oc );
262 return( oir->oir_oc );
277 AttributeType **satp;
283 sat = at_find(*attrs1);
286 return SLAP_SCHERR_ATTR_NOT_FOUND;
288 if ( at_find_in_list(sat, soc->soc_required) < 0) {
289 if ( at_append_to_list(sat, &soc->soc_required) ) {
291 return SLAP_SCHERR_OUTOFMEM;
296 /* Now delete duplicates from the allowed list */
297 for ( satp = soc->soc_required; *satp; satp++ ) {
298 i = at_find_in_list(*satp,soc->soc_allowed);
300 at_delete_from_list(i, &soc->soc_allowed);
320 sat = at_find(*attrs1);
323 return SLAP_SCHERR_ATTR_NOT_FOUND;
325 if ( at_find_in_list(sat, soc->soc_required) < 0 &&
326 at_find_in_list(sat, soc->soc_allowed) < 0 ) {
327 if ( at_append_to_list(sat, &soc->soc_allowed) ) {
329 return SLAP_SCHERR_OUTOFMEM;
352 if ( !soc->soc_sups ) {
353 /* We are at the first recursive level */
362 soc->soc_sups = (ObjectClass **)ch_calloc(nsups,
363 sizeof(ObjectClass *));
368 soc1 = oc_find(*sups1);
371 return SLAP_SCHERR_CLASS_NOT_FOUND;
375 soc->soc_sups[nsups] = soc1;
377 code = oc_add_sups(soc,soc1->soc_sup_oids, err);
381 code = oc_create_required(soc,soc1->soc_at_oids_must,err);
384 code = oc_create_allowed(soc,soc1->soc_at_oids_may,err);
402 struct oindexrec *oir;
406 while ( *ocp != NULL ) {
407 ocp = &(*ocp)->soc_next;
411 if ( soc->soc_oid ) {
412 oir = (struct oindexrec *)
413 ch_calloc( 1, sizeof(struct oindexrec) );
414 oir->oir_name = soc->soc_oid;
417 assert( oir->oir_name );
418 assert( oir->oir_oc );
420 if ( avl_insert( &oc_index, (caddr_t) oir,
421 (AVL_CMP) oc_index_cmp,
422 (AVL_DUP) avl_dup_error ) )
425 ldap_memfree(oir->oir_name);
427 return SLAP_SCHERR_DUP_CLASS;
430 /* FIX: temporal consistency check */
431 assert( oc_find(oir->oir_name) != NULL );
434 if ( (names = soc->soc_names) ) {
436 oir = (struct oindexrec *)
437 ch_calloc( 1, sizeof(struct oindexrec) );
438 oir->oir_name = ch_strdup(*names);
441 assert( oir->oir_name );
442 assert( oir->oir_oc );
444 if ( avl_insert( &oc_index, (caddr_t) oir,
445 (AVL_CMP) oc_index_cmp,
446 (AVL_DUP) avl_dup_error ) )
449 ldap_memfree(oir->oir_name);
451 return SLAP_SCHERR_DUP_CLASS;
454 /* FIX: temporal consistency check */
455 assert( oc_find(oir->oir_name) != NULL );
466 LDAP_OBJECT_CLASS *oc,
473 soc = (ObjectClass *) ch_calloc( 1, sizeof(ObjectClass) );
474 memcpy( &soc->soc_oclass, oc, sizeof(LDAP_OBJECT_CLASS));
475 if ( (code = oc_add_sups(soc,soc->soc_sup_oids,err)) != 0 )
477 if ( (code = oc_create_required(soc,soc->soc_at_oids_must,err)) != 0 )
479 if ( (code = oc_create_allowed(soc,soc->soc_at_oids_may,err)) != 0 )
481 code = oc_insert(soc,err);
488 oc_print( ObjectClass *oc )
493 printf( "objectclass %s\n", ldap_objectclass2name( &oc->soc_oclass ) );
494 if ( oc->soc_required != NULL ) {
496 for ( i = 0; oc->soc_required[i] != NULL; i++, mid = "," )
498 ldap_attributetype2name( &oc->soc_required[i]->sat_atype ) );
501 if ( oc->soc_allowed != NULL ) {
503 for ( i = 0; oc->soc_allowed[i] != NULL; i++, mid = "," )
505 ldap_attributetype2name( &oc->soc_allowed[i]->sat_atype ) );
513 #if defined( SLAPD_SCHEMA_DN )
516 oc_schema_info( Entry *e )
519 struct berval *vals[2];
522 #ifdef SLAPD_SCHEMA_NOT_COMPAT
523 AttributeDescription *ad_objectClasses = slap_schema.si_ad_objectClasses;
525 char *ad_objectClasses = "objectClasses";
531 for ( oc = oc_list; oc; oc = oc->soc_next ) {
532 val.bv_val = ldap_objectclass2str( &oc->soc_oclass );
533 if ( val.bv_val == NULL ) {
536 val.bv_len = strlen( val.bv_val );
538 Debug( LDAP_DEBUG_TRACE, "Merging oc [%ld] %s\n",
539 (long) val.bv_len, val.bv_val, 0 );
541 attr_merge( e, ad_objectClasses, vals );
542 ldap_memfree( val.bv_val );