Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
orbea -
OpenLDAP
Commits
9f054b64
Commit
9f054b64
authored
Sep 14, 2006
by
Howard Chu
Browse files
Support dynamic add/delete of attributeTypes and objectClasses
parent
8e928dbb
Changes
7
Hide whitespace changes
Inline
Side-by-side
servers/slapd/at.c
View file @
9f054b64
...
...
@@ -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
;
}
void
at_de
stroy
(
void
)
static
void
at_de
lete_names
(
AttributeType
*
at
)
{
AttributeType
*
a
;
avl_free
(
attr_index
,
ldap_memfree
);
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
++
;
}
}
while
(
!
LDAP_STAILQ_EMPTY
(
&
attr_list
)
)
{
a
=
LDAP_STAILQ_FIRST
(
&
attr_list
);
LDAP_STAILQ_REMOVE_HEAD
(
&
attr_list
,
sat_next
);
/* 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
;
if
(
a
->
sat_equality
)
{
MatchingRule
*
mr
;
LDAP_STAILQ_REMOVE
(
&
attr_list
,
at
,
slap_attribute_type
,
sat_next
);
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
;
}
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
;
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
;
}
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
);
}
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
);
void
at_destroy
(
void
)
{
AttributeType
*
a
;
while
(
!
LDAP_STAILQ_EMPTY
(
&
attr_list
)
)
{
a
=
LDAP_STAILQ_FIRST
(
&
attr_list
);
LDAP_STAILQ_REMOVE_HEAD
(
&
attr_list
,
sat_next
);
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
,
a
vl
_dup_error
)
)
attr_index_cmp
,
a
t
_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
;
/* 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
;
at_clean
(
sat
);
at_destroy_one
(
air
);
air
=
air_old
;
sat
=
old_sat
;
*
rat
=
sat
;
}
else
{
ldap_memfree
(
air
);
ldap_memfree
(
air
);
rc
=
at_check_dup
(
old_sat
,
sat
);
return
rc
;
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
;
...
...
servers/slapd/bconfig.c
View file @
9f054b64
...
...
@@ -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;
...
...
servers/slapd/oc.c
View file @
9f054b64
...
...
@@ -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
);