Skip to content

Commit

Permalink
Issue 4894 - IPA failure in ipa user-del --preserve (#4907)
Browse files Browse the repository at this point in the history
Bug Description: Starting with 389-ds 2.0.8 on rawhide,
any call to ipa user-del --preserve fails with
This entry already exists.

Fix Description: We should split 'dn' parameter in searchAllSubtrees
into parent and target. As one of them is used for excluding the
subtree checks and another one for searching.
Improve 'superior' processing when we don't change the parent.
Rename variables in a more sane way.

Fixes: #4894

Reviewed by: @Firstyear, @tbordaz, @progier389 (Thanks!)
  • Loading branch information
droideck committed Sep 10, 2021
1 parent 4173918 commit 57b6480
Showing 1 changed file with 39 additions and 39 deletions.
78 changes: 39 additions & 39 deletions ldap/servers/plugins/uiduniq/uid.c
Expand Up @@ -770,13 +770,13 @@ search_one_berval(Slapi_DN *baseDN, const char **attrNames, const struct berval
*
* Return:
* LDAP_SUCCESS - no matches, or the attribute matches the
* target dn.
* source (target) dn.
* LDAP_CONSTRAINT_VIOLATION - an entry was found that already
* contains the attribute value.
* LDAP_OPERATIONS_ERROR - a server failure.
*/
static int
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)
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)
{
int result = LDAP_SUCCESS;
int i;
Expand All @@ -788,12 +788,12 @@ searchAllSubtrees(Slapi_DN **subtrees, Slapi_DN **exclude_subtrees, const char *
* are unique in all the monitored subtrees
*/

/* First check the target entry is in one of
/* First check the destination entry is in one of
* the monitored subtree, so adding 'values' would
* violate constraint
*/
for (i = 0; subtrees && subtrees[i]; i++) {
if (slapi_sdn_issuffix(dn, subtrees[i])) {
if (slapi_sdn_issuffix(destinationSDN, subtrees[i])) {
in_a_subtree = PR_TRUE;
break;
}
Expand All @@ -808,7 +808,7 @@ searchAllSubtrees(Slapi_DN **subtrees, Slapi_DN **exclude_subtrees, const char *
if (exclude_subtrees != NULL) {
PRBool in_a_subtree = PR_FALSE;
for (i = 0; exclude_subtrees && exclude_subtrees[i]; i++) {
if (slapi_sdn_issuffix(dn, exclude_subtrees[i])) {
if (slapi_sdn_issuffix(destinationSDN, exclude_subtrees[i])) {
in_a_subtree = PR_TRUE;
break;
}
Expand All @@ -820,16 +820,16 @@ searchAllSubtrees(Slapi_DN **subtrees, Slapi_DN **exclude_subtrees, const char *

/*
* For each DN in the managed list, do uniqueness checking if
* the target DN is a subnode in the tree.
* the destination (target) DN is a subnode in the tree.
*/
for (i = 0; subtrees && subtrees[i]; i++) {
Slapi_DN *sufdn = subtrees[i];
/*
* The DN should already be normalized, so we don't have to
* worry about that here.
*/
if (unique_in_all_subtrees || slapi_sdn_issuffix(dn, sufdn)) {
result = search(sufdn, attrNames, attr, values, requiredObjectClass, dn, exclude_subtrees);
if (unique_in_all_subtrees || slapi_sdn_issuffix(destinationSDN, sufdn)) {
result = search(sufdn, attrNames, attr, values, requiredObjectClass, sourceSDN, exclude_subtrees);
if (result)
break;
}
Expand Down Expand Up @@ -903,20 +903,20 @@ getArguments(Slapi_PBlock *pb, char **attrName, char **markerObjectClass, char *
*
* Return:
* LDAP_SUCCESS - no matches, or the attribute matches the
* target dn.
* source (target) dn.
* LDAP_CONSTRAINT_VIOLATION - an entry was found that already
* contains the attribute value.
* LDAP_OPERATIONS_ERROR - a server failure.
*/
static int
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)
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)
{
int result = LDAP_SUCCESS;
Slapi_PBlock *spb = NULL;
Slapi_DN *curpar = slapi_sdn_new();
Slapi_DN *newpar = NULL;

slapi_sdn_get_parent(parentDN, curpar);
slapi_sdn_get_parent(destinationSDN, curpar);
while (slapi_sdn_get_dn(curpar) != NULL) {
if ((spb = dnHasObjectClass(curpar, markerObjectClass))) {
freePblock(spb);
Expand All @@ -925,7 +925,7 @@ findSubtreeAndSearch(Slapi_DN *parentDN, const char **attrNames, Slapi_Attr *att
* to have the attribute already.
*/
result = search(curpar, attrNames, attr, values, requiredObjectClass,
target, excludes);
sourceSDN, excludes);
break;
}
newpar = slapi_sdn_new();
Expand Down Expand Up @@ -964,7 +964,7 @@ preop_add(Slapi_PBlock *pb)
int err;
char *markerObjectClass = NULL;
char *requiredObjectClass = NULL;
Slapi_DN *sdn = NULL;
Slapi_DN *targetSDN = NULL;
int isupdatedn;
Slapi_Entry *e;
Slapi_Attr *attr;
Expand Down Expand Up @@ -998,16 +998,16 @@ preop_add(Slapi_PBlock *pb)
attr_friendly = config->attr_friendly;

/*
* Get the target DN for this add operation
* Get the target SDN for this add operation
*/
err = slapi_pblock_get(pb, SLAPI_ADD_TARGET_SDN, &sdn);
err = slapi_pblock_get(pb, SLAPI_ADD_TARGET_SDN, &targetSDN);
if (err) {
result = uid_op_error(51);
break;
}

#ifdef DEBUG
slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name, "preop_add - ADD target=%s\n", slapi_sdn_get_dn(sdn));
slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name, "preop_add - ADD target=%s\n", slapi_sdn_get_dn(targetSDN));
#endif

/*
Expand Down Expand Up @@ -1040,13 +1040,13 @@ preop_add(Slapi_PBlock *pb)
*/
if (NULL != markerObjectClass) {
/* Subtree defined by location of marker object class */
result = findSubtreeAndSearch(sdn, attrNames, attr, NULL,
requiredObjectClass, sdn,
result = findSubtreeAndSearch(targetSDN, attrNames, attr, NULL,
requiredObjectClass, targetSDN,
markerObjectClass, config->exclude_subtrees);
} else {
/* Subtrees listed on invocation line */
result = searchAllSubtrees(config->subtrees, config->exclude_subtrees, attrNames, attr, NULL,
requiredObjectClass, sdn, config->unique_in_all_subtrees);
requiredObjectClass, targetSDN, targetSDN, config->unique_in_all_subtrees);
}
if (result != LDAP_SUCCESS) {
break;
Expand Down Expand Up @@ -1120,7 +1120,7 @@ preop_modify(Slapi_PBlock *pb)
int modcount = 0;
int ii;
LDAPMod *mod;
Slapi_DN *sdn = NULL;
Slapi_DN *targetSDN = NULL;
int isupdatedn;
int i = 0;

Expand Down Expand Up @@ -1186,8 +1186,8 @@ preop_modify(Slapi_PBlock *pb)
break; /* no mods to check, we are done */
}

/* Get the target DN */
err = slapi_pblock_get(pb, SLAPI_MODIFY_TARGET_SDN, &sdn);
/* Get the target SDN */
err = slapi_pblock_get(pb, SLAPI_MODIFY_TARGET_SDN, &targetSDN);
if (err) {
result = uid_op_error(11);
break;
Expand All @@ -1197,7 +1197,7 @@ preop_modify(Slapi_PBlock *pb)
* Check if it has the required object class
*/
if (requiredObjectClass &&
!(spb = dnHasObjectClass(sdn, requiredObjectClass))) {
!(spb = dnHasObjectClass(targetSDN, requiredObjectClass))) {
break;
}

Expand All @@ -1213,13 +1213,13 @@ preop_modify(Slapi_PBlock *pb)
mod = checkmods[ii];
if (NULL != markerObjectClass) {
/* Subtree defined by location of marker object class */
result = findSubtreeAndSearch(sdn, attrNames, NULL,
result = findSubtreeAndSearch(targetSDN, attrNames, NULL,
mod->mod_bvalues, requiredObjectClass,
sdn, markerObjectClass, config->exclude_subtrees);
targetSDN, markerObjectClass, config->exclude_subtrees);
} else {
/* Subtrees listed on invocation line */
result = searchAllSubtrees(config->subtrees, config->exclude_subtrees, attrNames, NULL,
mod->mod_bvalues, requiredObjectClass, sdn, config->unique_in_all_subtrees);
mod->mod_bvalues, requiredObjectClass, targetSDN, targetSDN, config->unique_in_all_subtrees);
}
}
END
Expand Down Expand Up @@ -1271,8 +1271,8 @@ preop_modrdn(Slapi_PBlock *pb)
int err;
char *markerObjectClass = NULL;
char *requiredObjectClass = NULL;
Slapi_DN *sdn = NULL;
Slapi_DN *superior;
Slapi_DN *sourceSDN = NULL;
Slapi_DN *destinationSDN;
char *rdn;
int deloldrdn = 0;
int isupdatedn;
Expand Down Expand Up @@ -1311,26 +1311,26 @@ preop_modrdn(Slapi_PBlock *pb)
}

/* Get the DN of the entry being renamed */
err = slapi_pblock_get(pb, SLAPI_MODRDN_TARGET_SDN, &sdn);
err = slapi_pblock_get(pb, SLAPI_MODRDN_TARGET_SDN, &sourceSDN);
if (err) {
result = uid_op_error(31);
break;
}

/* Get superior value - unimplemented in 3.0/4.0/5.0 DS */
err = slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &superior);
err = slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &destinationSDN);
if (err) {
result = uid_op_error(32);
break;
}

/*
* No superior means the entry is just renamed at
* its current level in the tree. Use the target DN for
* its current level in the tree. Use the source SDN for
* determining which managed tree this belongs to
*/
if (!superior)
superior = sdn;
if (!destinationSDN)
slapi_sdn_get_parent(sourceSDN, destinationSDN);

/* Get the new RDN - this has the attribute values */
err = slapi_pblock_get(pb, SLAPI_MODRDN_NEWRDN, &rdn);
Expand All @@ -1352,10 +1352,10 @@ preop_modrdn(Slapi_PBlock *pb)

/* Get the entry that is being renamed so we can make a dummy copy
* of what it will look like after the rename. */
err = slapi_search_get_entry(&entry_pb, sdn, NULL, &e, plugin_identity);
err = slapi_search_get_entry(&entry_pb, sourceSDN, NULL, &e, plugin_identity);
if (err != LDAP_SUCCESS) {
result = uid_op_error(35);
/* We want to return a no such object error if the target doesn't exist. */
/* We want to return a no such object error if the source SDN doesn't exist. */
if (err == LDAP_NO_SUCH_OBJECT) {
result = err;
}
Expand All @@ -1364,7 +1364,7 @@ preop_modrdn(Slapi_PBlock *pb)

/* Apply the rename operation to the dummy entry. */
/* slapi_entry_rename does not expect rdn normalized */
err = slapi_entry_rename(e, rdn, deloldrdn, superior);
err = slapi_entry_rename(e, rdn, deloldrdn, destinationSDN);
if (err != LDAP_SUCCESS) {
result = uid_op_error(36);
break;
Expand Down Expand Up @@ -1392,13 +1392,13 @@ preop_modrdn(Slapi_PBlock *pb)
*/
if (NULL != markerObjectClass) {
/* Subtree defined by location of marker object class */
result = findSubtreeAndSearch(slapi_entry_get_sdn(e), attrNames, attr, NULL,
requiredObjectClass, superior,
result = findSubtreeAndSearch(destinationSDN, attrNames, attr, NULL,
requiredObjectClass, sourceSDN,
markerObjectClass, config->exclude_subtrees);
} else {
/* Subtrees listed on invocation line */
result = searchAllSubtrees(config->subtrees, config->exclude_subtrees, attrNames, attr, NULL,
requiredObjectClass, superior, config->unique_in_all_subtrees);
requiredObjectClass, destinationSDN, sourceSDN, config->unique_in_all_subtrees);
}
if (result != LDAP_SUCCESS) {
break;
Expand Down

0 comments on commit 57b6480

Please sign in to comment.