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(
21 #ifdef SLAPD_SCHEMA_NOT_COMPAT
29 #ifdef SLAPD_SCHEMA_NOT_COMPAT
31 AttributeDescription *objectClass = slap_schema.si_ad_objectClass;
32 assert(!( e == NULL || oc == NULL ));
35 static const char *objectClass = "objectclass";
36 assert(!( e == NULL || oc == NULL || *oc == '\0' ));
39 if( e == NULL || oc == NULL
40 #ifndef SLAPD_SCHEMA_NOT_COMPAT
48 * find objectClass attribute
50 attr = attr_find(e->e_attrs, objectClass);
53 /* no objectClass attribute */
54 Debug( LDAP_DEBUG_ANY, "is_entry_objectclass(\"%s\", \"%s\") "
55 "no objectClass attribute\n",
56 e->e_dn == NULL ? "" : e->e_dn, oc, 0 );
61 #ifdef SLAPD_SCHEMA_NOT_COMPAT
62 for( i=0; attr->a_vals[i]; i++ ) {
63 ObjectClass *objectClass = oc_find( attr->a_vals[i]->bv_val );
65 if( objectClass == oc ) {
73 bv.bv_val = (char *) oc;
74 bv.bv_len = strlen( bv.bv_val );
76 if( value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
77 /* entry is not of this objectclass */
86 #ifndef SLAPD_SCHEMA_NOT_COMPAT
87 /* these shouldn't be hardcoded */
89 static char *oc_op_usermod_attrs[] = {
91 * these are operational attributes which are
92 * not defined as NO-USER_MODIFICATION and
93 * which slapd supports modification of.
96 * Likely candidate, "aci"
101 static char *oc_op_attrs[] = {
103 * these are operational attributes
104 * most could be user modifiable
115 "supportedExtension",
117 "supportedSASLMechanisms",
118 "supportedLDAPversion",
119 "supportedACIMechanisms",
120 "subschemaSubentry", /* NO USER MOD */
125 /* this list should be extensible */
126 static char *oc_op_no_usermod_attrs[] = {
128 * Operational and 'no user modification' attributes
129 * which are STORED in the directory server.
143 * check to see if attribute is 'operational' or not.
146 oc_check_op_attr( const char *type )
148 #ifndef SLAPD_SCHEMA_NOT_COMPAT
149 return charray_inlist( oc_op_attrs, type )
150 || charray_inlist( oc_op_usermod_attrs, type )
151 || charray_inlist( oc_op_no_usermod_attrs, type );
153 AttributeType *at = at_find( type );
155 if( at == NULL ) return 0;
157 return at->sat_usage != LDAP_SCHEMA_USER_APPLICATIONS;
162 * check to see if attribute can be user modified or not.
165 oc_check_op_usermod_attr( const char *type )
167 #ifndef SLAPD_SCHEMA_NOT_COMPAT
168 return charray_inlist( oc_op_usermod_attrs, type );
170 /* not (yet) in schema */
176 * check to see if attribute is 'no user modification' or not.
179 oc_check_op_no_usermod_attr( const char *type )
181 #ifndef SLAPD_SCHEMA_NOT_COMPAT
182 return charray_inlist( oc_op_no_usermod_attrs, type );
184 AttributeType *at = at_find( type );
186 if( at == NULL ) return 0;
188 return at->sat_no_user_mod;
199 static Avlnode *oc_index = NULL;
200 static ObjectClass *oc_list = NULL;
204 struct oindexrec *oir1,
205 struct oindexrec *oir2
208 assert( oir1->oir_name );
209 assert( oir1->oir_oc );
210 assert( oir2->oir_name );
211 assert( oir2->oir_oc );
213 return (strcasecmp( oir1->oir_name, oir2->oir_name ));
219 struct oindexrec *oir
222 assert( oir->oir_name );
223 assert( oir->oir_oc );
225 return (strcasecmp( name, oir->oir_name ));
229 oc_find( const char *ocname )
231 struct oindexrec *oir;
233 oir = (struct oindexrec *) avl_find( oc_index, ocname,
234 (AVL_CMP) oc_index_name_cmp );
237 assert( oir->oir_name );
238 assert( oir->oir_oc );
240 return( oir->oir_oc );
255 AttributeType **satp;
261 sat = at_find(*attrs1);
264 return SLAP_SCHERR_ATTR_NOT_FOUND;
266 if ( at_find_in_list(sat, soc->soc_required) < 0) {
267 if ( at_append_to_list(sat, &soc->soc_required) ) {
269 return SLAP_SCHERR_OUTOFMEM;
274 /* Now delete duplicates from the allowed list */
275 for ( satp = soc->soc_required; *satp; satp++ ) {
276 i = at_find_in_list(*satp,soc->soc_allowed);
278 at_delete_from_list(i, &soc->soc_allowed);
298 sat = at_find(*attrs1);
301 return SLAP_SCHERR_ATTR_NOT_FOUND;
303 if ( at_find_in_list(sat, soc->soc_required) < 0 &&
304 at_find_in_list(sat, soc->soc_allowed) < 0 ) {
305 if ( at_append_to_list(sat, &soc->soc_allowed) ) {
307 return SLAP_SCHERR_OUTOFMEM;
330 if ( !soc->soc_sups ) {
331 /* We are at the first recursive level */
340 soc->soc_sups = (ObjectClass **)ch_calloc(nsups,
341 sizeof(ObjectClass *));
346 soc1 = oc_find(*sups1);
349 return SLAP_SCHERR_CLASS_NOT_FOUND;
353 soc->soc_sups[nsups] = soc1;
355 code = oc_add_sups(soc,soc1->soc_sup_oids, err);
359 code = oc_create_required(soc,soc1->soc_at_oids_must,err);
362 code = oc_create_allowed(soc,soc1->soc_at_oids_may,err);
380 struct oindexrec *oir;
384 while ( *ocp != NULL ) {
385 ocp = &(*ocp)->soc_next;
389 if ( soc->soc_oid ) {
390 oir = (struct oindexrec *)
391 ch_calloc( 1, sizeof(struct oindexrec) );
392 oir->oir_name = soc->soc_oid;
395 assert( oir->oir_name );
396 assert( oir->oir_oc );
398 if ( avl_insert( &oc_index, (caddr_t) oir,
399 (AVL_CMP) oc_index_cmp,
400 (AVL_DUP) avl_dup_error ) )
403 ldap_memfree(oir->oir_name);
405 return SLAP_SCHERR_DUP_CLASS;
408 /* FIX: temporal consistency check */
409 assert( oc_find(oir->oir_name) != NULL );
412 if ( (names = soc->soc_names) ) {
414 oir = (struct oindexrec *)
415 ch_calloc( 1, sizeof(struct oindexrec) );
416 oir->oir_name = ch_strdup(*names);
419 assert( oir->oir_name );
420 assert( oir->oir_oc );
422 if ( avl_insert( &oc_index, (caddr_t) oir,
423 (AVL_CMP) oc_index_cmp,
424 (AVL_DUP) avl_dup_error ) )
427 ldap_memfree(oir->oir_name);
429 return SLAP_SCHERR_DUP_CLASS;
432 /* FIX: temporal consistency check */
433 assert( oc_find(oir->oir_name) != NULL );
444 LDAP_OBJECT_CLASS *oc,
451 soc = (ObjectClass *) ch_calloc( 1, sizeof(ObjectClass) );
452 memcpy( &soc->soc_oclass, oc, sizeof(LDAP_OBJECT_CLASS));
453 if ( (code = oc_add_sups(soc,soc->soc_sup_oids,err)) != 0 )
455 if ( (code = oc_create_required(soc,soc->soc_at_oids_must,err)) != 0 )
457 if ( (code = oc_create_allowed(soc,soc->soc_at_oids_may,err)) != 0 )
459 code = oc_insert(soc,err);
466 oc_print( ObjectClass *oc )
471 printf( "objectclass %s\n", ldap_objectclass2name( &oc->soc_oclass ) );
472 if ( oc->soc_required != NULL ) {
474 for ( i = 0; oc->soc_required[i] != NULL; i++, mid = "," )
476 ldap_attributetype2name( &oc->soc_required[i]->sat_atype ) );
479 if ( oc->soc_allowed != NULL ) {
481 for ( i = 0; oc->soc_allowed[i] != NULL; i++, mid = "," )
483 ldap_attributetype2name( &oc->soc_allowed[i]->sat_atype ) );
491 #if defined( SLAPD_SCHEMA_DN )
494 oc_schema_info( Entry *e )
497 struct berval *vals[2];
500 #ifdef SLAPD_SCHEMA_NOT_COMPAT
501 AttributeDescription *ad_objectClasses = slap_schema.si_ad_objectClasses;
503 char *ad_objectClasses = "objectClasses";
509 for ( oc = oc_list; oc; oc = oc->soc_next ) {
510 val.bv_val = ldap_objectclass2str( &oc->soc_oclass );
511 if ( val.bv_val == NULL ) {
514 val.bv_len = strlen( val.bv_val );
516 Debug( LDAP_DEBUG_TRACE, "Merging oc [%ld] %s\n",
517 (long) val.bv_len, val.bv_val, 0 );
519 attr_merge( e, ad_objectClasses, vals );
520 ldap_memfree( val.bv_val );