|
|
a2f18f |
From 9ba3240a177c156e365f22c721432321bb0a679e Mon Sep 17 00:00:00 2001
|
|
|
b161c9 |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
b161c9 |
Date: Tue, 4 Aug 2015 12:19:31 -0400
|
|
|
a2f18f |
Subject: [PATCH 39/39] Ticket 47931 - memberOf & retrocl deadlocks
|
|
|
b161c9 |
|
|
|
b161c9 |
Bug Description: When concurrently updating multiple backends the
|
|
|
b161c9 |
memberOf and retrocl plugins can deadlock on each
|
|
|
b161c9 |
other. This is caused by the required retrocl lock,
|
|
|
b161c9 |
and the db lock on the changenumber index in the
|
|
|
b161c9 |
retrocl db.
|
|
|
b161c9 |
|
|
|
b161c9 |
Fix Description: Added scoping to the retrocl that allows subtrees/suffixes
|
|
|
b161c9 |
to be included or excluded. Also moved the existing
|
|
|
b161c9 |
memberOf scoping outside of its global lock.
|
|
|
b161c9 |
|
|
|
b161c9 |
Also improved the memberOf config copying to be consistent
|
|
|
b161c9 |
and more efficient. Improved the memberOf scoping attributes
|
|
|
b161c9 |
to be multivalued. And, properly valdiated new config
|
|
|
b161c9 |
settings in the preop valdiation function, instead of the
|
|
|
b161c9 |
"apply config" function.
|
|
|
b161c9 |
|
|
|
b161c9 |
https://fedorahosted.org/389/ticket/47931
|
|
|
b161c9 |
|
|
|
b161c9 |
Valgrind: passed
|
|
|
b161c9 |
|
|
|
b161c9 |
Reviewed by: nhosoi(Thanks!)
|
|
|
b161c9 |
|
|
|
b161c9 |
(cherry picked from commit fd959ac864d6d86d24928bc2c6f097d1a6031ecd)
|
|
|
b161c9 |
(cherry picked from commit d8108476d3bedbcc03f6c61bfb3d50e921faaf42)
|
|
|
b161c9 |
---
|
|
|
a2f18f |
ldap/servers/plugins/memberof/memberof.c | 217 +++++++++++++--------
|
|
|
b161c9 |
ldap/servers/plugins/memberof/memberof.h | 8 +-
|
|
|
a2f18f |
ldap/servers/plugins/memberof/memberof_config.c | 249 +++++++++++++++++-------
|
|
|
b161c9 |
ldap/servers/plugins/retrocl/retrocl.c | 183 +++++++++++++++--
|
|
|
b161c9 |
ldap/servers/plugins/retrocl/retrocl.h | 4 +
|
|
|
b161c9 |
ldap/servers/plugins/retrocl/retrocl_po.c | 41 +++-
|
|
|
a2f18f |
6 files changed, 516 insertions(+), 186 deletions(-)
|
|
|
b161c9 |
|
|
|
b161c9 |
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
|
|
|
a2f18f |
index da52bc8..9b577b9 100644
|
|
|
b161c9 |
--- a/ldap/servers/plugins/memberof/memberof.c
|
|
|
b161c9 |
+++ b/ldap/servers/plugins/memberof/memberof.c
|
|
|
a2f18f |
@@ -116,7 +116,7 @@ static int memberof_compare(MemberOfConfig *config, const void *a, const void *b
|
|
|
b161c9 |
static int memberof_qsort_compare(const void *a, const void *b);
|
|
|
b161c9 |
static void memberof_load_array(Slapi_Value **array, Slapi_Attr *attr);
|
|
|
b161c9 |
static int memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, Slapi_DN *sdn);
|
|
|
b161c9 |
-static int memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn,
|
|
|
b161c9 |
+static int memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, MemberOfConfig *config,
|
|
|
b161c9 |
char **types, plugin_search_entry_callback callback, void *callback_data);
|
|
|
b161c9 |
static int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn,
|
|
|
b161c9 |
Slapi_Value *memberdn);
|
|
|
a2f18f |
@@ -144,7 +144,7 @@ static const char *fetch_attr(Slapi_Entry *e, const char *attrname,
|
|
|
b161c9 |
static void memberof_fixup_task_thread(void *arg);
|
|
|
b161c9 |
static int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str);
|
|
|
b161c9 |
static int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data);
|
|
|
b161c9 |
-
|
|
|
b161c9 |
+static int memberof_entry_in_scope(MemberOfConfig *config, Slapi_DN *sdn);
|
|
|
b161c9 |
|
|
|
b161c9 |
/*** implementation ***/
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -489,7 +489,8 @@ memberof_get_plugin_area()
|
|
|
b161c9 |
int memberof_postop_del(Slapi_PBlock *pb)
|
|
|
b161c9 |
{
|
|
|
b161c9 |
int ret = SLAPI_PLUGIN_SUCCESS;
|
|
|
b161c9 |
- MemberOfConfig configCopy = {0, 0, 0, 0};
|
|
|
b161c9 |
+ MemberOfConfig *mainConfig = NULL;
|
|
|
b161c9 |
+ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
b161c9 |
Slapi_DN *sdn;
|
|
|
b161c9 |
void *caller_id = NULL;
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -509,12 +510,13 @@ int memberof_postop_del(Slapi_PBlock *pb)
|
|
|
b161c9 |
struct slapi_entry *e = NULL;
|
|
|
b161c9 |
|
|
|
b161c9 |
slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &e );
|
|
|
b161c9 |
-
|
|
|
b161c9 |
- /* We need to get the config lock first. Trying to get the
|
|
|
b161c9 |
- * config lock after we already hold the op lock can cause
|
|
|
b161c9 |
- * a deadlock. */
|
|
|
b161c9 |
memberof_rlock_config();
|
|
|
b161c9 |
- /* copy config so it doesn't change out from under us */
|
|
|
b161c9 |
+ mainConfig = memberof_get_config();
|
|
|
b161c9 |
+ if(!memberof_entry_in_scope(mainConfig, slapi_entry_get_sdn(e))){
|
|
|
b161c9 |
+ /* The entry is not in scope, bail...*/
|
|
|
b161c9 |
+ memberof_unlock_config();
|
|
|
b161c9 |
+ goto bail;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
memberof_copy_config(&configCopy, memberof_get_config());
|
|
|
b161c9 |
memberof_unlock_config();
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -529,7 +531,6 @@ int memberof_postop_del(Slapi_PBlock *pb)
|
|
|
b161c9 |
"memberof_postop_del: error deleting dn (%s) from group. Error (%d)\n",
|
|
|
b161c9 |
slapi_sdn_get_dn(sdn),ret);
|
|
|
b161c9 |
memberof_unlock();
|
|
|
b161c9 |
- memberof_free_config(&configCopy);
|
|
|
b161c9 |
goto bail;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -554,10 +555,10 @@ int memberof_postop_del(Slapi_PBlock *pb)
|
|
|
b161c9 |
}
|
|
|
b161c9 |
}
|
|
|
b161c9 |
memberof_unlock();
|
|
|
b161c9 |
+bail:
|
|
|
b161c9 |
memberof_free_config(&configCopy);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
-bail:
|
|
|
b161c9 |
if(ret){
|
|
|
b161c9 |
slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ret;;
|
|
|
b161c9 |
ret = SLAPI_PLUGIN_FAILURE;
|
|
|
a2f18f |
@@ -591,7 +592,7 @@ memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, Slapi_DN *
|
|
|
b161c9 |
|
|
|
b161c9 |
groupattrs[0] = config->groupattrs[i];
|
|
|
b161c9 |
|
|
|
b161c9 |
- rc = memberof_call_foreach_dn(pb, sdn, groupattrs,
|
|
|
b161c9 |
+ rc = memberof_call_foreach_dn(pb, sdn, config, groupattrs,
|
|
|
b161c9 |
memberof_del_dn_type_callback, &data);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -641,6 +642,20 @@ memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data)
|
|
|
b161c9 |
return rc;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
+/* Check if the the entry include scope is a child of the sdn */
|
|
|
b161c9 |
+static Slapi_DN*
|
|
|
b161c9 |
+memberof_scope_is_child_of_dn(MemberOfConfig *config, Slapi_DN *sdn)
|
|
|
b161c9 |
+{
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ while(config->entryScopes && config->entryScopes[i]){
|
|
|
b161c9 |
+ if(slapi_sdn_issuffix(config->entryScopes[i], sdn)){
|
|
|
b161c9 |
+ return config->entryScopes[i];
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ i++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ return NULL;
|
|
|
b161c9 |
+}
|
|
|
b161c9 |
/*
|
|
|
b161c9 |
* Does a callback search of "type=dn" under the db suffix that "dn" is in,
|
|
|
b161c9 |
* unless all_backends is set, then we look at all the backends. If "dn"
|
|
|
a2f18f |
@@ -649,7 +664,7 @@ memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data)
|
|
|
b161c9 |
*/
|
|
|
b161c9 |
int
|
|
|
b161c9 |
memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn,
|
|
|
b161c9 |
- char **types, plugin_search_entry_callback callback, void *callback_data)
|
|
|
b161c9 |
+ MemberOfConfig *config, char **types, plugin_search_entry_callback callback, void *callback_data)
|
|
|
b161c9 |
{
|
|
|
b161c9 |
Slapi_PBlock *search_pb = NULL;
|
|
|
b161c9 |
Slapi_DN *base_sdn = NULL;
|
|
|
a2f18f |
@@ -657,9 +672,7 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn,
|
|
|
b161c9 |
char *escaped_filter_val;
|
|
|
b161c9 |
char *filter_str = NULL;
|
|
|
b161c9 |
char *cookie = NULL;
|
|
|
b161c9 |
- int all_backends = memberof_config_get_all_backends();
|
|
|
b161c9 |
- Slapi_DN *entry_scope = memberof_config_get_entry_scope();
|
|
|
a2f18f |
- Slapi_DN *entry_scope_exclude_subtree = memberof_config_get_entry_scope_exclude_subtree();
|
|
|
b161c9 |
+ int all_backends = config->allBackends;
|
|
|
b161c9 |
int types_name_len = 0;
|
|
|
b161c9 |
int num_types = 0;
|
|
|
b161c9 |
int dn_len = slapi_sdn_get_ndn_len(sdn);
|
|
|
a2f18f |
@@ -667,11 +680,7 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn,
|
|
|
b161c9 |
int rc = 0;
|
|
|
b161c9 |
int i = 0;
|
|
|
b161c9 |
|
|
|
b161c9 |
- if (entry_scope && !slapi_sdn_issuffix(sdn, entry_scope)) {
|
|
|
b161c9 |
- return (rc);
|
|
|
b161c9 |
- }
|
|
|
b161c9 |
-
|
|
|
a2f18f |
- if (entry_scope_exclude_subtree && slapi_sdn_issuffix(sdn, entry_scope_exclude_subtree)) {
|
|
|
b161c9 |
+ if (!memberof_entry_in_scope(config, sdn)) {
|
|
|
b161c9 |
return (rc);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -728,6 +737,8 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn,
|
|
|
b161c9 |
search_pb = slapi_pblock_new();
|
|
|
b161c9 |
be = slapi_get_first_backend(&cookie);
|
|
|
b161c9 |
while(be){
|
|
|
b161c9 |
+ Slapi_DN *scope_sdn = NULL;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
if(!all_backends){
|
|
|
b161c9 |
be = slapi_be_select(sdn);
|
|
|
b161c9 |
if(be == NULL){
|
|
|
a2f18f |
@@ -743,13 +754,14 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn,
|
|
|
b161c9 |
continue;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
}
|
|
|
b161c9 |
- if (entry_scope) {
|
|
|
b161c9 |
- if (slapi_sdn_issuffix(base_sdn, entry_scope)) {
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ if (config->entryScopes || config->entryScopeExcludeSubtrees) {
|
|
|
b161c9 |
+ if (memberof_entry_in_scope(config, base_sdn)) {
|
|
|
b161c9 |
/* do nothing, entry scope is spanning
|
|
|
b161c9 |
* multiple suffixes, start at suffix */
|
|
|
b161c9 |
- } else if (slapi_sdn_issuffix(entry_scope, base_sdn)) {
|
|
|
b161c9 |
+ } else if ((scope_sdn = memberof_scope_is_child_of_dn(config, base_sdn))) {
|
|
|
b161c9 |
/* scope is below suffix, set search base */
|
|
|
b161c9 |
- base_sdn = entry_scope;
|
|
|
b161c9 |
+ base_sdn = scope_sdn;
|
|
|
b161c9 |
} else if(!all_backends){
|
|
|
b161c9 |
break;
|
|
|
b161c9 |
} else {
|
|
|
a2f18f |
@@ -767,7 +779,6 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn,
|
|
|
b161c9 |
break;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
-
|
|
|
b161c9 |
if(!all_backends){
|
|
|
b161c9 |
break;
|
|
|
b161c9 |
}
|
|
|
a2f18f |
@@ -792,10 +803,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
|
|
|
b161c9 |
{
|
|
|
b161c9 |
int ret = SLAPI_PLUGIN_SUCCESS;
|
|
|
b161c9 |
void *caller_id = NULL;
|
|
|
b161c9 |
- Slapi_DN *entry_scope = NULL;
|
|
|
b161c9 |
- Slapi_DN *entry_scope_exclude_subtree = memberof_config_get_entry_scope_exclude_subtree();
|
|
|
b161c9 |
|
|
|
b161c9 |
- entry_scope = memberof_config_get_entry_scope();
|
|
|
b161c9 |
slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
"--> memberof_postop_modrdn\n" );
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -810,7 +818,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
|
|
|
b161c9 |
if(memberof_oktodo(pb))
|
|
|
b161c9 |
{
|
|
|
b161c9 |
MemberOfConfig *mainConfig = 0;
|
|
|
b161c9 |
- MemberOfConfig configCopy = {0, 0, 0, 0};
|
|
|
b161c9 |
+ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
b161c9 |
struct slapi_entry *pre_e = NULL;
|
|
|
b161c9 |
struct slapi_entry *post_e = NULL;
|
|
|
b161c9 |
Slapi_DN *pre_sdn = 0;
|
|
|
a2f18f |
@@ -818,7 +826,6 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
|
|
|
b161c9 |
|
|
|
b161c9 |
slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &pre_e );
|
|
|
b161c9 |
slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &post_e );
|
|
|
b161c9 |
-
|
|
|
b161c9 |
if(pre_e && post_e)
|
|
|
b161c9 |
{
|
|
|
b161c9 |
pre_sdn = slapi_entry_get_sdn(pre_e);
|
|
|
a2f18f |
@@ -831,11 +838,19 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
|
|
|
b161c9 |
memberof_copy_config(&configCopy, mainConfig);
|
|
|
b161c9 |
memberof_unlock_config();
|
|
|
b161c9 |
|
|
|
b161c9 |
+ /* Need to check both the pre/post entries */
|
|
|
b161c9 |
+ if((pre_sdn && !memberof_entry_in_scope(&configCopy, pre_sdn)) &&
|
|
|
b161c9 |
+ (post_sdn && !memberof_entry_in_scope(&configCopy, post_sdn)))
|
|
|
b161c9 |
+ {
|
|
|
b161c9 |
+ /* The entry is not in scope */
|
|
|
b161c9 |
+ goto bail;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+
|
|
|
b161c9 |
memberof_lock();
|
|
|
b161c9 |
|
|
|
b161c9 |
/* update any downstream members */
|
|
|
b161c9 |
if(pre_sdn && post_sdn && configCopy.group_filter &&
|
|
|
b161c9 |
- 0 == slapi_filter_test_simple(post_e, configCopy.group_filter))
|
|
|
b161c9 |
+ 0 == slapi_filter_test_simple(post_e, configCopy.group_filter))
|
|
|
b161c9 |
{
|
|
|
b161c9 |
int i = 0;
|
|
|
b161c9 |
Slapi_Attr *attr = 0;
|
|
|
a2f18f |
@@ -847,7 +862,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
|
|
|
b161c9 |
if(0 == slapi_entry_attr_find(post_e, configCopy.groupattrs[i], &attr))
|
|
|
b161c9 |
{
|
|
|
b161c9 |
if((ret = memberof_moddn_attr_list(pb, &configCopy, pre_sdn,
|
|
|
b161c9 |
- post_sdn, attr) != 0))
|
|
|
b161c9 |
+ post_sdn, attr) != 0))
|
|
|
b161c9 |
{
|
|
|
b161c9 |
slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
"memberof_postop_modrdn - update failed for (%s), error (%d)\n",
|
|
|
a2f18f |
@@ -862,49 +877,49 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
|
|
|
b161c9 |
* of other group entries. We need to update any member
|
|
|
b161c9 |
* attributes to refer to the new name. */
|
|
|
b161c9 |
if (ret == LDAP_SUCCESS && pre_sdn && post_sdn) {
|
|
|
b161c9 |
- if ((entry_scope && !slapi_sdn_issuffix(post_sdn, entry_scope)) ||
|
|
|
b161c9 |
- (entry_scope_exclude_subtree && slapi_sdn_issuffix(post_sdn, entry_scope_exclude_subtree))) {
|
|
|
b161c9 |
+ if (!memberof_entry_in_scope(&configCopy, post_sdn)){
|
|
|
b161c9 |
if((ret = memberof_del_dn_from_groups(pb, &configCopy, pre_sdn))){
|
|
|
b161c9 |
slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
"memberof_postop_modrdn - delete dn failed for (%s), error (%d)\n",
|
|
|
b161c9 |
slapi_sdn_get_dn(pre_sdn), ret);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
if(ret == LDAP_SUCCESS && pre_e && configCopy.group_filter &&
|
|
|
b161c9 |
- 0 == slapi_filter_test_simple(pre_e, configCopy.group_filter)) {
|
|
|
b161c9 |
+ 0 == slapi_filter_test_simple(pre_e, configCopy.group_filter))
|
|
|
b161c9 |
+ {
|
|
|
b161c9 |
/* is the entry of interest as a group? */
|
|
|
b161c9 |
- int i = 0;
|
|
|
b161c9 |
- Slapi_Attr *attr = 0;
|
|
|
b161c9 |
-
|
|
|
b161c9 |
- /* Loop through to find each grouping attribute separately. */
|
|
|
b161c9 |
- for (i = 0; configCopy.groupattrs[i] && ret == LDAP_SUCCESS; i++) {
|
|
|
b161c9 |
- if (0 == slapi_entry_attr_find(pre_e, configCopy.groupattrs[i], &attr)) {
|
|
|
b161c9 |
- if((ret = memberof_del_attr_list(pb, &configCopy, pre_sdn, attr))){
|
|
|
b161c9 |
- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
- "memberof_postop_modrdn: error deleting attr list - dn (%s). Error (%d)\n",
|
|
|
b161c9 |
- slapi_sdn_get_dn(pre_sdn),ret);
|
|
|
b161c9 |
- }
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
+ Slapi_Attr *attr = 0;
|
|
|
b161c9 |
|
|
|
b161c9 |
+ /* Loop through to find each grouping attribute separately. */
|
|
|
b161c9 |
+ for (i = 0; configCopy.groupattrs[i] && ret == LDAP_SUCCESS; i++) {
|
|
|
b161c9 |
+ if (0 == slapi_entry_attr_find(pre_e, configCopy.groupattrs[i], &attr)) {
|
|
|
b161c9 |
+ if((ret = memberof_del_attr_list(pb, &configCopy, pre_sdn, attr))){
|
|
|
b161c9 |
+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
+ "memberof_postop_modrdn: error deleting attr list - dn (%s). Error (%d)\n",
|
|
|
b161c9 |
+ slapi_sdn_get_dn(pre_sdn),ret);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
+
|
|
|
b161c9 |
}
|
|
|
b161c9 |
- }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
if(ret == LDAP_SUCCESS) {
|
|
|
b161c9 |
- memberof_del_dn_data del_data = {0, configCopy.memberof_attr};
|
|
|
b161c9 |
- if((ret = memberof_del_dn_type_callback(post_e, &del_data))){
|
|
|
b161c9 |
- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
- "memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n",
|
|
|
b161c9 |
- slapi_entry_get_dn(post_e), ret);
|
|
|
b161c9 |
- }
|
|
|
b161c9 |
+ memberof_del_dn_data del_data = {0, configCopy.memberof_attr};
|
|
|
b161c9 |
+ if((ret = memberof_del_dn_type_callback(post_e, &del_data))){
|
|
|
b161c9 |
+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
+ "memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n",
|
|
|
b161c9 |
+ slapi_entry_get_dn(post_e), ret);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
} else {
|
|
|
b161c9 |
if((ret = memberof_replace_dn_from_groups(pb, &configCopy, pre_sdn, post_sdn))){
|
|
|
b161c9 |
slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
- "memberof_postop_modrdn - replace dne failed for (%s), error (%d)\n",
|
|
|
b161c9 |
+ "memberof_postop_modrdn - replace dn failed for (%s), error (%d)\n",
|
|
|
b161c9 |
slapi_sdn_get_dn(pre_sdn), ret);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
}
|
|
|
b161c9 |
}
|
|
|
b161c9 |
-
|
|
|
b161c9 |
memberof_unlock();
|
|
|
b161c9 |
+bail:
|
|
|
b161c9 |
memberof_free_config(&configCopy);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -946,7 +961,7 @@ memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config,
|
|
|
b161c9 |
|
|
|
b161c9 |
groupattrs[0] = config->groupattrs[i];
|
|
|
b161c9 |
|
|
|
b161c9 |
- if((ret = memberof_call_foreach_dn(pb, pre_sdn, groupattrs,
|
|
|
b161c9 |
+ if((ret = memberof_call_foreach_dn(pb, pre_sdn, config, groupattrs,
|
|
|
b161c9 |
memberof_replace_dn_type_callback,
|
|
|
b161c9 |
&data)))
|
|
|
b161c9 |
{
|
|
|
a2f18f |
@@ -1064,12 +1079,11 @@ int memberof_postop_modify(Slapi_PBlock *pb)
|
|
|
b161c9 |
goto done;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
-
|
|
|
b161c9 |
- if(memberof_oktodo(pb) && (sdn = memberof_getsdn(pb)))
|
|
|
b161c9 |
+ if(memberof_oktodo(pb))
|
|
|
b161c9 |
{
|
|
|
b161c9 |
int config_copied = 0;
|
|
|
b161c9 |
MemberOfConfig *mainConfig = 0;
|
|
|
b161c9 |
- MemberOfConfig configCopy = {0, 0, 0, 0};
|
|
|
b161c9 |
+ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
b161c9 |
|
|
|
b161c9 |
/* get the mod set */
|
|
|
b161c9 |
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods;;
|
|
|
a2f18f |
@@ -1088,19 +1102,22 @@ int memberof_postop_modify(Slapi_PBlock *pb)
|
|
|
b161c9 |
* only copy the config the first time it's needed so
|
|
|
b161c9 |
* it remains the same for all mods in the operation,
|
|
|
b161c9 |
* despite any config changes that may be made. */
|
|
|
b161c9 |
- if (!config_copied)
|
|
|
b161c9 |
- {
|
|
|
b161c9 |
+ if (!config_copied){
|
|
|
b161c9 |
memberof_rlock_config();
|
|
|
b161c9 |
mainConfig = memberof_get_config();
|
|
|
b161c9 |
|
|
|
b161c9 |
if (memberof_is_grouping_attr(type, mainConfig))
|
|
|
b161c9 |
{
|
|
|
b161c9 |
interested = 1;
|
|
|
b161c9 |
+ if (!memberof_entry_in_scope(mainConfig, sdn)){
|
|
|
b161c9 |
+ /* Entry is not in scope */
|
|
|
b161c9 |
+ memberof_unlock_config();
|
|
|
b161c9 |
+ goto bail;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
/* copy config so it doesn't change out from under us */
|
|
|
b161c9 |
memberof_copy_config(&configCopy, mainConfig);
|
|
|
b161c9 |
config_copied = 1;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
-
|
|
|
b161c9 |
memberof_unlock_config();
|
|
|
b161c9 |
} else {
|
|
|
b161c9 |
if (memberof_is_grouping_attr(type, &configCopy))
|
|
|
a2f18f |
@@ -1197,8 +1214,7 @@ int memberof_postop_modify(Slapi_PBlock *pb)
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
bail:
|
|
|
b161c9 |
- if (config_copied)
|
|
|
b161c9 |
- {
|
|
|
b161c9 |
+ if (config_copied){
|
|
|
b161c9 |
memberof_free_config(&configCopy);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -1244,22 +1260,25 @@ int memberof_postop_add(Slapi_PBlock *pb)
|
|
|
b161c9 |
|
|
|
b161c9 |
if(memberof_oktodo(pb) && (sdn = memberof_getsdn(pb)))
|
|
|
b161c9 |
{
|
|
|
b161c9 |
- MemberOfConfig *mainConfig = 0;
|
|
|
b161c9 |
- MemberOfConfig configCopy = {0, 0, 0, 0};
|
|
|
b161c9 |
struct slapi_entry *e = NULL;
|
|
|
b161c9 |
-
|
|
|
b161c9 |
+ MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
b161c9 |
+ MemberOfConfig *mainConfig;
|
|
|
b161c9 |
slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &e );
|
|
|
b161c9 |
-
|
|
|
b161c9 |
|
|
|
b161c9 |
/* is the entry of interest? */
|
|
|
b161c9 |
memberof_rlock_config();
|
|
|
b161c9 |
mainConfig = memberof_get_config();
|
|
|
b161c9 |
if(e && mainConfig && mainConfig->group_filter &&
|
|
|
b161c9 |
0 == slapi_filter_test_simple(e, mainConfig->group_filter))
|
|
|
b161c9 |
+
|
|
|
b161c9 |
{
|
|
|
b161c9 |
interested = 1;
|
|
|
b161c9 |
- /* copy config so it doesn't change out from under us */
|
|
|
b161c9 |
- memberof_copy_config(&configCopy, mainConfig);
|
|
|
b161c9 |
+ if(!memberof_entry_in_scope(mainConfig, slapi_entry_get_sdn(e))){
|
|
|
b161c9 |
+ /* Entry is not in scope */
|
|
|
b161c9 |
+ memberof_unlock_config();
|
|
|
b161c9 |
+ goto bail;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ memberof_copy_config(&configCopy, memberof_get_config());
|
|
|
b161c9 |
}
|
|
|
b161c9 |
memberof_unlock_config();
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -1284,11 +1303,11 @@ int memberof_postop_add(Slapi_PBlock *pb)
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
memberof_unlock();
|
|
|
b161c9 |
-
|
|
|
b161c9 |
memberof_free_config(&configCopy);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
+bail:
|
|
|
b161c9 |
if(ret){
|
|
|
b161c9 |
slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ret;;
|
|
|
b161c9 |
ret = SLAPI_PLUGIN_FAILURE;
|
|
|
a2f18f |
@@ -1326,26 +1345,61 @@ int memberof_oktodo(Slapi_PBlock *pb)
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
if(slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc) != 0)
|
|
|
b161c9 |
- {
|
|
|
b161c9 |
+ {
|
|
|
b161c9 |
slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
"memberof_postop_oktodo: could not get parameters\n" );
|
|
|
b161c9 |
ret = -1;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
- /* this plugin should only execute if the operation succeeded
|
|
|
b161c9 |
- */
|
|
|
b161c9 |
- if(oprc != 0)
|
|
|
b161c9 |
+ /* this plugin should only execute if the operation succeeded */
|
|
|
b161c9 |
+ if(oprc != 0)
|
|
|
b161c9 |
{
|
|
|
b161c9 |
ret = 0;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
-
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+bail:
|
|
|
b161c9 |
slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
"<-- memberof_postop_oktodo\n" );
|
|
|
b161c9 |
|
|
|
b161c9 |
-bail:
|
|
|
b161c9 |
return ret;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
+/*
|
|
|
b161c9 |
+ * Return 1 if the entry is in the scope.
|
|
|
b161c9 |
+ * For MODRDN the caller should check both the preop
|
|
|
b161c9 |
+ * and postop entries. If we are moving out of, or
|
|
|
b161c9 |
+ * into scope, we should process it.
|
|
|
b161c9 |
+ */
|
|
|
b161c9 |
+static int
|
|
|
b161c9 |
+memberof_entry_in_scope(MemberOfConfig *config, Slapi_DN *sdn)
|
|
|
b161c9 |
+{
|
|
|
b161c9 |
+ if (config->entryScopeExcludeSubtrees){
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ /* check the excludes */
|
|
|
b161c9 |
+ while(config->entryScopeExcludeSubtrees[i]){
|
|
|
b161c9 |
+ if (slapi_sdn_issuffix(sdn, config->entryScopeExcludeSubtrees[i])){
|
|
|
b161c9 |
+ return 0;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ i++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ if (config->entryScopes){
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ /* check the excludes */
|
|
|
b161c9 |
+ while(config->entryScopes[i]){
|
|
|
b161c9 |
+ if (slapi_sdn_issuffix(sdn, config->entryScopes[i])){
|
|
|
b161c9 |
+ return 1;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ i++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ return 0;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ return 1;
|
|
|
b161c9 |
+}
|
|
|
b161c9 |
+
|
|
|
b161c9 |
static Slapi_DN *
|
|
|
b161c9 |
memberof_getsdn(Slapi_PBlock *pb)
|
|
|
b161c9 |
{
|
|
|
a2f18f |
@@ -2013,7 +2067,7 @@ memberof_get_groups_r(MemberOfConfig *config, Slapi_DN *member_sdn,
|
|
|
b161c9 |
{
|
|
|
b161c9 |
/* Search for any grouping attributes that point to memberdn.
|
|
|
b161c9 |
* For each match, add it to the list, recurse and do same search */
|
|
|
b161c9 |
- return memberof_call_foreach_dn(NULL, member_sdn, config->groupattrs,
|
|
|
b161c9 |
+ return memberof_call_foreach_dn(NULL, member_sdn, config, config->groupattrs,
|
|
|
b161c9 |
memberof_get_groups_callback, data);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -2030,7 +2084,6 @@ int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data)
|
|
|
a2f18f |
Slapi_Value *group_dn_val = 0;
|
|
|
b161c9 |
Slapi_ValueSet *groupvals = *((memberof_get_groups_data*)callback_data)->groupvals;
|
|
|
a2f18f |
Slapi_ValueSet *group_norm_vals = *((memberof_get_groups_data*)callback_data)->group_norm_vals;
|
|
|
a2f18f |
- Slapi_DN *entry_scope_exclude_subtree = memberof_config_get_entry_scope_exclude_subtree();
|
|
|
a2f18f |
MemberOfConfig *config = ((memberof_get_groups_data*)callback_data)->config;
|
|
|
b161c9 |
int rc = 0;
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -2086,7 +2139,7 @@ int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data)
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
a2f18f |
/* if the group does not belong to an excluded subtree, adds it to the valueset */
|
|
|
a2f18f |
- if (!(entry_scope_exclude_subtree && slapi_sdn_issuffix(group_sdn, entry_scope_exclude_subtree))) {
|
|
|
b161c9 |
+ if (memberof_entry_in_scope(config, group_sdn)) {
|
|
|
a2f18f |
/* Push group_dn_val into the valueset. This memory is now owned
|
|
|
a2f18f |
* by the valueset. */
|
|
|
a2f18f |
group_dn_val = slapi_value_new_string(group_dn);
|
|
|
a2f18f |
@@ -2188,8 +2241,8 @@ memberof_test_membership(Slapi_PBlock *pb, MemberOfConfig *config,
|
|
|
b161c9 |
{
|
|
|
b161c9 |
char *attrs[2] = {config->memberof_attr, 0};
|
|
|
b161c9 |
|
|
|
b161c9 |
- return memberof_call_foreach_dn(pb, group_sdn, attrs,
|
|
|
b161c9 |
- memberof_test_membership_callback , config);
|
|
|
b161c9 |
+ return memberof_call_foreach_dn(pb, group_sdn, config, attrs,
|
|
|
b161c9 |
+ memberof_test_membership_callback, config);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
/*
|
|
|
b161c9 |
diff --git a/ldap/servers/plugins/memberof/memberof.h b/ldap/servers/plugins/memberof/memberof.h
|
|
|
a2f18f |
index 5a70400..9d9d158 100644
|
|
|
b161c9 |
--- a/ldap/servers/plugins/memberof/memberof.h
|
|
|
b161c9 |
+++ b/ldap/servers/plugins/memberof/memberof.h
|
|
|
a2f18f |
@@ -52,8 +52,10 @@ typedef struct memberofconfig {
|
|
|
b161c9 |
char **groupattrs;
|
|
|
b161c9 |
char *memberof_attr;
|
|
|
b161c9 |
int allBackends;
|
|
|
b161c9 |
- Slapi_DN *entryScope;
|
|
|
b161c9 |
- Slapi_DN *entryScopeExcludeSubtree;
|
|
|
b161c9 |
+ Slapi_DN **entryScopes;
|
|
|
b161c9 |
+ int entryScopeCount;
|
|
|
b161c9 |
+ Slapi_DN **entryScopeExcludeSubtrees;
|
|
|
b161c9 |
+ int entryExcludeScopeCount;
|
|
|
b161c9 |
Slapi_Filter *group_filter;
|
|
|
b161c9 |
Slapi_Attr **group_slapiattrs;
|
|
|
a2f18f |
int skip_nested;
|
|
|
a2f18f |
@@ -74,8 +76,6 @@ void memberof_rlock_config();
|
|
|
b161c9 |
void memberof_wlock_config();
|
|
|
b161c9 |
void memberof_unlock_config();
|
|
|
b161c9 |
int memberof_config_get_all_backends();
|
|
|
b161c9 |
-Slapi_DN * memberof_config_get_entry_scope();
|
|
|
b161c9 |
-Slapi_DN * memberof_config_get_entry_scope_exclude_subtree();
|
|
|
b161c9 |
void memberof_set_config_area(Slapi_DN *sdn);
|
|
|
b161c9 |
Slapi_DN * memberof_get_config_area();
|
|
|
b161c9 |
void memberof_set_plugin_area(Slapi_DN *sdn);
|
|
|
b161c9 |
diff --git a/ldap/servers/plugins/memberof/memberof_config.c b/ldap/servers/plugins/memberof/memberof_config.c
|
|
|
a2f18f |
index ac2d045..b4cc941 100644
|
|
|
b161c9 |
--- a/ldap/servers/plugins/memberof/memberof_config.c
|
|
|
b161c9 |
+++ b/ldap/servers/plugins/memberof/memberof_config.c
|
|
|
a2f18f |
@@ -48,7 +48,7 @@ static int memberof_search (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_En
|
|
|
b161c9 |
/* This is the main configuration which is updated from dse.ldif. The
|
|
|
b161c9 |
* config will be copied when it is used by the plug-in to prevent it
|
|
|
b161c9 |
* being changed out from under a running memberOf operation. */
|
|
|
b161c9 |
-static MemberOfConfig theConfig = {NULL, NULL,0, NULL, NULL, NULL, NULL};
|
|
|
b161c9 |
+static MemberOfConfig theConfig = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
b161c9 |
static Slapi_RWLock *memberof_config_lock = 0;
|
|
|
b161c9 |
static int inited = 0;
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -60,6 +60,19 @@ static int dont_allow_that(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Ent
|
|
|
b161c9 |
return SLAPI_DSE_CALLBACK_ERROR;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
+static void
|
|
|
b161c9 |
+memberof_free_scope(Slapi_DN **scopes, int *count)
|
|
|
b161c9 |
+{
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ while(scopes && scopes[i]){
|
|
|
b161c9 |
+ slapi_sdn_free(&scopes[i]);
|
|
|
b161c9 |
+ i++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ slapi_ch_free((void**)&scopes);
|
|
|
b161c9 |
+ *count = 0;
|
|
|
b161c9 |
+}
|
|
|
b161c9 |
+
|
|
|
b161c9 |
/*
|
|
|
b161c9 |
* memberof_config()
|
|
|
b161c9 |
*
|
|
|
a2f18f |
@@ -155,17 +168,22 @@ memberof_release_config()
|
|
|
b161c9 |
*
|
|
|
b161c9 |
* Validate the pending changes in the e entry.
|
|
|
b161c9 |
*/
|
|
|
b161c9 |
-static int
|
|
|
b161c9 |
+int
|
|
|
b161c9 |
memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
|
|
|
b161c9 |
int *returncode, char *returntext, void *arg)
|
|
|
b161c9 |
{
|
|
|
b161c9 |
Slapi_Attr *memberof_attr = NULL;
|
|
|
b161c9 |
Slapi_Attr *group_attr = NULL;
|
|
|
b161c9 |
Slapi_DN *config_sdn = NULL;
|
|
|
b161c9 |
+ Slapi_DN **include_dn = NULL;
|
|
|
b161c9 |
+ Slapi_DN **exclude_dn = NULL;
|
|
|
b161c9 |
char *syntaxoid = NULL;
|
|
|
b161c9 |
char *config_dn = NULL;
|
|
|
a2f18f |
char *skip_nested = NULL;
|
|
|
b161c9 |
+ char **entry_scopes = NULL;
|
|
|
b161c9 |
+ char **entry_exclude_scopes = NULL;
|
|
|
b161c9 |
int not_dn_syntax = 0;
|
|
|
b161c9 |
+ int num_vals = 0;
|
|
|
b161c9 |
|
|
|
b161c9 |
*returncode = LDAP_UNWILLING_TO_PERFORM; /* be pessimistic */
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -283,8 +301,112 @@ memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
|
|
|
b161c9 |
*returncode = LDAP_UNWILLING_TO_PERFORM;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
}
|
|
|
b161c9 |
+ /*
|
|
|
b161c9 |
+ * Check the entry scopes
|
|
|
b161c9 |
+ */
|
|
|
b161c9 |
+ entry_scopes = slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_ATTR, &num_vals);
|
|
|
b161c9 |
+ if(entry_scopes){
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ /* Validate the syntax before we create our DN array */
|
|
|
b161c9 |
+ for (i = 0;i < num_vals; i++){
|
|
|
b161c9 |
+ if(slapi_dn_syntax_check(pb, entry_scopes[i], 1)){
|
|
|
b161c9 |
+ /* invalid dn syntax */
|
|
|
b161c9 |
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
|
|
|
b161c9 |
+ "%s: Invalid DN (%s) for include suffix.",
|
|
|
b161c9 |
+ MEMBEROF_PLUGIN_SUBSYSTEM, entry_scopes[i]);
|
|
|
b161c9 |
+ slapi_ch_array_free(entry_scopes);
|
|
|
b161c9 |
+ theConfig.entryScopeCount = 0;
|
|
|
b161c9 |
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
|
|
|
b161c9 |
+ goto done;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ /* Now create our SDN array for conflict checking */
|
|
|
b161c9 |
+ include_dn = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *), num_vals+1);
|
|
|
b161c9 |
+ for (i = 0;i < num_vals; i++){
|
|
|
b161c9 |
+ include_dn[i] = slapi_sdn_new_dn_passin(entry_scopes[i]);
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ /*
|
|
|
b161c9 |
+ * Check and process the entry exclude scopes
|
|
|
b161c9 |
+ */
|
|
|
b161c9 |
+ entry_exclude_scopes =
|
|
|
b161c9 |
+ slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE, &num_vals);
|
|
|
b161c9 |
+ if(entry_exclude_scopes){
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ /* Validate the syntax before we create our DN array */
|
|
|
b161c9 |
+ for (i = 0;i < num_vals; i++){
|
|
|
b161c9 |
+ if(slapi_dn_syntax_check(pb, entry_exclude_scopes[i], 1)){
|
|
|
b161c9 |
+ /* invalid dn syntax */
|
|
|
b161c9 |
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
|
|
|
b161c9 |
+ "%s: Invalid DN (%s) for exclude suffix.",
|
|
|
b161c9 |
+ MEMBEROF_PLUGIN_SUBSYSTEM, entry_scopes[i]);
|
|
|
b161c9 |
+ slapi_ch_array_free(entry_exclude_scopes);
|
|
|
b161c9 |
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
|
|
|
b161c9 |
+ goto done;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ /* Now create our SDN array for conflict checking */
|
|
|
b161c9 |
+ exclude_dn = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1);
|
|
|
b161c9 |
+ for (i = 0;i < num_vals; i++){
|
|
|
b161c9 |
+ exclude_dn[i] = slapi_sdn_new_dn_passin(entry_exclude_scopes[i]);
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ /*
|
|
|
b161c9 |
+ * Need to do conflict checking
|
|
|
b161c9 |
+ */
|
|
|
b161c9 |
+ if(include_dn && exclude_dn){
|
|
|
b161c9 |
+ /*
|
|
|
b161c9 |
+ * Make sure we haven't mixed the same suffix, and there are no
|
|
|
b161c9 |
+ * conflicts between the includes and excludes
|
|
|
b161c9 |
+ */
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ while(include_dn[i]){
|
|
|
b161c9 |
+ int x = 0;
|
|
|
b161c9 |
+ while(exclude_dn[x]){
|
|
|
b161c9 |
+ if(slapi_sdn_compare(include_dn[i], exclude_dn[x] ) == 0)
|
|
|
b161c9 |
+ {
|
|
|
b161c9 |
+ /* we have a conflict */
|
|
|
b161c9 |
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
|
|
|
b161c9 |
+ "%s: include suffix (%s) is also listed as an exclude suffix list",
|
|
|
b161c9 |
+ MEMBEROF_PLUGIN_SUBSYSTEM, slapi_sdn_get_dn(include_dn[i]));
|
|
|
b161c9 |
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
|
|
|
b161c9 |
+ goto done;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ x++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ i++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ /* Check for parent/child conflicts */
|
|
|
b161c9 |
+ i = 0;
|
|
|
b161c9 |
+ while(include_dn[i]){
|
|
|
b161c9 |
+ int x = 0;
|
|
|
b161c9 |
+ while(exclude_dn[x]){
|
|
|
b161c9 |
+ if(slapi_sdn_issuffix(include_dn[i], exclude_dn[x]))
|
|
|
b161c9 |
+ {
|
|
|
b161c9 |
+ /* we have a conflict */
|
|
|
b161c9 |
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
|
|
|
b161c9 |
+ "%s: include suffix (%s) is a child of the exclude suffix(%s)",
|
|
|
b161c9 |
+ MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
+ slapi_sdn_get_dn(include_dn[i]),
|
|
|
b161c9 |
+ slapi_sdn_get_dn(exclude_dn[i]));
|
|
|
b161c9 |
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
|
|
|
b161c9 |
+ goto done;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ x++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ i++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
|
|
|
b161c9 |
done:
|
|
|
b161c9 |
+ memberof_free_scope(exclude_dn, &num_vals);
|
|
|
b161c9 |
+ memberof_free_scope(include_dn, &num_vals);
|
|
|
b161c9 |
+ slapi_ch_free((void**)&entry_scopes);
|
|
|
b161c9 |
+ slapi_ch_free((void**)&entry_exclude_scopes);
|
|
|
b161c9 |
slapi_sdn_free(&config_sdn);
|
|
|
b161c9 |
slapi_ch_free_string(&config_dn);
|
|
|
a2f18f |
slapi_ch_free_string(&skip_nested);
|
|
|
a2f18f |
@@ -299,7 +421,6 @@ done:
|
|
|
b161c9 |
}
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
-
|
|
|
b161c9 |
/*
|
|
|
b161c9 |
* memberof_apply_config()
|
|
|
b161c9 |
*
|
|
|
a2f18f |
@@ -318,10 +439,11 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
|
|
|
b161c9 |
int num_groupattrs = 0;
|
|
|
b161c9 |
int groupattr_name_len = 0;
|
|
|
b161c9 |
char *allBackends = NULL;
|
|
|
b161c9 |
- char *entryScope = NULL;
|
|
|
a2f18f |
- char *entryScopeExcludeSubtree = NULL;
|
|
|
b161c9 |
+ char **entryScopes = NULL;
|
|
|
b161c9 |
+ char **entryScopeExcludeSubtrees = NULL;
|
|
|
b161c9 |
char *sharedcfg = NULL;
|
|
|
a2f18f |
char *skip_nested = NULL;
|
|
|
b161c9 |
+ int num_vals = 0;
|
|
|
b161c9 |
|
|
|
b161c9 |
*returncode = LDAP_SUCCESS;
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -353,8 +475,6 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
|
|
|
b161c9 |
groupattrs = slapi_entry_attr_get_charray(e, MEMBEROF_GROUP_ATTR);
|
|
|
b161c9 |
memberof_attr = slapi_entry_attr_get_charptr(e, MEMBEROF_ATTR);
|
|
|
b161c9 |
allBackends = slapi_entry_attr_get_charptr(e, MEMBEROF_BACKEND_ATTR);
|
|
|
b161c9 |
- entryScope = slapi_entry_attr_get_charptr(e, MEMBEROF_ENTRY_SCOPE_ATTR);
|
|
|
a2f18f |
- entryScopeExcludeSubtree = slapi_entry_attr_get_charptr(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE);
|
|
|
a2f18f |
skip_nested = slapi_entry_attr_get_charptr(e, MEMBEROF_SKIP_NESTED_ATTR);
|
|
|
b161c9 |
|
|
|
b161c9 |
/*
|
|
|
a2f18f |
@@ -480,49 +600,39 @@ memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
|
|
|
b161c9 |
theConfig.allBackends = 0;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
- slapi_sdn_free(&theConfig.entryScope);
|
|
|
b161c9 |
- if (entryScope)
|
|
|
b161c9 |
- {
|
|
|
b161c9 |
- if (slapi_dn_syntax_check(NULL, entryScope, 1) == 1) {
|
|
|
b161c9 |
- slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
- "Error: Ignoring invalid DN used as plugin entry scope: [%s]\n",
|
|
|
b161c9 |
- entryScope);
|
|
|
b161c9 |
- theConfig.entryScope = NULL;
|
|
|
b161c9 |
- slapi_ch_free_string(&entryScope);
|
|
|
b161c9 |
- } else {
|
|
|
b161c9 |
- theConfig.entryScope = slapi_sdn_new_dn_passin(entryScope);
|
|
|
b161c9 |
+ /*
|
|
|
b161c9 |
+ * Check and process the entry scopes
|
|
|
b161c9 |
+ */
|
|
|
b161c9 |
+ memberof_free_scope(theConfig.entryScopes, &theConfig.entryScopeCount);
|
|
|
b161c9 |
+ entryScopes = slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_ATTR, &num_vals);
|
|
|
b161c9 |
+ if(entryScopes){
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ /* Validation has already been performed in preop, just build the DN's */
|
|
|
b161c9 |
+ theConfig.entryScopes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *), num_vals+1);
|
|
|
b161c9 |
+ for (i = 0;i < num_vals; i++){
|
|
|
b161c9 |
+ theConfig.entryScopes[i] = slapi_sdn_new_dn_passin(entryScopes[i]);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
- } else {
|
|
|
b161c9 |
- theConfig.entryScope = NULL;
|
|
|
b161c9 |
+ theConfig.entryScopeCount = num_vals; /* shortcut for config copy */
|
|
|
b161c9 |
}
|
|
|
b161c9 |
-
|
|
|
b161c9 |
- slapi_sdn_free(&theConfig.entryScopeExcludeSubtree);
|
|
|
b161c9 |
- if (entryScopeExcludeSubtree)
|
|
|
b161c9 |
- {
|
|
|
b161c9 |
- if (theConfig.entryScope == NULL) {
|
|
|
b161c9 |
- slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
- "Error: Ignoring ExcludeSubtree (%s) because entryScope is not define\n",
|
|
|
b161c9 |
- entryScopeExcludeSubtree);
|
|
|
b161c9 |
- theConfig.entryScopeExcludeSubtree = NULL;
|
|
|
b161c9 |
- slapi_ch_free_string(&entryScopeExcludeSubtree);
|
|
|
b161c9 |
- } else if (slapi_dn_syntax_check(NULL, entryScopeExcludeSubtree, 1) == 1) {
|
|
|
b161c9 |
- slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
- "Error: Ignoring invalid DN used as plugin entry exclude subtree: [%s]\n",
|
|
|
b161c9 |
- entryScopeExcludeSubtree);
|
|
|
b161c9 |
- theConfig.entryScopeExcludeSubtree = NULL;
|
|
|
b161c9 |
- slapi_ch_free_string(&entryScopeExcludeSubtree);
|
|
|
b161c9 |
- } else {
|
|
|
b161c9 |
- theConfig.entryScopeExcludeSubtree = slapi_sdn_new_dn_passin(entryScopeExcludeSubtree);
|
|
|
b161c9 |
+ /*
|
|
|
b161c9 |
+ * Check and process the entry exclude scopes
|
|
|
b161c9 |
+ */
|
|
|
b161c9 |
+ memberof_free_scope(theConfig.entryScopeExcludeSubtrees,
|
|
|
b161c9 |
+ &theConfig.entryExcludeScopeCount);
|
|
|
b161c9 |
+ entryScopeExcludeSubtrees =
|
|
|
b161c9 |
+ slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE, &num_vals);
|
|
|
b161c9 |
+ if(entryScopeExcludeSubtrees){
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ /* Validation has already been performed in preop, just build the DN's */
|
|
|
b161c9 |
+ theConfig.entryScopeExcludeSubtrees =
|
|
|
b161c9 |
+ (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1);
|
|
|
b161c9 |
+ for (i = 0;i < num_vals; i++){
|
|
|
b161c9 |
+ theConfig.entryScopeExcludeSubtrees[i] =
|
|
|
b161c9 |
+ slapi_sdn_new_dn_passin(entryScopeExcludeSubtrees[i]);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
- } else {
|
|
|
b161c9 |
- theConfig.entryScopeExcludeSubtree = NULL;
|
|
|
b161c9 |
- }
|
|
|
b161c9 |
- if (theConfig.entryScopeExcludeSubtree && theConfig.entryScope && !slapi_sdn_issuffix(theConfig.entryScopeExcludeSubtree, theConfig.entryScope)) {
|
|
|
b161c9 |
- slapi_log_error(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
|
|
|
b161c9 |
- "Error: Ignoring ExcludeSubtree (%s) that is out of the scope (%s)\n",
|
|
|
b161c9 |
- slapi_sdn_get_dn(theConfig.entryScopeExcludeSubtree),
|
|
|
b161c9 |
- slapi_sdn_get_dn(theConfig.entryScope));
|
|
|
b161c9 |
- slapi_sdn_free(&theConfig.entryScopeExcludeSubtree);
|
|
|
b161c9 |
+ theConfig.entryExcludeScopeCount = num_vals; /* shortcut for config copy */
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
/* release the lock */
|
|
|
a2f18f |
@@ -536,6 +646,8 @@ done:
|
|
|
b161c9 |
slapi_ch_free_string(&memberof_attr);
|
|
|
b161c9 |
slapi_ch_free_string(&allBackends);
|
|
|
a2f18f |
slapi_ch_free_string(&skip_nested);
|
|
|
b161c9 |
+ slapi_ch_free((void **)&entryScopes);
|
|
|
b161c9 |
+ slapi_ch_free((void **)&entryScopeExcludeSubtrees);
|
|
|
b161c9 |
|
|
|
b161c9 |
if (*returncode != LDAP_SUCCESS)
|
|
|
b161c9 |
{
|
|
|
a2f18f |
@@ -616,6 +728,23 @@ memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src)
|
|
|
b161c9 |
{
|
|
|
b161c9 |
dest->allBackends = src->allBackends;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ if(src->entryScopes){
|
|
|
b161c9 |
+ int num_vals = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ dest->entryScopes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),src->entryScopeCount+1);
|
|
|
b161c9 |
+ for(num_vals = 0; src->entryScopes[num_vals]; num_vals++){
|
|
|
b161c9 |
+ dest->entryScopes[num_vals] = slapi_sdn_dup(src->entryScopes[num_vals]);
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ if(src->entryScopeExcludeSubtrees){
|
|
|
b161c9 |
+ int num_vals = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ dest->entryScopeExcludeSubtrees = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),src->entryExcludeScopeCount+1);
|
|
|
b161c9 |
+ for(num_vals = 0; src->entryScopes[num_vals]; num_vals++){
|
|
|
b161c9 |
+ dest->entryScopeExcludeSubtrees[num_vals] = slapi_sdn_dup(src->entryScopeExcludeSubtrees[num_vals]);
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
}
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -641,6 +770,8 @@ memberof_free_config(MemberOfConfig *config)
|
|
|
b161c9 |
slapi_ch_free((void **)&config->group_slapiattrs);
|
|
|
b161c9 |
|
|
|
b161c9 |
slapi_ch_free_string(&config->memberof_attr);
|
|
|
b161c9 |
+ memberof_free_scope(config->entryScopes, &config->entryScopeCount);
|
|
|
b161c9 |
+ memberof_free_scope(config->entryScopeExcludeSubtrees, &config->entryExcludeScopeCount);
|
|
|
b161c9 |
}
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -706,30 +837,6 @@ memberof_config_get_all_backends()
|
|
|
b161c9 |
return all_backends;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
-Slapi_DN *
|
|
|
b161c9 |
-memberof_config_get_entry_scope()
|
|
|
b161c9 |
-{
|
|
|
b161c9 |
- Slapi_DN *entry_scope;
|
|
|
b161c9 |
-
|
|
|
b161c9 |
- slapi_rwlock_rdlock(memberof_config_lock);
|
|
|
b161c9 |
- entry_scope = theConfig.entryScope;
|
|
|
b161c9 |
- slapi_rwlock_unlock(memberof_config_lock);
|
|
|
b161c9 |
-
|
|
|
b161c9 |
- return entry_scope;
|
|
|
b161c9 |
-}
|
|
|
b161c9 |
-
|
|
|
b161c9 |
-Slapi_DN *
|
|
|
b161c9 |
-memberof_config_get_entry_scope_exclude_subtree()
|
|
|
b161c9 |
-{
|
|
|
b161c9 |
- Slapi_DN *entry_exclude_subtree;
|
|
|
b161c9 |
-
|
|
|
b161c9 |
- slapi_rwlock_rdlock(memberof_config_lock);
|
|
|
b161c9 |
- entry_exclude_subtree = theConfig.entryScopeExcludeSubtree;
|
|
|
b161c9 |
- slapi_rwlock_unlock(memberof_config_lock);
|
|
|
b161c9 |
-
|
|
|
b161c9 |
- return entry_exclude_subtree;
|
|
|
b161c9 |
-}
|
|
|
b161c9 |
-
|
|
|
b161c9 |
/*
|
|
|
b161c9 |
* Check if we are modifying the config, or changing the shared config entry
|
|
|
b161c9 |
*/
|
|
|
b161c9 |
diff --git a/ldap/servers/plugins/retrocl/retrocl.c b/ldap/servers/plugins/retrocl/retrocl.c
|
|
|
a2f18f |
index 78a0c6d..4bcbb38 100644
|
|
|
b161c9 |
--- a/ldap/servers/plugins/retrocl/retrocl.c
|
|
|
b161c9 |
+++ b/ldap/servers/plugins/retrocl/retrocl.c
|
|
|
a2f18f |
@@ -45,6 +45,9 @@ char **retrocl_attributes = NULL;
|
|
|
b161c9 |
char **retrocl_aliases = NULL;
|
|
|
b161c9 |
int retrocl_log_deleted = 0;
|
|
|
b161c9 |
|
|
|
b161c9 |
+static Slapi_DN **retrocl_includes = NULL;
|
|
|
b161c9 |
+static Slapi_DN **retrocl_excludes = NULL;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
/* ----------------------------- Retrocl Plugin */
|
|
|
b161c9 |
|
|
|
b161c9 |
static Slapi_PluginDesc retrocldesc = {"retrocl", VENDOR, DS_PACKAGE_VERSION, "Retrocl Plugin"};
|
|
|
a2f18f |
@@ -349,6 +352,8 @@ static int retrocl_start (Slapi_PBlock *pb)
|
|
|
b161c9 |
int rc = 0;
|
|
|
b161c9 |
Slapi_Entry *e = NULL;
|
|
|
b161c9 |
char **values = NULL;
|
|
|
b161c9 |
+ int num_vals = 0;
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
|
|
|
b161c9 |
retrocl_rootdse_init(pb);
|
|
|
b161c9 |
|
|
|
a2f18f |
@@ -369,6 +374,87 @@ static int retrocl_start (Slapi_PBlock *pb)
|
|
|
b161c9 |
return -1;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
+ /* Get the exclude suffixes */
|
|
|
b161c9 |
+ values = slapi_entry_attr_get_charray_ext(e, CONFIG_CHANGELOG_EXCLUDE_SUFFIX, &num_vals);
|
|
|
b161c9 |
+ if(values){
|
|
|
b161c9 |
+ /* Validate the syntax before we create our DN array */
|
|
|
b161c9 |
+ for (i = 0;i < num_vals; i++){
|
|
|
b161c9 |
+ if(slapi_dn_syntax_check(pb, values[i], 1)){
|
|
|
b161c9 |
+ /* invalid dn syntax */
|
|
|
b161c9 |
+ slapi_log_error(SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME,
|
|
|
b161c9 |
+ "Invalid DN (%s) for exclude suffix.\n", values[i] );
|
|
|
b161c9 |
+ slapi_ch_array_free(values);
|
|
|
b161c9 |
+ return -1;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ /* Now create our SDN array */
|
|
|
b161c9 |
+ retrocl_excludes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1);
|
|
|
b161c9 |
+ for (i = 0;i < num_vals; i++){
|
|
|
b161c9 |
+ retrocl_excludes[i] = slapi_sdn_new_dn_byval(values[i]);
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ slapi_ch_array_free(values);
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ /* Get the include suffixes */
|
|
|
b161c9 |
+ values = slapi_entry_attr_get_charray_ext(e, CONFIG_CHANGELOG_INCLUDE_SUFFIX, &num_vals);
|
|
|
b161c9 |
+ if(values){
|
|
|
b161c9 |
+ for (i = 0;i < num_vals; i++){
|
|
|
b161c9 |
+ /* Validate the syntax before we create our DN array */
|
|
|
b161c9 |
+ if(slapi_dn_syntax_check(pb, values[i], 1)){
|
|
|
b161c9 |
+ /* invalid dn syntax */
|
|
|
b161c9 |
+ slapi_log_error(SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME,
|
|
|
b161c9 |
+ "Invalid DN (%s) for include suffix.\n", values[i] );
|
|
|
b161c9 |
+ slapi_ch_array_free(values);
|
|
|
b161c9 |
+ return -1;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ /* Now create our SDN array */
|
|
|
b161c9 |
+ retrocl_includes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1);
|
|
|
b161c9 |
+ for (i = 0;i < num_vals; i++){
|
|
|
b161c9 |
+ retrocl_includes[i] = slapi_sdn_new_dn_byval(values[i]);
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ slapi_ch_array_free(values);
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ if(retrocl_includes && retrocl_excludes){
|
|
|
b161c9 |
+ /*
|
|
|
b161c9 |
+ * Make sure we haven't mixed the same suffix, and there are no
|
|
|
b161c9 |
+ * conflicts between the includes and excludes
|
|
|
b161c9 |
+ */
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ while(retrocl_includes[i]){
|
|
|
b161c9 |
+ int x = 0;
|
|
|
b161c9 |
+ while(retrocl_excludes[x]){
|
|
|
b161c9 |
+ if(slapi_sdn_compare(retrocl_includes[i], retrocl_excludes[x] ) == 0){
|
|
|
b161c9 |
+ /* we have a conflict */
|
|
|
b161c9 |
+ slapi_log_error(SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME,
|
|
|
b161c9 |
+ "include suffix (%s) is also listed in exclude suffix list\n",
|
|
|
b161c9 |
+ slapi_sdn_get_dn(retrocl_includes[i]));
|
|
|
b161c9 |
+ return -1;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ x++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ i++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ /* Check for parent/child conflicts */
|
|
|
b161c9 |
+ i = 0;
|
|
|
b161c9 |
+ while(retrocl_includes[i]){
|
|
|
b161c9 |
+ int x = 0;
|
|
|
b161c9 |
+ while(retrocl_excludes[x]){
|
|
|
b161c9 |
+ if(slapi_sdn_issuffix(retrocl_includes[i], retrocl_excludes[x])){
|
|
|
b161c9 |
+ /* we have a conflict */
|
|
|
b161c9 |
+ slapi_log_error(SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME,
|
|
|
b161c9 |
+ "include suffix (%s) is a child of the exclude suffix(%s)\n",
|
|
|
b161c9 |
+ slapi_sdn_get_dn(retrocl_includes[i]),
|
|
|
b161c9 |
+ slapi_sdn_get_dn(retrocl_excludes[i]));
|
|
|
b161c9 |
+ return -1;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ x++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ i++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+
|
|
|
b161c9 |
values = slapi_entry_attr_get_charray(e, "nsslapd-attribute");
|
|
|
b161c9 |
if (values != NULL) {
|
|
|
b161c9 |
int n = 0;
|
|
|
a2f18f |
@@ -434,6 +520,49 @@ static int retrocl_start (Slapi_PBlock *pb)
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
/*
|
|
|
b161c9 |
+ * Check if an entry is in the configured scope.
|
|
|
b161c9 |
+ * Return 1 if entry is in the scope, or 0 otherwise.
|
|
|
b161c9 |
+ * For MODRDN the caller should check both the preop
|
|
|
b161c9 |
+ * and postop entries. If we are moving out of, or
|
|
|
b161c9 |
+ * into scope, we should record it.
|
|
|
b161c9 |
+ */
|
|
|
b161c9 |
+int
|
|
|
b161c9 |
+retrocl_entry_in_scope(Slapi_Entry *e)
|
|
|
b161c9 |
+{
|
|
|
b161c9 |
+ Slapi_DN *sdn = slapi_entry_get_sdn(e);
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ if (e == NULL){
|
|
|
b161c9 |
+ return 1;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ if (retrocl_excludes){
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ /* check the excludes */
|
|
|
b161c9 |
+ while(retrocl_excludes[i]){
|
|
|
b161c9 |
+ if (slapi_sdn_issuffix(sdn, retrocl_excludes[i])){
|
|
|
b161c9 |
+ return 0;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ i++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ if (retrocl_includes){
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ /* check the excludes */
|
|
|
b161c9 |
+ while(retrocl_includes[i]){
|
|
|
b161c9 |
+ if (slapi_sdn_issuffix(sdn, retrocl_includes[i])){
|
|
|
b161c9 |
+ return 1;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ i++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ return 0;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ return 1;
|
|
|
b161c9 |
+}
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+/*
|
|
|
b161c9 |
* Function: retrocl_stop
|
|
|
b161c9 |
*
|
|
|
b161c9 |
* Returns: 0
|
|
|
a2f18f |
@@ -446,26 +575,40 @@ static int retrocl_start (Slapi_PBlock *pb)
|
|
|
b161c9 |
|
|
|
b161c9 |
static int retrocl_stop (Slapi_PBlock *pb)
|
|
|
b161c9 |
{
|
|
|
b161c9 |
- int rc = 0;
|
|
|
b161c9 |
-
|
|
|
b161c9 |
- slapi_ch_array_free(retrocl_attributes);
|
|
|
b161c9 |
- retrocl_attributes = NULL;
|
|
|
b161c9 |
- slapi_ch_array_free(retrocl_aliases);
|
|
|
b161c9 |
- retrocl_aliases = NULL;
|
|
|
b161c9 |
-
|
|
|
b161c9 |
- retrocl_stop_trimming();
|
|
|
b161c9 |
- retrocl_be_changelog = NULL;
|
|
|
b161c9 |
- retrocl_forget_changenumbers();
|
|
|
b161c9 |
- PR_DestroyLock(retrocl_internal_lock);
|
|
|
b161c9 |
- retrocl_internal_lock = NULL;
|
|
|
b161c9 |
- slapi_destroy_rwlock(retrocl_cn_lock);
|
|
|
b161c9 |
- retrocl_cn_lock = NULL;
|
|
|
b161c9 |
- legacy_initialised = 0;
|
|
|
b161c9 |
-
|
|
|
b161c9 |
- slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, "",
|
|
|
b161c9 |
- LDAP_SCOPE_BASE,"(objectclass=*)", retrocl_rootdse_search);
|
|
|
b161c9 |
-
|
|
|
b161c9 |
- return rc;
|
|
|
b161c9 |
+ int rc = 0;
|
|
|
b161c9 |
+ int i = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ slapi_ch_array_free(retrocl_attributes);
|
|
|
b161c9 |
+ retrocl_attributes = NULL;
|
|
|
b161c9 |
+ slapi_ch_array_free(retrocl_aliases);
|
|
|
b161c9 |
+ retrocl_aliases = NULL;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ while(retrocl_excludes && retrocl_excludes[i]){
|
|
|
b161c9 |
+ slapi_sdn_free(&retrocl_excludes[i]);
|
|
|
b161c9 |
+ i++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ slapi_ch_free((void**)&retrocl_excludes);
|
|
|
b161c9 |
+ i = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ while(retrocl_includes && retrocl_includes[i]){
|
|
|
b161c9 |
+ slapi_sdn_free(&retrocl_includes[i]);
|
|
|
b161c9 |
+ i++;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ slapi_ch_free((void**)&retrocl_includes);
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ retrocl_stop_trimming();
|
|
|
b161c9 |
+ retrocl_be_changelog = NULL;
|
|
|
b161c9 |
+ retrocl_forget_changenumbers();
|
|
|
b161c9 |
+ PR_DestroyLock(retrocl_internal_lock);
|
|
|
b161c9 |
+ retrocl_internal_lock = NULL;
|
|
|
b161c9 |
+ slapi_destroy_rwlock(retrocl_cn_lock);
|
|
|
b161c9 |
+ retrocl_cn_lock = NULL;
|
|
|
b161c9 |
+ legacy_initialised = 0;
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, "",
|
|
|
b161c9 |
+ LDAP_SCOPE_BASE,"(objectclass=*)", retrocl_rootdse_search);
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ return rc;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
/*
|
|
|
b161c9 |
diff --git a/ldap/servers/plugins/retrocl/retrocl.h b/ldap/servers/plugins/retrocl/retrocl.h
|
|
|
a2f18f |
index ae0139c..7edd62f 100644
|
|
|
b161c9 |
--- a/ldap/servers/plugins/retrocl/retrocl.h
|
|
|
b161c9 |
+++ b/ldap/servers/plugins/retrocl/retrocl.h
|
|
|
a2f18f |
@@ -67,6 +67,8 @@ typedef struct _cnumRet {
|
|
|
b161c9 |
/* was originally changelogmaximumage */
|
|
|
b161c9 |
#define CONFIG_CHANGELOG_MAXAGE_ATTRIBUTE "nsslapd-changelogmaxage"
|
|
|
b161c9 |
#define CONFIG_CHANGELOG_DIRECTORY_ATTRIBUTE "nsslapd-changelogdir"
|
|
|
b161c9 |
+#define CONFIG_CHANGELOG_INCLUDE_SUFFIX "nsslapd-include-suffix"
|
|
|
b161c9 |
+#define CONFIG_CHANGELOG_EXCLUDE_SUFFIX "nsslapd-exclude-suffix"
|
|
|
b161c9 |
|
|
|
b161c9 |
#define RETROCL_CHANGELOG_DN "cn=changelog"
|
|
|
b161c9 |
#define RETROCL_MAPPINGTREE_DN "cn=\"cn=changelog\",cn=mapping tree,cn=config"
|
|
|
a2f18f |
@@ -140,4 +142,6 @@ extern void retrocl_init_trimming(void);
|
|
|
b161c9 |
extern void retrocl_stop_trimming(void);
|
|
|
b161c9 |
extern char *retrocl_get_config_str(const char *attrt);
|
|
|
b161c9 |
|
|
|
b161c9 |
+int retrocl_entry_in_scope(Slapi_Entry *e);
|
|
|
b161c9 |
+
|
|
|
b161c9 |
#endif /* _H_RETROCL */
|
|
|
b161c9 |
diff --git a/ldap/servers/plugins/retrocl/retrocl_po.c b/ldap/servers/plugins/retrocl/retrocl_po.c
|
|
|
a2f18f |
index 7083d0a..f689373 100644
|
|
|
b161c9 |
--- a/ldap/servers/plugins/retrocl/retrocl_po.c
|
|
|
b161c9 |
+++ b/ldap/servers/plugins/retrocl/retrocl_po.c
|
|
|
a2f18f |
@@ -140,6 +140,7 @@ write_replog_db(
|
|
|
b161c9 |
int flag,
|
|
|
b161c9 |
time_t curtime,
|
|
|
b161c9 |
Slapi_Entry *log_e,
|
|
|
b161c9 |
+ Slapi_Entry *post_entry,
|
|
|
b161c9 |
const char *newrdn,
|
|
|
b161c9 |
LDAPMod **modrdn_mods,
|
|
|
b161c9 |
const char *newsuperior
|
|
|
a2f18f |
@@ -156,11 +157,26 @@ write_replog_db(
|
|
|
b161c9 |
int err = 0;
|
|
|
b161c9 |
int ret = LDAP_SUCCESS;
|
|
|
b161c9 |
int i;
|
|
|
b161c9 |
+ int mark = 0;
|
|
|
b161c9 |
|
|
|
b161c9 |
if (!dn) {
|
|
|
b161c9 |
slapi_log_error( SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "write_replog_db: NULL dn\n");
|
|
|
b161c9 |
return ret;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
+ mark = (post_entry && retrocl_entry_in_scope(post_entry));
|
|
|
b161c9 |
+ slapi_log_error( SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, "post in scope (%d)\n",mark);
|
|
|
b161c9 |
+
|
|
|
b161c9 |
+ if (post_entry){
|
|
|
b161c9 |
+ if(!retrocl_entry_in_scope(log_e) && !retrocl_entry_in_scope(post_entry)){
|
|
|
b161c9 |
+ /* modrdn: entry not in scope, just return... */
|
|
|
b161c9 |
+ return ret;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ } else {
|
|
|
b161c9 |
+ if(!retrocl_entry_in_scope(log_e)){
|
|
|
b161c9 |
+ /* entry not in scope, just return... */
|
|
|
b161c9 |
+ return ret;
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
+ }
|
|
|
b161c9 |
|
|
|
b161c9 |
PR_Lock(retrocl_internal_lock);
|
|
|
b161c9 |
changenum = retrocl_assign_changenumber();
|
|
|
a2f18f |
@@ -319,7 +335,7 @@ write_replog_db(
|
|
|
b161c9 |
break;
|
|
|
b161c9 |
|
|
|
b161c9 |
case OP_DELETE:
|
|
|
b161c9 |
- if (log_e) {
|
|
|
b161c9 |
+ if (retrocl_log_deleted) {
|
|
|
b161c9 |
/* we have to log the full entry */
|
|
|
b161c9 |
if ( entry2reple( e, log_e, OP_DELETE ) != 0 ) {
|
|
|
b161c9 |
err = SLAPI_PLUGIN_FAILURE;
|
|
|
a2f18f |
@@ -559,7 +575,8 @@ int retrocl_postob (Slapi_PBlock *pb, int optype)
|
|
|
b161c9 |
char *dn;
|
|
|
b161c9 |
LDAPMod **log_m = NULL;
|
|
|
b161c9 |
int flag = 0;
|
|
|
b161c9 |
- Slapi_Entry *te = NULL;
|
|
|
b161c9 |
+ Slapi_Entry *entry = NULL;
|
|
|
b161c9 |
+ Slapi_Entry *post_entry = NULL;
|
|
|
b161c9 |
Slapi_Operation *op = NULL;
|
|
|
b161c9 |
LDAPMod **modrdn_mods = NULL;
|
|
|
b161c9 |
char *newrdn = NULL;
|
|
|
a2f18f |
@@ -624,7 +641,12 @@ int retrocl_postob (Slapi_PBlock *pb, int optype)
|
|
|
b161c9 |
LDAPDebug0Args(LDAP_DEBUG_TRACE,"not applying change for nsTombstone entries\n");
|
|
|
b161c9 |
return SLAPI_PLUGIN_SUCCESS;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
-
|
|
|
b161c9 |
+ /*
|
|
|
b161c9 |
+ * Start by grabbing the preop entry, ADD will replace it as needed. Getting the entry
|
|
|
b161c9 |
+ * allows up to perform scoping in write_replog_db() for all op types.
|
|
|
b161c9 |
+ */
|
|
|
b161c9 |
+ (void)slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &entry);
|
|
|
b161c9 |
+
|
|
|
b161c9 |
switch ( optype ) {
|
|
|
b161c9 |
case OP_MODIFY:
|
|
|
b161c9 |
(void)slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &log_m );
|
|
|
a2f18f |
@@ -634,14 +656,14 @@ int retrocl_postob (Slapi_PBlock *pb, int optype)
|
|
|
b161c9 |
* For adds, we want the unnormalized dn, so we can preserve
|
|
|
b161c9 |
* spacing, case, when replicating it.
|
|
|
b161c9 |
*/
|
|
|
b161c9 |
- (void)slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &te );
|
|
|
b161c9 |
- if ( NULL != te ) {
|
|
|
b161c9 |
- dn = slapi_entry_get_dn( te );
|
|
|
b161c9 |
+ (void)slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &entry );
|
|
|
b161c9 |
+ if ( NULL != entry ) {
|
|
|
b161c9 |
+ dn = slapi_entry_get_dn( entry );
|
|
|
b161c9 |
}
|
|
|
b161c9 |
break;
|
|
|
b161c9 |
case OP_DELETE:
|
|
|
b161c9 |
if (retrocl_log_deleted)
|
|
|
b161c9 |
- (void)slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &te);
|
|
|
b161c9 |
+ (void)slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &entry);
|
|
|
b161c9 |
break;
|
|
|
b161c9 |
case OP_MODRDN:
|
|
|
b161c9 |
/* newrdn is used just for logging; no need to be normalized */
|
|
|
a2f18f |
@@ -649,13 +671,14 @@ int retrocl_postob (Slapi_PBlock *pb, int optype)
|
|
|
b161c9 |
(void)slapi_pblock_get( pb, SLAPI_MODRDN_DELOLDRDN, &flag );
|
|
|
b161c9 |
(void)slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &modrdn_mods );
|
|
|
b161c9 |
(void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &newsuperior );
|
|
|
b161c9 |
+ (void)slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &post_entry);
|
|
|
b161c9 |
break;
|
|
|
b161c9 |
}
|
|
|
b161c9 |
|
|
|
b161c9 |
/* check if we should log change to retro changelog, and
|
|
|
b161c9 |
* if so, do it here */
|
|
|
b161c9 |
- if((rc = write_replog_db( pb, optype, dn, log_m, flag, curtime, te,
|
|
|
b161c9 |
- newrdn, modrdn_mods, slapi_sdn_get_dn(newsuperior) )))
|
|
|
b161c9 |
+ if((rc = write_replog_db( pb, optype, dn, log_m, flag, curtime, entry,
|
|
|
b161c9 |
+ post_entry, newrdn, modrdn_mods, slapi_sdn_get_dn(newsuperior) )))
|
|
|
b161c9 |
{
|
|
|
b161c9 |
slapi_log_error(SLAPI_LOG_FATAL, "retrocl-plugin",
|
|
|
b161c9 |
"retrocl_postob: operation failure [%d]\n", rc);
|
|
|
b161c9 |
--
|
|
|
b161c9 |
1.9.3
|
|
|
b161c9 |
|