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
Tero Saarni
OpenLDAP
Commits
43e0ae8d
Commit
43e0ae8d
authored
Jan 31, 2011
by
Quanah Gibson-Mount
Browse files
ITS#6684
parent
1c8bfbe5
Changes
3
Hide whitespace changes
Inline
Side-by-side
CHANGES
View file @
43e0ae8d
...
...
@@ -130,6 +130,8 @@ OpenLDAP 2.4.24 Engineering
Fixed slapo-translucent entry leak (ITS#6746)
Fixed contrib/autogroup install location (ITS#6684)
Fixed contrib/autogroup crash with ppolicy (ITS#6684)
Fixed contrib/autogroup with non-DN URIs (ITS#6684)
Fixed contrib/autogroup with memberOf overlay (ITS#6684)
Fixed contrib/cloak when returning multiple entries (ITS#6762)
Fixed contrib/nssov to only close socket on shutdown (ITS#6676)
Fixed contrib/nssov multi platform support (ITS#6604)
...
...
contrib/slapd-modules/autogroup/README
View file @
43e0ae8d
...
...
@@ -51,6 +51,14 @@ CONFIGURATION
specifies the member attribute. User modification of this attribute
is disabled for consistency.
autogroup-memberof-ad <memberof-ad>
This configuration option is defined for the autogroup overlay.
It defines the attribute that is used by the memberOf overlay
to store the names of groups that an entry is member of; it must be
DN-valued. It should be set to the same value as
memberof-memberof-ad. It defaults to 'memberOf'.
EXAMPLE
### slapd.conf
...
...
@@ -66,6 +74,24 @@ EXAMPLE
autogroup-attrset groupOfURLs memberURL member
### end slapd.conf
### slapd.conf
include /path/to/dyngroup.schema
# ...
moduleload /path/to/autogroup.so
moduleload /path/to/memberof.so
# ...
database <database>
#...
overlay memberof
memberof-memberof-ad foo
overlay autogroup
autogroup-attrset groupOfURLs memberURL member
autogroup-memberof-ad foo
### end slapd.conf
CAVEATS
As with static groups, update operations on groups with a large number
of members may be slow.
...
...
@@ -76,7 +102,9 @@ CAVEATS
number of entries.
ACKNOWLEDGEMENTS
This module was originally written in 2007 by Michał Szulczyński.
This module was originally written in 2007 by Michał Szulczyński. Further
enhancements were contributed by Howard Chu, Raphael Ouazana,
Norbert Pueschel, and Christian Manal.
---
Copyright 1998-2011 The OpenLDAP Foundation.
...
...
contrib/slapd-modules/autogroup/autogroup.c
View file @
43e0ae8d
...
...
@@ -19,6 +19,9 @@
* This work was initially developed by Michał Szulczyński for inclusion in
* OpenLDAP Software. Additional significant contributors include:
* Howard Chu
* Raphael Ouazana
* Norbert Pueschel
* Christian Manal
*/
#include
"portable.h"
...
...
@@ -31,6 +34,10 @@
#include
"config.h"
#include
"lutil.h"
#ifndef SLAPD_MEMBEROF_ATTR
#define SLAPD_MEMBEROF_ATTR "memberOf"
#endif
/* Filter represents the memberURL of a group. */
typedef
struct
autogroup_filter_t
{
struct
berval
agf_dn
;
/* The base DN in memberURL */
...
...
@@ -66,6 +73,7 @@ typedef struct autogroup_entry_t {
typedef
struct
autogroup_info_t
{
autogroup_def_t
*
agi_def
;
/* Group attributes definitions. */
autogroup_entry_t
*
agi_entry
;
/* Group entries. */
AttributeDescription
*
agi_memberof_ad
;
/* memberOf attribute description */
ldap_pvt_thread_mutex_t
agi_mutex
;
}
autogroup_info_t
;
...
...
@@ -257,6 +265,56 @@ autogroup_delete_member_from_group( Operation *op, BerValue *dn, BerValue *ndn,
return
sreply
.
sr_err
;
}
/*
** e - the entry where to get the attribute values
** age - the group from which the values will be deleted
*/
static
int
autogroup_delete_member_values_from_group
(
Operation
*
op
,
Entry
*
e
,
autogroup_entry_t
*
age
,
AttributeDescription
*
attrdesc
)
{
slap_overinst
*
on
=
(
slap_overinst
*
)
op
->
o_bd
->
bd_info
;
Modifications
modlist
;
SlapReply
sreply
=
{
REP_RESULT
};
Attribute
*
attr
;
slap_callback
cb
=
{
NULL
,
slap_null_cb
,
NULL
,
NULL
};
Operation
o
=
*
op
;
Debug
(
LDAP_DEBUG_TRACE
,
"==> autogroup_delete_member_values_from_group removing <%s> from <%s>
\n
"
,
e
->
e_name
.
bv_val
,
age
->
age_dn
.
bv_val
,
0
);
assert
(
e
!=
NULL
);
attr
=
attrs_find
(
e
->
e_attrs
,
attrdesc
);
if
(
!
attr
)
{
// Nothing to add
return
LDAP_SUCCESS
;
}
modlist
.
sml_op
=
LDAP_MOD_DELETE
;
modlist
.
sml_desc
=
age
->
age_def
->
agd_member_ad
;
modlist
.
sml_type
=
age
->
age_def
->
agd_member_ad
->
ad_cname
;
modlist
.
sml_values
=
attr
->
a_vals
;
modlist
.
sml_nvalues
=
attr
->
a_nvals
;
modlist
.
sml_numvals
=
attr
->
a_numvals
;
modlist
.
sml_flags
=
SLAP_MOD_INTERNAL
;
modlist
.
sml_next
=
NULL
;
o
.
o_tag
=
LDAP_REQ_MODIFY
;
o
.
o_callback
=
&
cb
;
o
.
orm_modlist
=
&
modlist
;
o
.
o_req_dn
=
age
->
age_dn
;
o
.
o_req_ndn
=
age
->
age_ndn
;
o
.
o_permissive_modify
=
1
;
o
.
o_managedsait
=
SLAP_CONTROL_CRITICAL
;
o
.
o_relax
=
SLAP_CONTROL_CRITICAL
;
o
.
o_bd
->
bd_info
=
(
BackendInfo
*
)
on
->
on_info
;
(
void
)
op
->
o_bd
->
be_modify
(
&
o
,
&
sreply
);
o
.
o_bd
->
bd_info
=
(
BackendInfo
*
)
on
;
return
sreply
.
sr_err
;
}
/*
** Callback used to add entries to a group,
** which are going to be written in the database
...
...
@@ -663,10 +721,10 @@ autogroup_group_add_cb( Operation *op, SlapReply *rs )
static
int
autogroup_add_entry
(
Operation
*
op
,
SlapReply
*
rs
)
{
slap_overinst
*
on
=
(
slap_overinst
*
)
op
->
o_bd
->
bd_info
;
autogroup_info_t
*
agi
=
(
autogroup_info_t
*
)
on
->
on_bi
.
bi_private
;
slap_overinst
*
on
=
(
slap_overinst
*
)
op
->
o_bd
->
bd_info
;
autogroup_info_t
*
agi
=
(
autogroup_info_t
*
)
on
->
on_bi
.
bi_private
;
autogroup_def_t
*
agd
=
agi
->
agi_def
;
autogroup_entry_t
*
age
=
agi
->
agi_entry
;
autogroup_entry_t
*
age
;
autogroup_filter_t
*
agf
;
int
rc
=
0
;
...
...
@@ -697,7 +755,8 @@ autogroup_add_entry( Operation *op, SlapReply *rs)
}
}
for
(
;
age
;
age
=
age
->
age_next
)
{
for
(
age
=
agi
->
agi_entry
;
age
;
age
=
age
->
age_next
)
{
ldap_pvt_thread_mutex_lock
(
&
age
->
age_mutex
);
/* Check if any of the filters are the suffix to the entry DN.
...
...
@@ -786,9 +845,8 @@ static int
autogroup_delete_entry
(
Operation
*
op
,
SlapReply
*
rs
)
{
slap_overinst
*
on
=
(
slap_overinst
*
)
op
->
o_bd
->
bd_info
;
autogroup_info_t
*
agi
=
(
autogroup_info_t
*
)
on
->
on_bi
.
bi_private
;
autogroup_entry_t
*
age
=
agi
->
agi_entry
,
*
age_prev
,
*
age_next
;
autogroup_info_t
*
agi
=
(
autogroup_info_t
*
)
on
->
on_bi
.
bi_private
;
autogroup_entry_t
*
age
,
*
age_prev
,
*
age_next
;
autogroup_filter_t
*
agf
;
Entry
*
e
;
int
matched_group
=
0
,
rc
=
0
;
...
...
@@ -805,7 +863,8 @@ autogroup_delete_entry( Operation *op, SlapReply *rs)
}
/* Check if the entry to be deleted is one of our groups. */
for
(
age_next
=
age
;
age_next
;
age_prev
=
age
,
age
=
age_next
)
{
for
(
age_next
=
agi
->
agi_entry
;
age_next
;
age_prev
=
age
)
{
age
=
age_next
;
ldap_pvt_thread_mutex_lock
(
&
age
->
age_mutex
);
age_next
=
age
->
age_next
;
...
...
@@ -868,13 +927,13 @@ static int
autogroup_response
(
Operation
*
op
,
SlapReply
*
rs
)
{
slap_overinst
*
on
=
(
slap_overinst
*
)
op
->
o_bd
->
bd_info
;
autogroup_info_t
*
agi
=
(
autogroup_info_t
*
)
on
->
on_bi
.
bi_private
;
autogroup_info_t
*
agi
=
(
autogroup_info_t
*
)
on
->
on_bi
.
bi_private
;
autogroup_def_t
*
agd
=
agi
->
agi_def
;
autogroup_entry_t
*
age
=
agi
->
agi_entry
;
autogroup_entry_t
*
age
;
autogroup_filter_t
*
agf
;
BerValue
new_dn
,
new_ndn
,
pdn
;
Entry
*
e
,
*
group
;
Attribute
*
a
;
Attribute
*
a
,
*
ea
;
int
is_olddn
,
is_newdn
,
is_value_refresh
,
dn_equal
;
/* Handle all cases where a refresh of the group is needed */
...
...
@@ -901,8 +960,7 @@ autogroup_response( Operation *op, SlapReply *rs )
ldap_pvt_thread_mutex_unlock
(
&
agi
->
agi_mutex
);
}
}
if
(
op
->
o_tag
==
LDAP_REQ_MODRDN
)
{
}
else
if
(
op
->
o_tag
==
LDAP_REQ_MODRDN
)
{
if
(
rs
->
sr_type
==
REP_RESULT
&&
rs
->
sr_err
==
LDAP_SUCCESS
&&
!
get_manageDSAit
(
op
))
{
Debug
(
LDAP_DEBUG_TRACE
,
"==> autogroup_response MODRDN from <%s>
\n
"
,
op
->
o_req_dn
.
bv_val
,
0
,
0
);
...
...
@@ -974,8 +1032,6 @@ autogroup_response( Operation *op, SlapReply *rs )
}
}
overlay_entry_release_ov
(
op
,
e
,
0
,
on
);
/* For each group:
1. check if the orginal entry's DN is in the group.
2. chceck if the any of the group filter's base DN is a suffix of the new DN
...
...
@@ -994,6 +1050,13 @@ autogroup_response( Operation *op, SlapReply *rs )
ldap_pvt_thread_mutex_lock
(
&
age
->
age_mutex
);
if
(
age
->
age_filter
&&
age
->
age_filter
->
agf_anlist
)
{
ea
=
attrs_find
(
e
->
e_attrs
,
age
->
age_filter
->
agf_anlist
[
0
].
an_desc
);
}
else
{
ea
=
NULL
;
}
if
(
age
->
age_modrdn_olddnmodified
)
{
/* Resquest already marked this group to be updated */
is_olddn
=
1
;
...
...
@@ -1008,6 +1071,7 @@ autogroup_response( Operation *op, SlapReply *rs )
op
->
o_tmpfree
(
new_dn
.
bv_val
,
op
->
o_tmpmemctx
);
op
->
o_tmpfree
(
new_ndn
.
bv_val
,
op
->
o_tmpmemctx
);
overlay_entry_release_ov
(
op
,
e
,
0
,
on
);
ldap_pvt_thread_mutex_unlock
(
&
age
->
age_mutex
);
ldap_pvt_thread_mutex_unlock
(
&
agi
->
agi_mutex
);
return
SLAP_CB_CONTINUE
;
...
...
@@ -1019,7 +1083,7 @@ autogroup_response( Operation *op, SlapReply *rs )
if
(
value_find_ex
(
age
->
age_def
->
agd_member_ad
,
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH
|
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH
,
a
->
a_nvals
,
&
op
->
o_req_ndn
,
op
->
o_tmpmemctx
)
==
0
)
a
->
a_nvals
,
ea
?
ea
->
a_nvals
:
&
op
->
o_req_ndn
,
op
->
o_tmpmemctx
)
==
0
)
{
is_olddn
=
1
;
}
...
...
@@ -1052,19 +1116,35 @@ autogroup_response( Operation *op, SlapReply *rs )
continue
;
}
if
(
is_olddn
==
1
&&
is_newdn
==
0
)
{
autogroup_delete_member_from_group
(
op
,
&
op
->
o_req_dn
,
&
op
->
o_req_ndn
,
age
);
if
(
ea
)
autogroup_delete_member_values_from_group
(
op
,
e
,
age
,
age
->
age_filter
->
agf_anlist
[
0
].
an_desc
);
else
autogroup_delete_member_from_group
(
op
,
&
op
->
o_req_dn
,
&
op
->
o_req_ndn
,
age
);
}
else
if
(
is_olddn
==
0
&&
is_newdn
==
1
)
{
for
(
agf
=
age
->
age_filter
;
agf
;
agf
=
agf
->
agf_next
)
{
if
(
test_filter
(
op
,
e
,
agf
->
agf_filter
)
==
LDAP_COMPARE_TRUE
)
{
autogroup_add_member_to_group
(
op
,
&
new_dn
,
&
new_ndn
,
age
);
if
(
ea
)
autogroup_add_member_values_to_group
(
op
,
e
,
age
,
age
->
age_filter
->
agf_anlist
[
0
].
an_desc
);
else
autogroup_add_member_to_group
(
op
,
&
new_dn
,
&
new_ndn
,
age
);
break
;
}
}
}
else
if
(
is_olddn
==
1
&&
is_newdn
==
1
&&
dn_equal
!=
0
)
{
autogroup_delete_member_from_group
(
op
,
&
op
->
o_req_dn
,
&
op
->
o_req_ndn
,
age
);
autogroup_add_member_to_group
(
op
,
&
new_dn
,
&
new_ndn
,
age
);
if
(
ea
)
{
/* group refresh */
autogroup_delete_member_from_group
(
op
,
NULL
,
NULL
,
age
)
;
for
(
agf
=
age
->
age_filter
;
agf
;
agf
=
agf
->
agf_next
)
{
autogroup_add_members_from_filter
(
op
,
NULL
,
age
,
agf
,
1
);
}
}
else
{
autogroup_delete_member_from_group
(
op
,
&
op
->
o_req_dn
,
&
op
->
o_req_ndn
,
age
);
autogroup_add_member_to_group
(
op
,
&
new_dn
,
&
new_ndn
,
age
);
}
}
ldap_pvt_thread_mutex_unlock
(
&
age
->
age_mutex
);
...
...
@@ -1073,6 +1153,8 @@ autogroup_response( Operation *op, SlapReply *rs )
op
->
o_tmpfree
(
new_dn
.
bv_val
,
op
->
o_tmpmemctx
);
op
->
o_tmpfree
(
new_ndn
.
bv_val
,
op
->
o_tmpmemctx
);
overlay_entry_release_ov
(
op
,
e
,
0
,
on
);
ldap_pvt_thread_mutex_unlock
(
&
agi
->
agi_mutex
);
}
}
...
...
@@ -1100,7 +1182,6 @@ autogroup_response( Operation *op, SlapReply *rs )
return
SLAP_CB_CONTINUE
;
}
/* If we modify a group's memberURL, we have to delete all of it's members,
and add them anew, because we cannot tell from which memberURL a member was added. */
for
(
;
agd
;
agd
=
agd
->
agd_next
)
{
...
...
@@ -1135,6 +1216,7 @@ autogroup_response( Operation *op, SlapReply *rs )
autogroup_add_group
(
op
,
agi
,
group_agd
,
NULL
,
&
op
->
o_req_ndn
,
1
,
1
);
overlay_entry_release_ov
(
op
,
e
,
0
,
on
);
ldap_pvt_thread_mutex_unlock
(
&
agi
->
agi_mutex
);
return
SLAP_CB_CONTINUE
;
}
...
...
@@ -1153,8 +1235,6 @@ autogroup_response( Operation *op, SlapReply *rs )
}
}
overlay_entry_release_ov
(
op
,
e
,
0
,
on
);
/* When modifing any of the attributes of an entry, we must
check if the entry is in any of our groups, and if
the modified entry maches any of the filters of that group.
...
...
@@ -1171,11 +1251,19 @@ autogroup_response( Operation *op, SlapReply *rs )
ldap_pvt_thread_mutex_lock
(
&
age
->
age_mutex
);
if
(
age
->
age_filter
&&
age
->
age_filter
->
agf_anlist
)
{
ea
=
attrs_find
(
e
->
e_attrs
,
age
->
age_filter
->
agf_anlist
[
0
].
an_desc
);
}
else
{
ea
=
NULL
;
}
if
(
overlay_entry_get_ov
(
op
,
&
age
->
age_ndn
,
NULL
,
NULL
,
0
,
&
group
,
on
)
!=
LDAP_SUCCESS
||
group
==
NULL
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"autogroup_response MODIFY cannot get entry for <%s>
\n
"
,
age
->
age_dn
.
bv_val
,
0
,
0
);
overlay_entry_release_ov
(
op
,
e
,
0
,
on
);
ldap_pvt_thread_mutex_unlock
(
&
age
->
age_mutex
);
ldap_pvt_thread_mutex_unlock
(
&
agi
->
agi_mutex
);
return
SLAP_CB_CONTINUE
;
...
...
@@ -1187,7 +1275,7 @@ autogroup_response( Operation *op, SlapReply *rs )
if
(
value_find_ex
(
age
->
age_def
->
agd_member_ad
,
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH
|
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH
,
a
->
a_nvals
,
&
op
->
o_req_ndn
,
op
->
o_tmpmemctx
)
==
0
)
a
->
a_nvals
,
ea
?
ea
->
a_nvals
:
&
op
->
o_req_ndn
,
op
->
o_tmpmemctx
)
==
0
)
{
is_olddn
=
1
;
}
...
...
@@ -1197,7 +1285,7 @@ autogroup_response( Operation *op, SlapReply *rs )
overlay_entry_release_ov
(
op
,
group
,
0
,
on
);
for
(
agf
=
age
->
age_filter
;
agf
;
agf
=
agf
->
agf_next
)
{
if
(
!
agf
->
agf_anlist
&&
dnIsSuffix
(
&
op
->
o_req_ndn
,
&
agf
->
agf_ndn
)
)
{
if
(
dnIsSuffix
(
&
op
->
o_req_ndn
,
&
agf
->
agf_ndn
)
)
{
if
(
test_filter
(
op
,
e
,
agf
->
agf_filter
)
==
LDAP_COMPARE_TRUE
)
{
is_newdn
=
1
;
break
;
...
...
@@ -1206,15 +1294,23 @@ autogroup_response( Operation *op, SlapReply *rs )
}
if
(
is_olddn
==
1
&&
is_newdn
==
0
)
{
autogroup_delete_member_from_group
(
op
,
&
op
->
o_req_dn
,
&
op
->
o_req_ndn
,
age
);
if
(
ea
)
autogroup_delete_member_values_from_group
(
op
,
e
,
age
,
age
->
age_filter
->
agf_anlist
[
0
].
an_desc
);
else
autogroup_delete_member_from_group
(
op
,
&
op
->
o_req_dn
,
&
op
->
o_req_ndn
,
age
);
}
else
if
(
is_olddn
==
0
&&
is_newdn
==
1
)
{
autogroup_add_member_to_group
(
op
,
&
op
->
o_req_dn
,
&
op
->
o_req_ndn
,
age
);
if
(
ea
)
autogroup_add_member_values_to_group
(
op
,
e
,
age
,
age
->
age_filter
->
agf_anlist
[
0
].
an_desc
);
else
autogroup_add_member_to_group
(
op
,
&
op
->
o_req_dn
,
&
op
->
o_req_ndn
,
age
);
}
ldap_pvt_thread_mutex_unlock
(
&
age
->
age_mutex
);
}
overlay_entry_release_ov
(
op
,
e
,
0
,
on
);
ldap_pvt_thread_mutex_unlock
(
&
agi
->
agi_mutex
);
}
}
...
...
@@ -1222,6 +1318,34 @@ autogroup_response( Operation *op, SlapReply *rs )
return
SLAP_CB_CONTINUE
;
}
/*
** Detect if filter contains a memberOf check for dn
*/
static
int
autogroup_memberOf_filter
(
Filter
*
f
,
BerValue
*
dn
,
AttributeDescription
*
memberof_ad
)
{
int
result
=
0
;
if
(
f
==
NULL
)
return
0
;
switch
(
f
->
f_choice
&
SLAPD_FILTER_MASK
)
{
case
LDAP_FILTER_AND
:
case
LDAP_FILTER_OR
:
case
LDAP_FILTER_NOT
:
for
(
f
=
f
->
f_un
.
f_un_complex
;
f
&&
!
result
;
f
=
f
->
f_next
)
{
result
=
result
||
autogroup_memberOf_filter
(
f
,
dn
,
memberof_ad
);
}
break
;
case
LDAP_FILTER_EQUALITY
:
result
=
(
f
->
f_ava
->
aa_desc
==
memberof_ad
&&
ber_bvcmp
(
&
f
->
f_ava
->
aa_value
,
dn
)
==
0
);
break
;
default:
break
;
}
return
result
;
}
/*
** When modifing a group, we must deny any modifications to the member attribute,
** because the group would be inconsistent.
...
...
@@ -1232,7 +1356,7 @@ autogroup_modify_entry( Operation *op, SlapReply *rs)
slap_overinst
*
on
=
(
slap_overinst
*
)
op
->
o_bd
->
bd_info
;
autogroup_info_t
*
agi
=
(
autogroup_info_t
*
)
on
->
on_bi
.
bi_private
;
autogroup_def_t
*
agd
=
agi
->
agi_def
;
autogroup_entry_t
*
age
=
agi
->
agi_entry
;
autogroup_entry_t
*
age
;
Entry
*
e
;
Attribute
*
a
;
...
...
@@ -1250,8 +1374,8 @@ autogroup_modify_entry( Operation *op, SlapReply *rs)
return
SLAP_CB_CONTINUE
;
}
/* Must refresh groups if a matching member value is modified */
for
(
;
age
;
age
=
age
->
age_next
)
{
/* Must refresh groups if a matching member value is modified
OR filter contains memberOf=DN
*/
for
(
age
=
agi
->
agi_entry
;
age
;
age
=
age
->
age_next
)
{
autogroup_filter_t
*
agf
;
for
(
agf
=
age
->
age_filter
;
agf
;
agf
=
agf
->
agf_next
)
{
if
(
agf
->
agf_anlist
)
{
...
...
@@ -1267,6 +1391,10 @@ autogroup_modify_entry( Operation *op, SlapReply *rs)
}
}
}
if
(
autogroup_memberOf_filter
(
agf
->
agf_filter
,
&
op
->
o_req_ndn
,
agi
->
agi_memberof_ad
)
)
{
age
->
age_mustrefresh
=
1
;
}
}
}
...
...
@@ -1327,8 +1455,8 @@ static int
autogroup_modrdn_entry
(
Operation
*
op
,
SlapReply
*
rs
)
{
slap_overinst
*
on
=
(
slap_overinst
*
)
op
->
o_bd
->
bd_info
;
autogroup_info_t
*
agi
=
(
autogroup_info_t
*
)
on
->
on_bi
.
bi_private
;
autogroup_entry_t
*
age
=
agi
->
agi_entry
;
autogroup_info_t
*
agi
=
(
autogroup_info_t
*
)
on
->
on_bi
.
bi_private
;
autogroup_entry_t
*
age
;
Entry
*
e
;
if
(
get_manageDSAit
(
op
)
)
{
...
...
@@ -1346,7 +1474,7 @@ autogroup_modrdn_entry( Operation *op, SlapReply *rs)
}
/* Must check if a dn is modified */
for
(
;
age
;
age
=
age
->
age_next
)
{
for
(
age
=
agi
->
agi_entry
;
age
;
age
=
age
->
age_next
)
{
autogroup_filter_t
*
agf
;
for
(
agf
=
age
->
age_filter
;
agf
;
agf
=
agf
->
agf_next
)
{
if
(
agf
->
agf_anlist
)
{
...
...
@@ -1396,6 +1524,7 @@ autogroup_build_def_filter( autogroup_def_t *agd, Operation *op )
enum
{
AG_ATTRSET
=
1
,
AG_MEMBER_OF_AD
,
AG_LAST
};
...
...
@@ -1410,6 +1539,14 @@ static ConfigTable agcfg[] = {
"SYNTAX OMsDirectoryString "
"X-ORDERED 'VALUES' )"
,
NULL
,
NULL
},
{
"autogroup-memberof-ad"
,
"memberOf attribute"
,
2
,
2
,
0
,
ARG_MAGIC
|
AG_MEMBER_OF_AD
,
ag_cfgen
,
"( OLcfgCtAt:2.2 NAME 'olcAGmemberOfAd' "
"DESC 'memberOf attribute' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )"
,
NULL
,
NULL
},
{
NULL
,
NULL
,
0
,
0
,
0
,
ARG_IGNORED
}
};
...
...
@@ -1418,7 +1555,11 @@ static ConfigOCs agocs[] = {
"NAME 'olcAutomaticGroups' "
"DESC 'Automatic groups configuration' "
"SUP olcOverlayConfig "
"MAY olcAGattrSet )"
,
"MAY ( "
"olcAGattrSet "
"$ olcAGmemberOfAd "
")"
")"
,
Cft_Overlay
,
agcfg
,
NULL
,
NULL
},
{
NULL
,
0
,
NULL
}
};
...
...
@@ -1449,28 +1590,39 @@ ag_cfgen( ConfigArgs *c )
if
(
c
->
op
==
SLAP_CONFIG_EMIT
)
{
ldap_pvt_thread_mutex_lock
(
&
agi
->
agi_mutex
);
for
(
i
=
0
;
agd
;
i
++
,
agd
=
agd
->
agd_next
)
{
struct
berval
bv
;
char
*
ptr
=
c
->
cr_msg
;
assert
(
agd
->
agd_oc
!=
NULL
);
assert
(
agd
->
agd_member_url_ad
!=
NULL
);
assert
(
agd
->
agd_member_ad
!=
NULL
);
ptr
+=
snprintf
(
c
->
cr_msg
,
sizeof
(
c
->
cr_msg
),
SLAP_X_ORDERED_FMT
"%s %s %s"
,
i
,
agd
->
agd_oc
->
soc_cname
.
bv_val
,
agd
->
agd_member_url_ad
->
ad_cname
.
bv_val
,
agd
->
agd_member_ad
->
ad_cname
.
bv_val
);
switch
(
c
->
type
){
case
AG_ATTRSET
:
for
(
i
=
0
;
agd
;
i
++
,
agd
=
agd
->
agd_next
)
{
struct
berval
bv
;
char
*
ptr
=
c
->
cr_msg
;
assert
(
agd
->
agd_oc
!=
NULL
);
assert
(
agd
->
agd_member_url_ad
!=
NULL
);
assert
(
agd
->
agd_member_ad
!=
NULL
);
ptr
+=
snprintf
(
c
->
cr_msg
,
sizeof
(
c
->
cr_msg
),
SLAP_X_ORDERED_FMT
"%s %s %s"
,
i
,
agd
->
agd_oc
->
soc_cname
.
bv_val
,
agd
->
agd_member_url_ad
->
ad_cname
.
bv_val
,
agd
->
agd_member_ad
->
ad_cname
.
bv_val
);
bv
.
bv_val
=
c
->
cr_msg
;
bv
.
bv_len
=
ptr
-
bv
.
bv_val
;
value_add_one
(
&
c
->
rvalue_vals
,
&
bv
);
}
break
;
bv
.
bv_val
=
c
->
cr_msg
;
bv
.
bv_len
=
ptr
-
bv
.
bv_val
;
value_add_one
(
&
c
->
rvalue_vals
,
&
bv
);
case
AG_MEMBER_OF_AD
:
if
(
agi
->
agi_memberof_ad
!=
NULL
){
value_add_one
(
&
c
->
rvalue_vals
,
&
agi
->
agi_memberof_ad
->
ad_cname
);
}
break
;
}
ldap_pvt_thread_mutex_unlock
(
&
agi
->
agi_mutex
);
default:
assert
(
0
);
return
1
;
}
return
rc
;
...
...
@@ -1481,8 +1633,6 @@ ag_cfgen( ConfigArgs *c )
autogroup_filter_t
*
agf
=
age
->
age_filter
,
*
agf_next
;
ldap_pvt_thread_mutex_lock
(
&
agi
->
agi_mutex
);
for
(
agd_next
=
agd
;
agd_next
;
agd
=
agd_next
)
{
agd_next
=
agd
->
agd_next
;
...
...
@@ -1510,9 +1660,6 @@ ag_cfgen( ConfigArgs *c )
ch_free
(
age
);
}
ldap_pvt_thread_mutex_unlock
(
&
agi
->
agi_mutex
);
ldap_pvt_thread_mutex_destroy
(
&
agi
->
agi_mutex
);
ch_free
(
agi
);
on
->
on_bi
.
bi_private
=
NULL
;
...
...
@@ -1522,8 +1669,6 @@ ag_cfgen( ConfigArgs *c )
autogroup_filter_t
*
agf
,
*
agf_next
;
ldap_pvt_thread_mutex_lock
(
&
agi
->
agi_mutex
);
for
(
i
=
0
,
agdp
=
&
agi
->
agi_def
;
i
<
c
->
valx
;
i
++
)
{
...
...
@@ -1568,7 +1713,6 @@ ag_cfgen( ConfigArgs *c )
ch_free
(
agd
);
agd
=
agi
->
agi_def
;
ldap_pvt_thread_mutex_unlock
(
&
agi
->
agi_mutex
);
}
...
...
@@ -1630,8 +1774,6 @@ ag_cfgen( ConfigArgs *c )
return
1
;
}
ldap_pvt_thread_mutex_lock
(
&
agi
->
agi_mutex
);
for
(
agdp
=
&
agi
->
agi_def
;
*
agdp
;
agdp
=
&
(
*
agdp
)
->
agd_next
)
{
/* The same URL attribute / member attribute pair
* cannot be repeated */
...
...
@@ -1661,7 +1803,6 @@ ag_cfgen( ConfigArgs *c )
Debug
(
LDAP_DEBUG_ANY
,
"%s: %s.
\n
"
,