mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-29 02:59:34 -05:00
Support dynamic add/delete of attributeTypes and objectClasses
This commit is contained in:
parent
8e928dbb0b
commit
9f054b648b
7 changed files with 404 additions and 92 deletions
|
|
@ -110,9 +110,13 @@ at_bvfind( struct berval *name )
|
|||
|
||||
air = avl_find( attr_index, name, attr_index_name_cmp );
|
||||
|
||||
if ( air && ( slapMode & SLAP_TOOL_MODE ) && at_oc_cache ) {
|
||||
avl_insert( &attr_cache, (caddr_t) air,
|
||||
attr_index_cmp, avl_dup_error );
|
||||
if ( air ) {
|
||||
if ( air->air_at->sat_flags & SLAP_AT_DELETED ) {
|
||||
air = NULL;
|
||||
} else if (( slapMode & SLAP_TOOL_MODE ) && at_oc_cache ) {
|
||||
avl_insert( &attr_cache, (caddr_t) air,
|
||||
attr_index_cmp, avl_dup_error );
|
||||
}
|
||||
}
|
||||
|
||||
return air != NULL ? air->air_at : NULL;
|
||||
|
|
@ -204,46 +208,96 @@ at_find_in_list(
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
at_delete_names( AttributeType *at )
|
||||
{
|
||||
char **names = at->sat_names;
|
||||
|
||||
while (*names) {
|
||||
struct aindexrec tmpair, *air;
|
||||
|
||||
ber_str2bv( *names, 0, 0, &tmpair.air_name );
|
||||
tmpair.air_at = at;
|
||||
air = (struct aindexrec *)avl_delete( &attr_index,
|
||||
(caddr_t)&tmpair, attr_index_cmp );
|
||||
assert( air != NULL );
|
||||
ldap_memfree( air );
|
||||
names++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark the attribute as deleted, remove from list, and remove all its
|
||||
* names from the AVL tree. Leave the OID in the tree.
|
||||
*/
|
||||
int
|
||||
at_delete( AttributeType *at )
|
||||
{
|
||||
at->sat_flags |= SLAP_AT_DELETED;
|
||||
|
||||
LDAP_STAILQ_REMOVE(&attr_list,at,slap_attribute_type,sat_next);
|
||||
|
||||
at_delete_names( at );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
at_clean( AttributeType *a )
|
||||
{
|
||||
if ( a->sat_equality ) {
|
||||
MatchingRule *mr;
|
||||
|
||||
mr = mr_find( a->sat_equality->smr_oid );
|
||||
assert( mr != NULL );
|
||||
if ( mr != a->sat_equality ) {
|
||||
ch_free( a->sat_equality );
|
||||
a->sat_equality = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
assert( a->sat_syntax != NULL );
|
||||
if ( a->sat_syntax != NULL ) {
|
||||
Syntax *syn;
|
||||
|
||||
syn = syn_find( a->sat_syntax->ssyn_oid );
|
||||
assert( syn != NULL );
|
||||
if ( syn != a->sat_syntax ) {
|
||||
ch_free( a->sat_syntax );
|
||||
a->sat_syntax = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( a->sat_oidmacro ) ldap_memfree( a->sat_oidmacro );
|
||||
if ( a->sat_subtypes ) ldap_memfree( a->sat_subtypes );
|
||||
}
|
||||
|
||||
static void
|
||||
at_destroy_one( void *v )
|
||||
{
|
||||
struct aindexrec *air = v;
|
||||
AttributeType *a = air->air_at;
|
||||
|
||||
at_clean( a );
|
||||
ad_destroy(a->sat_ad);
|
||||
ldap_pvt_thread_mutex_destroy(&a->sat_ad_mutex);
|
||||
ldap_attributetype_free((LDAPAttributeType *)a);
|
||||
ldap_memfree(air);
|
||||
}
|
||||
|
||||
void
|
||||
at_destroy( void )
|
||||
{
|
||||
AttributeType *a;
|
||||
avl_free(attr_index, ldap_memfree);
|
||||
|
||||
while( !LDAP_STAILQ_EMPTY(&attr_list) ) {
|
||||
a = LDAP_STAILQ_FIRST(&attr_list);
|
||||
LDAP_STAILQ_REMOVE_HEAD(&attr_list, sat_next);
|
||||
|
||||
if ( a->sat_equality ) {
|
||||
MatchingRule *mr;
|
||||
|
||||
mr = mr_find( a->sat_equality->smr_oid );
|
||||
assert( mr != NULL );
|
||||
if ( mr != a->sat_equality ) {
|
||||
ch_free( a->sat_equality );
|
||||
a->sat_equality = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
assert( a->sat_syntax != NULL );
|
||||
if ( a->sat_syntax != NULL ) {
|
||||
Syntax *syn;
|
||||
|
||||
syn = syn_find( a->sat_syntax->ssyn_oid );
|
||||
assert( syn != NULL );
|
||||
if ( syn != a->sat_syntax ) {
|
||||
ch_free( a->sat_syntax );
|
||||
a->sat_syntax = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( a->sat_oidmacro ) ldap_memfree( a->sat_oidmacro );
|
||||
if ( a->sat_subtypes ) ldap_memfree( a->sat_subtypes );
|
||||
ad_destroy(a->sat_ad);
|
||||
ldap_pvt_thread_mutex_destroy(&a->sat_ad_mutex);
|
||||
ldap_attributetype_free((LDAPAttributeType *)a);
|
||||
at_delete_names( a );
|
||||
}
|
||||
|
||||
avl_free(attr_index, at_destroy_one);
|
||||
|
||||
if ( slap_schema.si_at_undefined ) {
|
||||
ad_destroy(slap_schema.si_at_undefined->sat_ad);
|
||||
}
|
||||
|
|
@ -338,36 +392,72 @@ at_check_dup(
|
|||
return SLAP_SCHERR_ATTR_DUP;
|
||||
}
|
||||
|
||||
static struct aindexrec *air_old;
|
||||
|
||||
static int
|
||||
at_dup_error( void *left, void *right )
|
||||
{
|
||||
air_old = left;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
at_insert(
|
||||
AttributeType *sat,
|
||||
AttributeType **rat,
|
||||
AttributeType *prev,
|
||||
const char **err )
|
||||
{
|
||||
struct aindexrec *air;
|
||||
char **names = NULL;
|
||||
|
||||
AttributeType *sat = *rat;
|
||||
|
||||
if ( sat->sat_oid ) {
|
||||
air = (struct aindexrec *)
|
||||
ch_calloc( 1, sizeof(struct aindexrec) );
|
||||
ber_str2bv( sat->sat_oid, 0, 0, &air->air_name );
|
||||
air->air_at = sat;
|
||||
air_old = NULL;
|
||||
|
||||
if ( avl_insert( &attr_index, (caddr_t) air,
|
||||
attr_index_cmp, avl_dup_error ) )
|
||||
attr_index_cmp, at_dup_error ) )
|
||||
{
|
||||
AttributeType *old_sat;
|
||||
int rc;
|
||||
|
||||
*err = sat->sat_oid;
|
||||
|
||||
old_sat = at_bvfind( &air->air_name );
|
||||
assert( old_sat != NULL );
|
||||
rc = at_check_dup( old_sat, sat );
|
||||
assert( air_old != NULL );
|
||||
old_sat = air_old->air_at;
|
||||
|
||||
ldap_memfree( air );
|
||||
/* replacing a deleted definition? */
|
||||
if ( old_sat->sat_flags & SLAP_AT_DELETED ) {
|
||||
AttributeType tmp;
|
||||
|
||||
/* Keep old oid, free new oid;
|
||||
* Keep old ads, free new ads;
|
||||
* Keep new everything else, free old
|
||||
*/
|
||||
tmp = *old_sat;
|
||||
*old_sat = *sat;
|
||||
old_sat->sat_oid = tmp.sat_oid;
|
||||
tmp.sat_oid = sat->sat_oid;
|
||||
old_sat->sat_ad = tmp.sat_ad;
|
||||
tmp.sat_ad = sat->sat_ad;
|
||||
*sat = tmp;
|
||||
|
||||
return rc;
|
||||
at_clean( sat );
|
||||
at_destroy_one( air );
|
||||
|
||||
air = air_old;
|
||||
sat = old_sat;
|
||||
*rat = sat;
|
||||
} else {
|
||||
ldap_memfree( air );
|
||||
|
||||
rc = at_check_dup( old_sat, sat );
|
||||
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
/* FIX: temporal consistency check */
|
||||
at_bvfind( &air->air_name );
|
||||
|
|
@ -437,7 +527,11 @@ at_insert(
|
|||
}
|
||||
}
|
||||
|
||||
LDAP_STAILQ_INSERT_TAIL( &attr_list, sat, sat_next );
|
||||
if ( prev ) {
|
||||
LDAP_STAILQ_INSERT_AFTER( &attr_list, prev, sat, sat_next );
|
||||
} else {
|
||||
LDAP_STAILQ_INSERT_TAIL( &attr_list, sat, sat_next );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -447,6 +541,7 @@ at_add(
|
|||
LDAPAttributeType *at,
|
||||
int user,
|
||||
AttributeType **rsat,
|
||||
AttributeType *prev,
|
||||
const char **err )
|
||||
{
|
||||
AttributeType *sat = NULL;
|
||||
|
|
@ -769,7 +864,7 @@ at_add(
|
|||
sat->sat_substr = mr;
|
||||
}
|
||||
|
||||
code = at_insert( sat, err );
|
||||
code = at_insert( &sat, prev, err );
|
||||
if ( code != 0 ) {
|
||||
error_return:;
|
||||
if ( sat ) {
|
||||
|
|
@ -909,7 +1004,7 @@ register_at( char *def, AttributeDescription **rad, int dupok )
|
|||
return code;
|
||||
}
|
||||
|
||||
code = at_add( at, 0, NULL, &err );
|
||||
code = at_add( at, 0, NULL, NULL, &err );
|
||||
if ( code ) {
|
||||
if ( code == SLAP_SCHERR_ATTR_DUP && dupok ) {
|
||||
freeit = 1;
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ static ConfigTable config_back_cf_table[] = {
|
|||
"EQUALITY caseIgnoreMatch "
|
||||
"SYNTAX OMsDirectoryString )", NULL, NULL },
|
||||
{ "attribute", "attribute", 2, 0, STRLENOF( "attribute" ),
|
||||
ARG_PAREN|ARG_MAGIC|CFG_ATTR|ARG_NO_DELETE|ARG_NO_INSERT,
|
||||
ARG_PAREN|ARG_MAGIC|CFG_ATTR,
|
||||
&config_generic, "( OLcfgGlAt:4 NAME 'olcAttributeTypes' "
|
||||
"DESC 'OpenLDAP attributeTypes' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
|
|
@ -387,7 +387,7 @@ static ConfigTable config_back_cf_table[] = {
|
|||
ARG_MAGIC|CFG_MONITORING|ARG_DB|ARG_ON_OFF, &config_generic,
|
||||
"( OLcfgDbAt:0.18 NAME 'olcMonitoring' "
|
||||
"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
|
||||
{ "objectclass", "objectclass", 2, 0, 0, ARG_PAREN|ARG_MAGIC|CFG_OC|ARG_NO_DELETE|ARG_NO_INSERT,
|
||||
{ "objectclass", "objectclass", 2, 0, 0, ARG_PAREN|ARG_MAGIC|CFG_OC,
|
||||
&config_generic, "( OLcfgGlAt:32 NAME 'olcObjectClasses' "
|
||||
"DESC 'OpenLDAP object classes' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
|
|
@ -1108,6 +1108,49 @@ config_generic(ConfigArgs *c) {
|
|||
}
|
||||
break;
|
||||
|
||||
case CFG_OC: {
|
||||
CfEntryInfo *ce = c->ca_entry->e_private;
|
||||
/* can't modify the hardcoded schema */
|
||||
if ( ce->ce_parent->ce_type == Cft_Global )
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case CFG_ATTR: {
|
||||
CfEntryInfo *ce = c->ca_entry->e_private;
|
||||
/* can't modify the hardcoded schema */
|
||||
if ( ce->ce_parent->ce_type == Cft_Global )
|
||||
return 1;
|
||||
}
|
||||
cfn = c->private;
|
||||
if ( c->valx < 0 ) {
|
||||
AttributeType *at;
|
||||
|
||||
for( at = cfn->c_at_head; at; at_next( &at )) {
|
||||
at_delete( at );
|
||||
if ( at == cfn->c_at_tail )
|
||||
break;
|
||||
}
|
||||
cfn->c_at_head = cfn->c_at_tail = NULL;
|
||||
} else {
|
||||
AttributeType *at, *prev = NULL;
|
||||
int i;
|
||||
|
||||
for ( i=0, at=cfn->c_at_head; i<c->valx; i++) {
|
||||
prev = at;
|
||||
at_next( &at );
|
||||
}
|
||||
at_delete( at );
|
||||
if ( cfn->c_at_tail == at ) {
|
||||
cfn->c_at_tail = prev;
|
||||
}
|
||||
if ( cfn->c_at_head == at ) {
|
||||
at_next( &at );
|
||||
cfn->c_at_head = at;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CFG_LIMITS:
|
||||
/* FIXME: there is no limits_free function */
|
||||
case CFG_ATOPT:
|
||||
|
|
@ -1116,9 +1159,7 @@ config_generic(ConfigArgs *c) {
|
|||
/* FIXME: there is no way to remove attributes added by
|
||||
a DSE file */
|
||||
case CFG_OID:
|
||||
case CFG_OC:
|
||||
case CFG_DIT:
|
||||
case CFG_ATTR:
|
||||
case CFG_MODPATH:
|
||||
default:
|
||||
rc = 1;
|
||||
|
|
@ -1243,6 +1284,8 @@ config_generic(ConfigArgs *c) {
|
|||
case CFG_OID: {
|
||||
OidMacro *om;
|
||||
|
||||
if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
|
||||
cfn = c->private;
|
||||
if(parse_oidm(c->fname, c->lineno, c->argc, c->argv, 1, &om))
|
||||
return(1);
|
||||
if (!cfn->c_om_head) cfn->c_om_head = om;
|
||||
|
|
@ -1251,32 +1294,80 @@ config_generic(ConfigArgs *c) {
|
|||
break;
|
||||
|
||||
case CFG_OC: {
|
||||
ObjectClass *oc;
|
||||
ObjectClass *oc, *prev;
|
||||
|
||||
if(parse_oc(c->fname, c->lineno, p, c->argv, &oc)) return(1);
|
||||
if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
|
||||
cfn = c->private;
|
||||
if ( c->valx < 0 ) {
|
||||
prev = cfn->c_oc_tail;
|
||||
} else {
|
||||
prev = NULL;
|
||||
/* If adding anything after the first, prev is easy */
|
||||
if ( c->valx ) {
|
||||
int i;
|
||||
for (i=0, oc = cfn->c_oc_head; i<c->valx; i++) {
|
||||
prev = oc;
|
||||
oc_next( &oc );
|
||||
}
|
||||
} else
|
||||
/* If adding the first, and head exists, find its prev */
|
||||
if (cfn->c_oc_head) {
|
||||
for ( oc_start( &oc ); oc != cfn->c_oc_head; ) {
|
||||
prev = oc;
|
||||
oc_next( &oc );
|
||||
}
|
||||
}
|
||||
/* else prev is NULL, append to end of global list */
|
||||
}
|
||||
if(parse_oc(c->fname, c->lineno, p, c->argv, &oc, prev)) return(1);
|
||||
if (!cfn->c_oc_head) cfn->c_oc_head = oc;
|
||||
cfn->c_oc_tail = oc;
|
||||
if (cfn->c_oc_tail == prev) cfn->c_oc_tail = oc;
|
||||
}
|
||||
break;
|
||||
|
||||
case CFG_ATTR: {
|
||||
AttributeType *at, *prev;
|
||||
|
||||
if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
|
||||
cfn = c->private;
|
||||
if ( c->valx < 0 ) {
|
||||
prev = cfn->c_at_tail;
|
||||
} else {
|
||||
prev = NULL;
|
||||
/* If adding anything after the first, prev is easy */
|
||||
if ( c->valx ) {
|
||||
int i;
|
||||
for (i=0, at = cfn->c_at_head; i<c->valx; i++) {
|
||||
prev = at;
|
||||
at_next( &at );
|
||||
}
|
||||
} else
|
||||
/* If adding the first, and head exists, find its prev */
|
||||
if (cfn->c_at_head) {
|
||||
for ( at_start( &at ); at != cfn->c_at_head; ) {
|
||||
prev = at;
|
||||
at_next( &at );
|
||||
}
|
||||
}
|
||||
/* else prev is NULL, append to end of global list */
|
||||
}
|
||||
if(parse_at(c->fname, c->lineno, p, c->argv, &at, prev)) return(1);
|
||||
if (!cfn->c_at_head) cfn->c_at_head = at;
|
||||
if (cfn->c_at_tail == prev) cfn->c_at_tail = at;
|
||||
}
|
||||
break;
|
||||
|
||||
case CFG_DIT: {
|
||||
ContentRule *cr;
|
||||
|
||||
if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
|
||||
cfn = c->private;
|
||||
if(parse_cr(c->fname, c->lineno, p, c->argv, &cr)) return(1);
|
||||
if (!cfn->c_cr_head) cfn->c_cr_head = cr;
|
||||
cfn->c_cr_tail = cr;
|
||||
}
|
||||
break;
|
||||
|
||||
case CFG_ATTR: {
|
||||
AttributeType *at;
|
||||
|
||||
if(parse_at(c->fname, c->lineno, p, c->argv, &at)) return(1);
|
||||
if (!cfn->c_at_head) cfn->c_at_head = at;
|
||||
cfn->c_at_tail = at;
|
||||
}
|
||||
break;
|
||||
|
||||
case CFG_ATOPT:
|
||||
ad_define_option(NULL, NULL, 0);
|
||||
for(i = 1; i < c->argc; i++)
|
||||
|
|
@ -1388,6 +1479,8 @@ config_generic(ConfigArgs *c) {
|
|||
{
|
||||
struct berval bv;
|
||||
ber_str2bv( c->argv[1], 0, 1, &bv );
|
||||
if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
|
||||
cfn = c->private;
|
||||
ber_bvarray_add( &cfn->c_dseFiles, &bv );
|
||||
}
|
||||
break;
|
||||
|
|
@ -3416,7 +3509,7 @@ check_vals( ConfigTable *ct, ConfigArgs *ca, void *ptr, int isAttr )
|
|||
AttributeDescription *ad;
|
||||
BerVarray vals;
|
||||
|
||||
int i, rc = 0, sort = 0;
|
||||
int i, rc = 0;
|
||||
|
||||
if ( isAttr ) {
|
||||
a = ptr;
|
||||
|
|
@ -3429,7 +3522,6 @@ check_vals( ConfigTable *ct, ConfigArgs *ca, void *ptr, int isAttr )
|
|||
}
|
||||
|
||||
if ( a && ( ad->ad_type->sat_flags & SLAP_AT_ORDERED_VAL )) {
|
||||
sort = 1;
|
||||
rc = ordered_value_sort( a, 1 );
|
||||
if ( rc ) {
|
||||
snprintf(ca->msg, sizeof( ca->msg ), "ordered_value_sort failed on attr %s\n",
|
||||
|
|
@ -3439,7 +3531,7 @@ check_vals( ConfigTable *ct, ConfigArgs *ca, void *ptr, int isAttr )
|
|||
}
|
||||
for ( i=0; vals[i].bv_val; i++ ) {
|
||||
ca->line = vals[i].bv_val;
|
||||
if ( sort ) {
|
||||
if ( ad->ad_type->sat_flags & SLAP_AT_ORDERED_VAL ) {
|
||||
char *idx = strchr( ca->line, '}' );
|
||||
if ( idx ) ca->line = idx+1;
|
||||
}
|
||||
|
|
@ -4169,8 +4261,9 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
|
|||
if ( rc ) rc = LDAP_OTHER;
|
||||
}
|
||||
if ( ml->sml_values ) {
|
||||
d = d->next;
|
||||
ch_free( dels );
|
||||
dels = d->next;
|
||||
dels = d;
|
||||
}
|
||||
if ( ml->sml_op == LDAP_MOD_REPLACE ) {
|
||||
ml->sml_values = vals;
|
||||
|
|
|
|||
|
|
@ -386,23 +386,73 @@ oc_add_sups(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
oc_delete_names( ObjectClass *oc )
|
||||
{
|
||||
char **names = oc->soc_names;
|
||||
|
||||
while (*names) {
|
||||
struct oindexrec tmpoir, *oir;
|
||||
|
||||
ber_str2bv( *names, 0, 0, &tmpoir.oir_name );
|
||||
tmpoir.oir_oc = oc;
|
||||
oir = (struct oindexrec *)avl_delete( &oc_index,
|
||||
(caddr_t)&tmpoir, oc_index_cmp );
|
||||
assert( oir != NULL );
|
||||
ldap_memfree( oir );
|
||||
names++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark the ObjectClass as deleted, remove from list, and remove all its
|
||||
* names from the AVL tree. Leave the OID in the tree.
|
||||
*/
|
||||
int
|
||||
oc_delete( ObjectClass *oc )
|
||||
{
|
||||
oc->soc_flags |= SLAP_OC_DELETED;
|
||||
|
||||
LDAP_STAILQ_REMOVE(&oc_list,oc,slap_object_class,soc_next);
|
||||
|
||||
oc_delete_names( oc );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
oc_clean( ObjectClass *o )
|
||||
{
|
||||
if (o->soc_sups) ldap_memfree(o->soc_sups);
|
||||
if (o->soc_required) ldap_memfree(o->soc_required);
|
||||
if (o->soc_allowed) ldap_memfree(o->soc_allowed);
|
||||
if (o->soc_oidmacro) ldap_memfree(o->soc_oidmacro);
|
||||
}
|
||||
|
||||
static void
|
||||
oc_destroy_one( void *v )
|
||||
{
|
||||
struct oindexrec *oir = v;
|
||||
ObjectClass *o = oir->oir_oc;
|
||||
|
||||
oc_clean( o );
|
||||
ldap_objectclass_free((LDAPObjectClass *)o);
|
||||
ldap_memfree(oir);
|
||||
}
|
||||
|
||||
void
|
||||
oc_destroy( void )
|
||||
{
|
||||
ObjectClass *o;
|
||||
|
||||
avl_free(oc_index, ldap_memfree);
|
||||
while( !LDAP_STAILQ_EMPTY(&oc_list) ) {
|
||||
o = LDAP_STAILQ_FIRST(&oc_list);
|
||||
LDAP_STAILQ_REMOVE_HEAD(&oc_list, soc_next);
|
||||
|
||||
if (o->soc_sups) ldap_memfree(o->soc_sups);
|
||||
if (o->soc_required) ldap_memfree(o->soc_required);
|
||||
if (o->soc_allowed) ldap_memfree(o->soc_allowed);
|
||||
if (o->soc_oidmacro) ldap_memfree(o->soc_oidmacro);
|
||||
ldap_objectclass_free((LDAPObjectClass *)o);
|
||||
oc_delete_names( o );
|
||||
}
|
||||
|
||||
avl_free( oc_index, oc_destroy_one );
|
||||
|
||||
while( !LDAP_STAILQ_EMPTY(&oc_undef_list) ) {
|
||||
o = LDAP_STAILQ_FIRST(&oc_undef_list);
|
||||
LDAP_STAILQ_REMOVE_HEAD(&oc_undef_list, soc_next);
|
||||
|
|
@ -411,6 +461,40 @@ oc_destroy( void )
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
oc_start( ObjectClass **oc )
|
||||
{
|
||||
assert( oc != NULL );
|
||||
|
||||
*oc = LDAP_STAILQ_FIRST(&oc_list);
|
||||
|
||||
return (*oc != NULL);
|
||||
}
|
||||
|
||||
int
|
||||
oc_next( ObjectClass **oc )
|
||||
{
|
||||
assert( oc != NULL );
|
||||
|
||||
#if 1 /* pedantic check */
|
||||
{
|
||||
ObjectClass *tmp = NULL;
|
||||
|
||||
LDAP_STAILQ_FOREACH(tmp,&oc_list,soc_next) {
|
||||
if ( tmp == *oc ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert( tmp != NULL );
|
||||
}
|
||||
#endif
|
||||
|
||||
*oc = LDAP_STAILQ_NEXT(*oc,soc_next);
|
||||
|
||||
return (*oc != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* check whether the two ObjectClasses actually __are__ identical,
|
||||
* or rather inconsistent
|
||||
|
|
@ -462,38 +546,68 @@ oc_check_dup(
|
|||
return SLAP_SCHERR_CLASS_DUP;
|
||||
}
|
||||
|
||||
static struct oindexrec *oir_old;
|
||||
|
||||
static int
|
||||
oc_dup_error( void *left, void *right )
|
||||
{
|
||||
oir_old = left;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
oc_insert(
|
||||
ObjectClass *soc,
|
||||
ObjectClass **roc,
|
||||
ObjectClass *prev,
|
||||
const char **err )
|
||||
{
|
||||
struct oindexrec *oir;
|
||||
char **names;
|
||||
ObjectClass *soc = *roc;
|
||||
|
||||
if ( soc->soc_oid ) {
|
||||
oir = (struct oindexrec *)
|
||||
ch_calloc( 1, sizeof(struct oindexrec) );
|
||||
oir->oir_name.bv_val = soc->soc_oid;
|
||||
oir->oir_name.bv_len = strlen( soc->soc_oid );
|
||||
ber_str2bv( soc->soc_oid, 0, 0, &oir->oir_name );
|
||||
oir->oir_oc = soc;
|
||||
|
||||
assert( oir->oir_name.bv_val != NULL );
|
||||
assert( oir->oir_oc != NULL );
|
||||
oir_old = NULL;
|
||||
|
||||
if ( avl_insert( &oc_index, (caddr_t) oir,
|
||||
oc_index_cmp, avl_dup_error ) )
|
||||
oc_index_cmp, oc_dup_error ) )
|
||||
{
|
||||
ObjectClass *old_soc;
|
||||
int rc;
|
||||
|
||||
*err = soc->soc_oid;
|
||||
|
||||
old_soc = oc_bvfind( &oir->oir_name );
|
||||
assert( old_soc != NULL );
|
||||
rc = oc_check_dup( old_soc, soc );
|
||||
assert( oir_old != NULL );
|
||||
old_soc = oir_old->oir_oc;
|
||||
|
||||
ldap_memfree( oir );
|
||||
return rc;
|
||||
/* replacing a deleted definition? */
|
||||
if ( old_soc->soc_flags & SLAP_OC_DELETED ) {
|
||||
ObjectClass tmp;
|
||||
|
||||
/* Keep old oid, free new oid;
|
||||
* Keep new everything else, free old
|
||||
*/
|
||||
tmp = *old_soc;
|
||||
*old_soc = *soc;
|
||||
old_soc->soc_oid = tmp.soc_oid;
|
||||
tmp.soc_oid = soc->soc_oid;
|
||||
*soc = tmp;
|
||||
|
||||
oc_clean( soc );
|
||||
oc_destroy_one( oir );
|
||||
|
||||
oir = oir_old;
|
||||
soc = old_soc;
|
||||
*roc = soc;
|
||||
} else {
|
||||
rc = oc_check_dup( old_soc, soc );
|
||||
|
||||
ldap_memfree( oir );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIX: temporal consistency check */
|
||||
|
|
@ -567,6 +681,7 @@ oc_add(
|
|||
LDAPObjectClass *oc,
|
||||
int user,
|
||||
ObjectClass **rsoc,
|
||||
ObjectClass *prev,
|
||||
const char **err )
|
||||
{
|
||||
ObjectClass *soc;
|
||||
|
|
@ -646,7 +761,7 @@ oc_add(
|
|||
soc->soc_flags |= SLAP_OC_HARDCODE;
|
||||
}
|
||||
|
||||
code = oc_insert(soc,err);
|
||||
code = oc_insert(&soc,prev,err);
|
||||
done:;
|
||||
if ( code != 0 ) {
|
||||
if ( soc->soc_sups ) {
|
||||
|
|
@ -770,7 +885,7 @@ register_oc( char *def, ObjectClass **soc, int dupok )
|
|||
def, ldap_scherr2str(code), err );
|
||||
return code;
|
||||
}
|
||||
code = oc_add(oc,0,NULL,&err);
|
||||
code = oc_add(oc,0,NULL,NULL,&err);
|
||||
if ( code && ( code != SLAP_SCHERR_CLASS_DUP || !dupok )) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"register_oc: objectclass \"%s\": %s, %s\n",
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ LDAP_SLAPD_F (int) at_delete_from_list LDAP_P((
|
|||
LDAP_SLAPD_F (int) at_schema_info LDAP_P(( Entry *e ));
|
||||
LDAP_SLAPD_F (int) at_add LDAP_P((
|
||||
LDAPAttributeType *at, int user,
|
||||
AttributeType **sat, const char **err ));
|
||||
AttributeType **sat, AttributeType *prev, const char **err ));
|
||||
LDAP_SLAPD_F (void) at_destroy LDAP_P(( void ));
|
||||
|
||||
LDAP_SLAPD_F (int) is_at_subtype LDAP_P((
|
||||
|
|
@ -1187,6 +1187,7 @@ LDAP_SLAPD_F (int) oc_add LDAP_P((
|
|||
LDAPObjectClass *oc,
|
||||
int user,
|
||||
ObjectClass **soc,
|
||||
ObjectClass *prev,
|
||||
const char **err));
|
||||
LDAP_SLAPD_F (void) oc_destroy LDAP_P(( void ));
|
||||
|
||||
|
|
@ -1238,6 +1239,10 @@ LDAP_SLAPD_F (int) is_entry_objectclass LDAP_P((
|
|||
: is_entry_objectclass((e), slap_schema.si_oc_syncConsumerSubentry, SLAP_OCF_SET_FLAGS))
|
||||
|
||||
LDAP_SLAPD_F (int) oc_schema_info( Entry *e );
|
||||
|
||||
LDAP_SLAPD_F (int) oc_start LDAP_P(( ObjectClass **at ));
|
||||
LDAP_SLAPD_F (int) oc_next LDAP_P(( ObjectClass **at ));
|
||||
|
||||
LDAP_SLAPD_F (void) oc_unparse LDAP_P((
|
||||
BerVarray *bva, ObjectClass *start, ObjectClass *end, int system ));
|
||||
|
||||
|
|
@ -1565,10 +1570,10 @@ LDAP_SLAPD_F (int) parse_cr LDAP_P((
|
|||
ContentRule **scr ));
|
||||
LDAP_SLAPD_F (int) parse_oc LDAP_P((
|
||||
const char *fname, int lineno, char *line, char **argv,
|
||||
ObjectClass **soc ));
|
||||
ObjectClass **soc, ObjectClass *prev ));
|
||||
LDAP_SLAPD_F (int) parse_at LDAP_P((
|
||||
const char *fname, int lineno, char *line, char **argv,
|
||||
AttributeType **sat ));
|
||||
AttributeType **sat, AttributeType *prev ));
|
||||
LDAP_SLAPD_F (char *) scherr2str LDAP_P((int code)) LDAP_GCCATTR((const));
|
||||
LDAP_SLAPD_F (int) dscompare LDAP_P(( const char *s1, const char *s2del,
|
||||
char delim ));
|
||||
|
|
|
|||
|
|
@ -1195,7 +1195,7 @@ slap_schema_load( void )
|
|||
return LDAP_OTHER;
|
||||
}
|
||||
|
||||
code = at_add( at, 0, NULL, &err );
|
||||
code = at_add( at, 0, NULL, NULL, &err );
|
||||
if ( code ) {
|
||||
ldap_attributetype_free( at );
|
||||
fprintf( stderr, "slap_schema_load: AttributeType "
|
||||
|
|
@ -1311,7 +1311,7 @@ slap_schema_load( void )
|
|||
return LDAP_OTHER;
|
||||
}
|
||||
|
||||
code = oc_add(oc,0,NULL,&err);
|
||||
code = oc_add(oc,0,NULL,NULL,&err);
|
||||
if ( code ) {
|
||||
ldap_objectclass_free( oc );
|
||||
fprintf( stderr, "slap_schema_load: ObjectClass "
|
||||
|
|
|
|||
|
|
@ -176,7 +176,8 @@ parse_oc(
|
|||
int lineno,
|
||||
char *line,
|
||||
char **argv,
|
||||
ObjectClass **soc )
|
||||
ObjectClass **soc,
|
||||
ObjectClass *prev )
|
||||
{
|
||||
LDAPObjectClass *oc;
|
||||
int code;
|
||||
|
|
@ -199,7 +200,7 @@ parse_oc(
|
|||
goto done;
|
||||
}
|
||||
|
||||
code = oc_add( oc, 1, soc, &err );
|
||||
code = oc_add( oc, 1, soc, prev, &err );
|
||||
if ( code ) {
|
||||
fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
|
||||
fname, lineno, scherr2str( code ), err );
|
||||
|
|
@ -267,7 +268,8 @@ parse_at(
|
|||
int lineno,
|
||||
char *line,
|
||||
char **argv,
|
||||
AttributeType **sat )
|
||||
AttributeType **sat,
|
||||
AttributeType *prev )
|
||||
{
|
||||
LDAPAttributeType *at;
|
||||
int code;
|
||||
|
|
@ -298,7 +300,7 @@ parse_at(
|
|||
goto done;
|
||||
}
|
||||
|
||||
code = at_add( at, 1, sat, &err);
|
||||
code = at_add( at, 1, sat, prev, &err);
|
||||
if ( code ) {
|
||||
fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
|
||||
fname, lineno, scherr2str(code), err);
|
||||
|
|
|
|||
|
|
@ -662,6 +662,7 @@ typedef struct slap_attribute_type {
|
|||
#define SLAP_AT_ORDERED 0x0003U /* value has order index */
|
||||
|
||||
#define SLAP_AT_HARDCODE 0x10000U /* hardcoded schema */
|
||||
#define SLAP_AT_DELETED 0x20000U
|
||||
|
||||
slap_mask_t sat_flags;
|
||||
|
||||
|
|
@ -744,6 +745,7 @@ typedef struct slap_object_class {
|
|||
#define SLAP_OC_HIDE 0x8000
|
||||
#endif
|
||||
#define SLAP_OC_HARDCODE 0x10000U /* This is hardcoded schema */
|
||||
#define SLAP_OC_DELETED 0x20000U
|
||||
|
||||
/*
|
||||
* DIT content rule
|
||||
|
|
|
|||
Loading…
Reference in a new issue