|
|
7e63d6 |
From faab51b0d14bdf7af013abdd7937f47cc0eb5cdc Mon Sep 17 00:00:00 2001
|
|
|
7e63d6 |
From: Simon Pichugin <spichugi@redhat.com>
|
|
|
7e63d6 |
Date: Fri, 10 Sep 2021 14:17:41 -0700
|
|
|
7e63d6 |
Subject: [PATCH] Issue 4894 - IPA failure in ipa user-del --preserve (#4907)
|
|
|
7e63d6 |
|
|
|
7e63d6 |
Bug Description: Starting with 389-ds 2.0.8 on rawhide,
|
|
|
7e63d6 |
any call to ipa user-del --preserve fails with
|
|
|
7e63d6 |
This entry already exists.
|
|
|
7e63d6 |
|
|
|
7e63d6 |
Fix Description: We should split 'dn' parameter in searchAllSubtrees
|
|
|
7e63d6 |
into parent and target. As one of them is used for excluding the
|
|
|
7e63d6 |
subtree checks and another one for searching.
|
|
|
7e63d6 |
Improve 'superior' processing when we don't change the parent.
|
|
|
7e63d6 |
Rename variables in a more sane way.
|
|
|
7e63d6 |
|
|
|
7e63d6 |
Fixes: https://github.com/389ds/389-ds-base/issues/4894
|
|
|
7e63d6 |
|
|
|
7e63d6 |
Reviewed by: @Firstyear, @tbordaz, @progier389 (Thanks!)
|
|
|
7e63d6 |
---
|
|
|
7e63d6 |
ldap/servers/plugins/uiduniq/uid.c | 78 +++++++++++++++---------------
|
|
|
7e63d6 |
1 file changed, 39 insertions(+), 39 deletions(-)
|
|
|
7e63d6 |
|
|
|
7e63d6 |
diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c
|
|
|
7e63d6 |
index 9924623a7..5b763b551 100644
|
|
|
7e63d6 |
--- a/ldap/servers/plugins/uiduniq/uid.c
|
|
|
7e63d6 |
+++ b/ldap/servers/plugins/uiduniq/uid.c
|
|
|
7e63d6 |
@@ -770,13 +770,13 @@ search_one_berval(Slapi_DN *baseDN, const char **attrNames, const struct berval
|
|
|
7e63d6 |
*
|
|
|
7e63d6 |
* Return:
|
|
|
7e63d6 |
* LDAP_SUCCESS - no matches, or the attribute matches the
|
|
|
7e63d6 |
- * target dn.
|
|
|
7e63d6 |
+ * source (target) dn.
|
|
|
7e63d6 |
* LDAP_CONSTRAINT_VIOLATION - an entry was found that already
|
|
|
7e63d6 |
* contains the attribute value.
|
|
|
7e63d6 |
* LDAP_OPERATIONS_ERROR - a server failure.
|
|
|
7e63d6 |
*/
|
|
|
7e63d6 |
static int
|
|
|
7e63d6 |
-searchAllSubtrees(Slapi_DN **subtrees, Slapi_DN **exclude_subtrees, const char **attrNames, Slapi_Attr *attr, struct berval **values, const char *requiredObjectClass, Slapi_DN *dn, PRBool unique_in_all_subtrees)
|
|
|
7e63d6 |
+searchAllSubtrees(Slapi_DN **subtrees, Slapi_DN **exclude_subtrees, const char **attrNames, Slapi_Attr *attr, struct berval **values, const char *requiredObjectClass, Slapi_DN *destinationSDN, Slapi_DN *sourceSDN, PRBool unique_in_all_subtrees)
|
|
|
7e63d6 |
{
|
|
|
7e63d6 |
int result = LDAP_SUCCESS;
|
|
|
7e63d6 |
int i;
|
|
|
7e63d6 |
@@ -788,12 +788,12 @@ searchAllSubtrees(Slapi_DN **subtrees, Slapi_DN **exclude_subtrees, const char *
|
|
|
7e63d6 |
* are unique in all the monitored subtrees
|
|
|
7e63d6 |
*/
|
|
|
7e63d6 |
|
|
|
7e63d6 |
- /* First check the target entry is in one of
|
|
|
7e63d6 |
+ /* First check the destination entry is in one of
|
|
|
7e63d6 |
* the monitored subtree, so adding 'values' would
|
|
|
7e63d6 |
* violate constraint
|
|
|
7e63d6 |
*/
|
|
|
7e63d6 |
for (i = 0; subtrees && subtrees[i]; i++) {
|
|
|
7e63d6 |
- if (slapi_sdn_issuffix(dn, subtrees[i])) {
|
|
|
7e63d6 |
+ if (slapi_sdn_issuffix(destinationSDN, subtrees[i])) {
|
|
|
7e63d6 |
in_a_subtree = PR_TRUE;
|
|
|
7e63d6 |
break;
|
|
|
7e63d6 |
}
|
|
|
7e63d6 |
@@ -808,7 +808,7 @@ searchAllSubtrees(Slapi_DN **subtrees, Slapi_DN **exclude_subtrees, const char *
|
|
|
7e63d6 |
if (exclude_subtrees != NULL) {
|
|
|
7e63d6 |
PRBool in_a_subtree = PR_FALSE;
|
|
|
7e63d6 |
for (i = 0; exclude_subtrees && exclude_subtrees[i]; i++) {
|
|
|
7e63d6 |
- if (slapi_sdn_issuffix(dn, exclude_subtrees[i])) {
|
|
|
7e63d6 |
+ if (slapi_sdn_issuffix(destinationSDN, exclude_subtrees[i])) {
|
|
|
7e63d6 |
in_a_subtree = PR_TRUE;
|
|
|
7e63d6 |
break;
|
|
|
7e63d6 |
}
|
|
|
7e63d6 |
@@ -820,7 +820,7 @@ searchAllSubtrees(Slapi_DN **subtrees, Slapi_DN **exclude_subtrees, const char *
|
|
|
7e63d6 |
|
|
|
7e63d6 |
/*
|
|
|
7e63d6 |
* For each DN in the managed list, do uniqueness checking if
|
|
|
7e63d6 |
- * the target DN is a subnode in the tree.
|
|
|
7e63d6 |
+ * the destination (target) DN is a subnode in the tree.
|
|
|
7e63d6 |
*/
|
|
|
7e63d6 |
for (i = 0; subtrees && subtrees[i]; i++) {
|
|
|
7e63d6 |
Slapi_DN *sufdn = subtrees[i];
|
|
|
7e63d6 |
@@ -828,8 +828,8 @@ searchAllSubtrees(Slapi_DN **subtrees, Slapi_DN **exclude_subtrees, const char *
|
|
|
7e63d6 |
* The DN should already be normalized, so we don't have to
|
|
|
7e63d6 |
* worry about that here.
|
|
|
7e63d6 |
*/
|
|
|
7e63d6 |
- if (unique_in_all_subtrees || slapi_sdn_issuffix(dn, sufdn)) {
|
|
|
7e63d6 |
- result = search(sufdn, attrNames, attr, values, requiredObjectClass, dn, exclude_subtrees);
|
|
|
7e63d6 |
+ if (unique_in_all_subtrees || slapi_sdn_issuffix(destinationSDN, sufdn)) {
|
|
|
7e63d6 |
+ result = search(sufdn, attrNames, attr, values, requiredObjectClass, sourceSDN, exclude_subtrees);
|
|
|
7e63d6 |
if (result)
|
|
|
7e63d6 |
break;
|
|
|
7e63d6 |
}
|
|
|
7e63d6 |
@@ -903,20 +903,20 @@ getArguments(Slapi_PBlock *pb, char **attrName, char **markerObjectClass, char *
|
|
|
7e63d6 |
*
|
|
|
7e63d6 |
* Return:
|
|
|
7e63d6 |
* LDAP_SUCCESS - no matches, or the attribute matches the
|
|
|
7e63d6 |
- * target dn.
|
|
|
7e63d6 |
+ * source (target) dn.
|
|
|
7e63d6 |
* LDAP_CONSTRAINT_VIOLATION - an entry was found that already
|
|
|
7e63d6 |
* contains the attribute value.
|
|
|
7e63d6 |
* LDAP_OPERATIONS_ERROR - a server failure.
|
|
|
7e63d6 |
*/
|
|
|
7e63d6 |
static int
|
|
|
7e63d6 |
-findSubtreeAndSearch(Slapi_DN *parentDN, const char **attrNames, Slapi_Attr *attr, struct berval **values, const char *requiredObjectClass, Slapi_DN *target, const char *markerObjectClass, Slapi_DN **excludes)
|
|
|
7e63d6 |
+findSubtreeAndSearch(Slapi_DN *destinationSDN, const char **attrNames, Slapi_Attr *attr, struct berval **values, const char *requiredObjectClass, Slapi_DN *sourceSDN, const char *markerObjectClass, Slapi_DN **excludes)
|
|
|
7e63d6 |
{
|
|
|
7e63d6 |
int result = LDAP_SUCCESS;
|
|
|
7e63d6 |
Slapi_PBlock *spb = NULL;
|
|
|
7e63d6 |
Slapi_DN *curpar = slapi_sdn_new();
|
|
|
7e63d6 |
Slapi_DN *newpar = NULL;
|
|
|
7e63d6 |
|
|
|
7e63d6 |
- slapi_sdn_get_parent(parentDN, curpar);
|
|
|
7e63d6 |
+ slapi_sdn_get_parent(destinationSDN, curpar);
|
|
|
7e63d6 |
while (slapi_sdn_get_dn(curpar) != NULL) {
|
|
|
7e63d6 |
if ((spb = dnHasObjectClass(curpar, markerObjectClass))) {
|
|
|
7e63d6 |
freePblock(spb);
|
|
|
7e63d6 |
@@ -925,7 +925,7 @@ findSubtreeAndSearch(Slapi_DN *parentDN, const char **attrNames, Slapi_Attr *att
|
|
|
7e63d6 |
* to have the attribute already.
|
|
|
7e63d6 |
*/
|
|
|
7e63d6 |
result = search(curpar, attrNames, attr, values, requiredObjectClass,
|
|
|
7e63d6 |
- target, excludes);
|
|
|
7e63d6 |
+ sourceSDN, excludes);
|
|
|
7e63d6 |
break;
|
|
|
7e63d6 |
}
|
|
|
7e63d6 |
newpar = slapi_sdn_new();
|
|
|
7e63d6 |
@@ -964,7 +964,7 @@ preop_add(Slapi_PBlock *pb)
|
|
|
7e63d6 |
int err;
|
|
|
7e63d6 |
char *markerObjectClass = NULL;
|
|
|
7e63d6 |
char *requiredObjectClass = NULL;
|
|
|
7e63d6 |
- Slapi_DN *sdn = NULL;
|
|
|
7e63d6 |
+ Slapi_DN *targetSDN = NULL;
|
|
|
7e63d6 |
int isupdatedn;
|
|
|
7e63d6 |
Slapi_Entry *e;
|
|
|
7e63d6 |
Slapi_Attr *attr;
|
|
|
7e63d6 |
@@ -998,16 +998,16 @@ preop_add(Slapi_PBlock *pb)
|
|
|
7e63d6 |
attr_friendly = config->attr_friendly;
|
|
|
7e63d6 |
|
|
|
7e63d6 |
/*
|
|
|
7e63d6 |
- * Get the target DN for this add operation
|
|
|
7e63d6 |
+ * Get the target SDN for this add operation
|
|
|
7e63d6 |
*/
|
|
|
7e63d6 |
- err = slapi_pblock_get(pb, SLAPI_ADD_TARGET_SDN, &sdn;;
|
|
|
7e63d6 |
+ err = slapi_pblock_get(pb, SLAPI_ADD_TARGET_SDN, &targetSDN);
|
|
|
7e63d6 |
if (err) {
|
|
|
7e63d6 |
result = uid_op_error(51);
|
|
|
7e63d6 |
break;
|
|
|
7e63d6 |
}
|
|
|
7e63d6 |
|
|
|
7e63d6 |
#ifdef DEBUG
|
|
|
7e63d6 |
- slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name, "preop_add - ADD target=%s\n", slapi_sdn_get_dn(sdn));
|
|
|
7e63d6 |
+ slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name, "preop_add - ADD target=%s\n", slapi_sdn_get_dn(targetSDN));
|
|
|
7e63d6 |
#endif
|
|
|
7e63d6 |
|
|
|
7e63d6 |
/*
|
|
|
7e63d6 |
@@ -1040,13 +1040,13 @@ preop_add(Slapi_PBlock *pb)
|
|
|
7e63d6 |
*/
|
|
|
7e63d6 |
if (NULL != markerObjectClass) {
|
|
|
7e63d6 |
/* Subtree defined by location of marker object class */
|
|
|
7e63d6 |
- result = findSubtreeAndSearch(sdn, attrNames, attr, NULL,
|
|
|
7e63d6 |
- requiredObjectClass, sdn,
|
|
|
7e63d6 |
+ result = findSubtreeAndSearch(targetSDN, attrNames, attr, NULL,
|
|
|
7e63d6 |
+ requiredObjectClass, targetSDN,
|
|
|
7e63d6 |
markerObjectClass, config->exclude_subtrees);
|
|
|
7e63d6 |
} else {
|
|
|
7e63d6 |
/* Subtrees listed on invocation line */
|
|
|
7e63d6 |
result = searchAllSubtrees(config->subtrees, config->exclude_subtrees, attrNames, attr, NULL,
|
|
|
7e63d6 |
- requiredObjectClass, sdn, config->unique_in_all_subtrees);
|
|
|
7e63d6 |
+ requiredObjectClass, targetSDN, targetSDN, config->unique_in_all_subtrees);
|
|
|
7e63d6 |
}
|
|
|
7e63d6 |
if (result != LDAP_SUCCESS) {
|
|
|
7e63d6 |
break;
|
|
|
7e63d6 |
@@ -1120,7 +1120,7 @@ preop_modify(Slapi_PBlock *pb)
|
|
|
7e63d6 |
int modcount = 0;
|
|
|
7e63d6 |
int ii;
|
|
|
7e63d6 |
LDAPMod *mod;
|
|
|
7e63d6 |
- Slapi_DN *sdn = NULL;
|
|
|
7e63d6 |
+ Slapi_DN *targetSDN = NULL;
|
|
|
7e63d6 |
int isupdatedn;
|
|
|
7e63d6 |
int i = 0;
|
|
|
7e63d6 |
|
|
|
7e63d6 |
@@ -1186,8 +1186,8 @@ preop_modify(Slapi_PBlock *pb)
|
|
|
7e63d6 |
break; /* no mods to check, we are done */
|
|
|
7e63d6 |
}
|
|
|
7e63d6 |
|
|
|
7e63d6 |
- /* Get the target DN */
|
|
|
7e63d6 |
- err = slapi_pblock_get(pb, SLAPI_MODIFY_TARGET_SDN, &sdn;;
|
|
|
7e63d6 |
+ /* Get the target SDN */
|
|
|
7e63d6 |
+ err = slapi_pblock_get(pb, SLAPI_MODIFY_TARGET_SDN, &targetSDN);
|
|
|
7e63d6 |
if (err) {
|
|
|
7e63d6 |
result = uid_op_error(11);
|
|
|
7e63d6 |
break;
|
|
|
7e63d6 |
@@ -1197,7 +1197,7 @@ preop_modify(Slapi_PBlock *pb)
|
|
|
7e63d6 |
* Check if it has the required object class
|
|
|
7e63d6 |
*/
|
|
|
7e63d6 |
if (requiredObjectClass &&
|
|
|
7e63d6 |
- !(spb = dnHasObjectClass(sdn, requiredObjectClass))) {
|
|
|
7e63d6 |
+ !(spb = dnHasObjectClass(targetSDN, requiredObjectClass))) {
|
|
|
7e63d6 |
break;
|
|
|
7e63d6 |
}
|
|
|
7e63d6 |
|
|
|
7e63d6 |
@@ -1213,13 +1213,13 @@ preop_modify(Slapi_PBlock *pb)
|
|
|
7e63d6 |
mod = checkmods[ii];
|
|
|
7e63d6 |
if (NULL != markerObjectClass) {
|
|
|
7e63d6 |
/* Subtree defined by location of marker object class */
|
|
|
7e63d6 |
- result = findSubtreeAndSearch(sdn, attrNames, NULL,
|
|
|
7e63d6 |
+ result = findSubtreeAndSearch(targetSDN, attrNames, NULL,
|
|
|
7e63d6 |
mod->mod_bvalues, requiredObjectClass,
|
|
|
7e63d6 |
- sdn, markerObjectClass, config->exclude_subtrees);
|
|
|
7e63d6 |
+ targetSDN, markerObjectClass, config->exclude_subtrees);
|
|
|
7e63d6 |
} else {
|
|
|
7e63d6 |
/* Subtrees listed on invocation line */
|
|
|
7e63d6 |
result = searchAllSubtrees(config->subtrees, config->exclude_subtrees, attrNames, NULL,
|
|
|
7e63d6 |
- mod->mod_bvalues, requiredObjectClass, sdn, config->unique_in_all_subtrees);
|
|
|
7e63d6 |
+ mod->mod_bvalues, requiredObjectClass, targetSDN, targetSDN, config->unique_in_all_subtrees);
|
|
|
7e63d6 |
}
|
|
|
7e63d6 |
}
|
|
|
7e63d6 |
END
|
|
|
7e63d6 |
@@ -1271,8 +1271,8 @@ preop_modrdn(Slapi_PBlock *pb)
|
|
|
7e63d6 |
int err;
|
|
|
7e63d6 |
char *markerObjectClass = NULL;
|
|
|
7e63d6 |
char *requiredObjectClass = NULL;
|
|
|
7e63d6 |
- Slapi_DN *sdn = NULL;
|
|
|
7e63d6 |
- Slapi_DN *superior;
|
|
|
7e63d6 |
+ Slapi_DN *sourceSDN = NULL;
|
|
|
7e63d6 |
+ Slapi_DN *destinationSDN;
|
|
|
7e63d6 |
char *rdn;
|
|
|
7e63d6 |
int deloldrdn = 0;
|
|
|
7e63d6 |
int isupdatedn;
|
|
|
7e63d6 |
@@ -1311,14 +1311,14 @@ preop_modrdn(Slapi_PBlock *pb)
|
|
|
7e63d6 |
}
|
|
|
7e63d6 |
|
|
|
7e63d6 |
/* Get the DN of the entry being renamed */
|
|
|
7e63d6 |
- err = slapi_pblock_get(pb, SLAPI_MODRDN_TARGET_SDN, &sdn;;
|
|
|
7e63d6 |
+ err = slapi_pblock_get(pb, SLAPI_MODRDN_TARGET_SDN, &sourceSDN);
|
|
|
7e63d6 |
if (err) {
|
|
|
7e63d6 |
result = uid_op_error(31);
|
|
|
7e63d6 |
break;
|
|
|
7e63d6 |
}
|
|
|
7e63d6 |
|
|
|
7e63d6 |
/* Get superior value - unimplemented in 3.0/4.0/5.0 DS */
|
|
|
7e63d6 |
- err = slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &superior);
|
|
|
7e63d6 |
+ err = slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &destinationSDN);
|
|
|
7e63d6 |
if (err) {
|
|
|
7e63d6 |
result = uid_op_error(32);
|
|
|
7e63d6 |
break;
|
|
|
7e63d6 |
@@ -1326,11 +1326,11 @@ preop_modrdn(Slapi_PBlock *pb)
|
|
|
7e63d6 |
|
|
|
7e63d6 |
/*
|
|
|
7e63d6 |
* No superior means the entry is just renamed at
|
|
|
7e63d6 |
- * its current level in the tree. Use the target DN for
|
|
|
7e63d6 |
+ * its current level in the tree. Use the source SDN for
|
|
|
7e63d6 |
* determining which managed tree this belongs to
|
|
|
7e63d6 |
*/
|
|
|
7e63d6 |
- if (!superior)
|
|
|
7e63d6 |
- superior = sdn;
|
|
|
7e63d6 |
+ if (!destinationSDN)
|
|
|
7e63d6 |
+ slapi_sdn_get_parent(sourceSDN, destinationSDN);
|
|
|
7e63d6 |
|
|
|
7e63d6 |
/* Get the new RDN - this has the attribute values */
|
|
|
7e63d6 |
err = slapi_pblock_get(pb, SLAPI_MODRDN_NEWRDN, &rdn;;
|
|
|
7e63d6 |
@@ -1352,10 +1352,10 @@ preop_modrdn(Slapi_PBlock *pb)
|
|
|
7e63d6 |
|
|
|
7e63d6 |
/* Get the entry that is being renamed so we can make a dummy copy
|
|
|
7e63d6 |
* of what it will look like after the rename. */
|
|
|
7e63d6 |
- err = slapi_search_get_entry(&entry_pb, sdn, NULL, &e, plugin_identity);
|
|
|
7e63d6 |
+ err = slapi_search_get_entry(&entry_pb, sourceSDN, NULL, &e, plugin_identity);
|
|
|
7e63d6 |
if (err != LDAP_SUCCESS) {
|
|
|
7e63d6 |
result = uid_op_error(35);
|
|
|
7e63d6 |
- /* We want to return a no such object error if the target doesn't exist. */
|
|
|
7e63d6 |
+ /* We want to return a no such object error if the source SDN doesn't exist. */
|
|
|
7e63d6 |
if (err == LDAP_NO_SUCH_OBJECT) {
|
|
|
7e63d6 |
result = err;
|
|
|
7e63d6 |
}
|
|
|
7e63d6 |
@@ -1364,7 +1364,7 @@ preop_modrdn(Slapi_PBlock *pb)
|
|
|
7e63d6 |
|
|
|
7e63d6 |
/* Apply the rename operation to the dummy entry. */
|
|
|
7e63d6 |
/* slapi_entry_rename does not expect rdn normalized */
|
|
|
7e63d6 |
- err = slapi_entry_rename(e, rdn, deloldrdn, superior);
|
|
|
7e63d6 |
+ err = slapi_entry_rename(e, rdn, deloldrdn, destinationSDN);
|
|
|
7e63d6 |
if (err != LDAP_SUCCESS) {
|
|
|
7e63d6 |
result = uid_op_error(36);
|
|
|
7e63d6 |
break;
|
|
|
7e63d6 |
@@ -1392,13 +1392,13 @@ preop_modrdn(Slapi_PBlock *pb)
|
|
|
7e63d6 |
*/
|
|
|
7e63d6 |
if (NULL != markerObjectClass) {
|
|
|
7e63d6 |
/* Subtree defined by location of marker object class */
|
|
|
7e63d6 |
- result = findSubtreeAndSearch(slapi_entry_get_sdn(e), attrNames, attr, NULL,
|
|
|
7e63d6 |
- requiredObjectClass, superior,
|
|
|
7e63d6 |
+ result = findSubtreeAndSearch(destinationSDN, attrNames, attr, NULL,
|
|
|
7e63d6 |
+ requiredObjectClass, sourceSDN,
|
|
|
7e63d6 |
markerObjectClass, config->exclude_subtrees);
|
|
|
7e63d6 |
} else {
|
|
|
7e63d6 |
/* Subtrees listed on invocation line */
|
|
|
7e63d6 |
result = searchAllSubtrees(config->subtrees, config->exclude_subtrees, attrNames, attr, NULL,
|
|
|
7e63d6 |
- requiredObjectClass, superior, config->unique_in_all_subtrees);
|
|
|
7e63d6 |
+ requiredObjectClass, destinationSDN, sourceSDN, config->unique_in_all_subtrees);
|
|
|
7e63d6 |
}
|
|
|
7e63d6 |
if (result != LDAP_SUCCESS) {
|
|
|
7e63d6 |
break;
|
|
|
7e63d6 |
--
|
|
|
7e63d6 |
2.31.1
|
|
|
7e63d6 |
|