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_entry_objectclass(
25 #ifdef SLAPD_SCHEMA_NOT_COMPAT
26 static AttributeDescription *objectClass = NULL;
28 static const char *objectClass = "objectclass";
31 if( e == NULL || oc == NULL || *oc == '\0' )
35 * find objectClass attribute
37 attr = attr_find(e->e_attrs, objectClass);
40 /* no objectClass attribute */
44 bv.bv_val = (char *) oc;
45 bv.bv_len = strlen( bv.bv_val );
47 #ifdef SLAPD_SCHEMA_NOT_COMPAT
48 /* not yet implemented */
50 if( value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
51 /* entry is not of this objectclass */
60 #ifndef SLAPD_SCHEMA_NOT_COMPAT
61 /* these shouldn't be hardcoded */
63 static char *oc_op_usermod_attrs[] = {
65 * these are operational attributes which are
66 * not defined as NO-USER_MODIFICATION and
67 * which slapd supports modification of.
70 * Likely candidate, "aci"
75 static char *oc_op_attrs[] = {
77 * these are operational attributes
78 * most could be user modifiable
91 "supportedSASLMechanisms",
92 "supportedLDAPversion",
93 "supportedACIMechanisms",
94 "subschemaSubentry", /* NO USER MOD */
99 /* this list should be extensible */
100 static char *oc_op_no_usermod_attrs[] = {
102 * Operational and 'no user modification' attributes
103 * which are STORED in the directory server.
118 * check to see if attribute is 'operational' or not.
121 oc_check_op_attr( const char *type )
123 #ifndef SLAPD_SCHEMA_NOT_COMPAT
124 return charray_inlist( oc_op_attrs, type )
125 || charray_inlist( oc_op_usermod_attrs, type )
126 || charray_inlist( oc_op_no_usermod_attrs, type );
128 AttributeType *at = at_find( type );
130 if( at == NULL ) return 0;
132 return at->sat_usage != LDAP_SCHEMA_USER_APPLICATIONS;
137 * check to see if attribute can be user modified or not.
140 oc_check_op_usermod_attr( const char *type )
142 #ifndef SLAPD_SCHEMA_NOT_COMPAT
143 return charray_inlist( oc_op_usermod_attrs, type );
145 /* not (yet) in schema */
151 * check to see if attribute is 'no user modification' or not.
154 oc_check_op_no_usermod_attr( const char *type )
156 #ifndef SLAPD_SCHEMA_NOT_COMPAT
157 return charray_inlist( oc_op_no_usermod_attrs, type );
159 AttributeType *at = at_find( type );
161 if( at == NULL ) return 0;
163 return at->sat_no_user_mod;
173 static Avlnode *oc_index = NULL;
174 static ObjectClass *oc_list = NULL;
178 struct oindexrec *oir1,
179 struct oindexrec *oir2
182 return (strcasecmp( oir1->oir_name, oir2->oir_name ));
188 struct oindexrec *oir
191 return (strcasecmp( name, oir->oir_name ));
195 oc_find( const char *ocname )
197 struct oindexrec *oir = NULL;
199 if ( (oir = (struct oindexrec *) avl_find( oc_index, ocname,
200 (AVL_CMP) oc_index_name_cmp )) != NULL ) {
201 return( oir->oir_oc );
215 AttributeType **satp;
221 sat = at_find(*attrs1);
224 return SLAP_SCHERR_ATTR_NOT_FOUND;
226 if ( at_find_in_list(sat, soc->soc_required) < 0) {
227 if ( at_append_to_list(sat, &soc->soc_required) ) {
229 return SLAP_SCHERR_OUTOFMEM;
234 /* Now delete duplicates from the allowed list */
235 for ( satp = soc->soc_required; *satp; satp++ ) {
236 i = at_find_in_list(*satp,soc->soc_allowed);
238 at_delete_from_list(i, &soc->soc_allowed);
258 sat = at_find(*attrs1);
261 return SLAP_SCHERR_ATTR_NOT_FOUND;
263 if ( at_find_in_list(sat, soc->soc_required) < 0 &&
264 at_find_in_list(sat, soc->soc_allowed) < 0 ) {
265 if ( at_append_to_list(sat, &soc->soc_allowed) ) {
267 return SLAP_SCHERR_OUTOFMEM;
290 if ( !soc->soc_sups ) {
291 /* We are at the first recursive level */
300 soc->soc_sups = (ObjectClass **)ch_calloc(nsups,
301 sizeof(ObjectClass *));
306 soc1 = oc_find(*sups1);
309 return SLAP_SCHERR_CLASS_NOT_FOUND;
313 soc->soc_sups[nsups] = soc1;
315 code = oc_add_sups(soc,soc1->soc_sup_oids, err);
319 code = oc_create_required(soc,soc1->soc_at_oids_must,err);
322 code = oc_create_allowed(soc,soc1->soc_at_oids_may,err);
340 struct oindexrec *oir;
344 while ( *ocp != NULL ) {
345 ocp = &(*ocp)->soc_next;
349 if ( soc->soc_oid ) {
350 oir = (struct oindexrec *)
351 ch_calloc( 1, sizeof(struct oindexrec) );
352 oir->oir_name = soc->soc_oid;
354 if ( avl_insert( &oc_index, (caddr_t) oir,
355 (AVL_CMP) oc_index_cmp,
356 (AVL_DUP) avl_dup_error ) ) {
359 return SLAP_SCHERR_DUP_CLASS;
361 /* FIX: temporal consistency check */
362 oc_find(oir->oir_name);
364 if ( (names = soc->soc_names) ) {
366 oir = (struct oindexrec *)
367 ch_calloc( 1, sizeof(struct oindexrec) );
368 oir->oir_name = ch_strdup(*names);
370 if ( avl_insert( &oc_index, (caddr_t) oir,
371 (AVL_CMP) oc_index_cmp,
372 (AVL_DUP) avl_dup_error ) ) {
375 return SLAP_SCHERR_DUP_CLASS;
377 /* FIX: temporal consistency check */
378 oc_find(oir->oir_name);
387 LDAP_OBJECT_CLASS *oc,
394 soc = (ObjectClass *) ch_calloc( 1, sizeof(ObjectClass) );
395 memcpy( &soc->soc_oclass, oc, sizeof(LDAP_OBJECT_CLASS));
396 if ( (code = oc_add_sups(soc,soc->soc_sup_oids,err)) != 0 )
398 if ( (code = oc_create_required(soc,soc->soc_at_oids_must,err)) != 0 )
400 if ( (code = oc_create_allowed(soc,soc->soc_at_oids_may,err)) != 0 )
402 code = oc_insert(soc,err);
409 oc_print( ObjectClass *oc )
414 printf( "objectclass %s\n", ldap_objectclass2name( &oc->soc_oclass ) );
415 if ( oc->soc_required != NULL ) {
417 for ( i = 0; oc->soc_required[i] != NULL; i++, mid = "," )
419 ldap_attributetype2name( &oc->soc_required[i]->sat_atype ) );
422 if ( oc->soc_allowed != NULL ) {
424 for ( i = 0; oc->soc_allowed[i] != NULL; i++, mid = "," )
426 ldap_attributetype2name( &oc->soc_allowed[i]->sat_atype ) );
434 #if defined( SLAPD_SCHEMA_DN )
437 oc_schema_info( Entry *e )
440 struct berval *vals[2];
446 for ( oc = oc_list; oc; oc = oc->soc_next ) {
447 val.bv_val = ldap_objectclass2str( &oc->soc_oclass );
449 val.bv_len = strlen( val.bv_val );
450 Debug( LDAP_DEBUG_TRACE, "Merging oc [%ld] %s\n",
451 (long) val.bv_len, val.bv_val, 0 );
452 attr_merge( e, "objectClasses", vals );
453 ldap_memfree( val.bv_val );