summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2010-01-25 15:05:59 -0800
committerNoriko Hosoi <nhosoi@redhat.com>2010-01-25 15:05:59 -0800
commit1a769808a6e169913be66ffbabc7f278594798a7 (patch)
tree01f228cc0ec70c77b763f9ac6dd1b067f708eb52
parent0e9fd8bc8205a46a6355555683e3fa0b014b4d03 (diff)
downloadds-1a769808a6e169913be66ffbabc7f278594798a7.tar.gz
ds-1a769808a6e169913be66ffbabc7f278594798a7.tar.xz
ds-1a769808a6e169913be66ffbabc7f278594798a7.zip
544089 - Referential Integrity Plugin does not take into account the attribute
subtypes Bug Description: Referential Integrity Plugin does not change the references in subtyped attributes like "manager;en" or "ou;19" Fix Description: The problem is in the way the function int update_integrity (char **argv, char *origDN, char *newrDN, int logChanges) in referint.c makes the changes. The initial search with the filter ldap_create_filter( filter, filtlen, "(%a=%e)", NULL, NULL, argv[i], origDN, NULL) finds the entries with attributes and with attribute subtypes. But after that when generating the necessary changes (attribute1.mod_type = argv[i] and attribute2.mod_type = argv[i]) the function takes care only of the "base" attributes listed in the plugin arguments. We should parse each found entry to find all the attribute subtypes with the value concerned and then make changes to them all. Note: This bug was reported by andrey.ivanov@polytechnique.fr, and the bug fix was also provided by him. The patch was reviewed by rmeggins@redhat.com as well as nhosoi@redhat.com.
-rw-r--r--ldap/servers/plugins/referint/referint.c152
1 files changed, 84 insertions, 68 deletions
diff --git a/ldap/servers/plugins/referint/referint.c b/ldap/servers/plugins/referint/referint.c
index 70fccd22..1c369825 100644
--- a/ldap/servers/plugins/referint/referint.c
+++ b/ldap/servers/plugins/referint/referint.c
@@ -317,6 +317,7 @@ int update_integrity(char **argv, char *origDN, char *newrDN, int logChanges){
Slapi_Entry **search_entries = NULL;
int search_result;
Slapi_DN *sdn = NULL;
+ Slapi_Value *oldDNslv = NULL;
void *node = NULL;
LDAPMod attribute1, attribute2;
const LDAPMod *list_of_mods[3];
@@ -338,6 +339,7 @@ int update_integrity(char **argv, char *origDN, char *newrDN, int logChanges){
goto free_and_return;
}
+ oldDNslv = slapi_value_new_string(origDN);
/* for now, just putting attributes to keep integrity on in conf file,
until resolve the other timing mode issue */
@@ -355,9 +357,9 @@ int update_integrity(char **argv, char *origDN, char *newrDN, int logChanges){
if (( search_result = ldap_create_filter( filter, filtlen, "(%a=%e)",
NULL, NULL, argv[i], origDN, NULL )) == LDAP_SUCCESS ) {
- /* Don't need any attribute */
+ /* Need only the current attribute and its subtypes */
char * attrs[2];
- attrs[0]="1.1";
+ attrs[0]=argv[i];
attrs[1]=NULL;
/* Use new search API */
@@ -378,76 +380,88 @@ int update_integrity(char **argv, char *origDN, char *newrDN, int logChanges){
for(j=0; search_entries[j] != NULL; j++)
{
- /* no matter what mode in always going to delete old dn so set that up */
- values_del[0]= origDN;
- values_del[1]= NULL;
- attribute1.mod_type = argv[i];
- attribute1.mod_op = LDAP_MOD_DELETE;
- attribute1.mod_values = values_del;
- list_of_mods[0] = &attribute1;
-
- if(newrDN == NULL){
- /* in delete mode so terminate list of mods cause this is the only one */
- list_of_mods[1] = NULL;
- }else if(newrDN != NULL){
- /* in modrdn mode */
-
- /* need to put together rdn into a dn */
- dnParts = ldap_explode_dn( origDN, 0 );
+ Slapi_Attr *attr = NULL;
+ char *attrName = NULL;
+
+ /* Loop over all the attributes of the entry and search for the integrity attribute and its subtypes */
+ for (slapi_entry_first_attr(search_entries[j], &attr); attr; slapi_entry_next_attr(search_entries[j], attr, &attr))
+ {
+ /* Take into account only the subtypes of the attribute in argv[i] having the necessary value - origDN */
+ slapi_attr_get_type(attr, &attrName);
+ if ((slapi_attr_type_cmp(argv[i], attrName, SLAPI_TYPE_CMP_SUBTYPE) == 0) &&
+ (slapi_attr_value_find(attr, slapi_value_get_berval(oldDNslv)) == 0))
+ {
+ /* no matter what mode in always going to delete old dn so set that up */
+ values_del[0]= origDN;
+ values_del[1]= NULL;
+ attribute1.mod_type = attrName;
+ attribute1.mod_op = LDAP_MOD_DELETE;
+ attribute1.mod_values = values_del;
+ list_of_mods[0] = &attribute1;
+
+ if(newrDN == NULL){
+ /* in delete mode so terminate list of mods cause this is the only one */
+ list_of_mods[1] = NULL;
+ }else if(newrDN != NULL){
+ /* in modrdn mode */
+
+ /* need to put together rdn into a dn */
+ dnParts = ldap_explode_dn( origDN, 0 );
- /* skip original rdn so start at 1*/
- dnsize = 0;
- for(x=1; dnParts[x] != NULL; x++)
- {
- /* +1 for comma adding later */
- dnsize += strlen(dnParts[x]) + 1;
- }
- /* add the newrDN length */
- dnsize += strlen(newrDN) + 1;
-
- newDN = slapi_ch_calloc(dnsize, sizeof(char));
- strcat(newDN, newrDN);
- for(x=1; dnParts[x] != NULL; x++)
- {
- strcat(newDN, ",");
- strcat(newDN, dnParts[x]);
- }
+ /* skip original rdn so start at 1*/
+ dnsize = 0;
+ for(x=1; dnParts[x] != NULL; x++)
+ {
+ /* +1 for comma adding later */
+ dnsize += strlen(dnParts[x]) + 1;
+ }
+ /* add the newrDN length */
+ dnsize += strlen(newrDN) + 1;
+
+ newDN = slapi_ch_calloc(dnsize, sizeof(char));
+ strcat(newDN, newrDN);
+ for(x=1; dnParts[x] != NULL; x++)
+ {
+ strcat(newDN, ",");
+ strcat(newDN, dnParts[x]);
+ }
- values_add[0]=newDN;
- values_add[1]=NULL;
- attribute2.mod_type = argv[i];
- attribute2.mod_op = LDAP_MOD_ADD;
- attribute2.mod_values = values_add;
-
- /* add the new dn to list of mods and terminate list of mods */
- list_of_mods[1] = &attribute2;
- list_of_mods[2] = NULL;
-
- }
-
- /* try to cleanup entry */
-
- /* Use new internal operation API */
- mod_result_pb=slapi_pblock_new();
- slapi_modify_internal_set_pb(mod_result_pb,slapi_entry_get_dn(search_entries[j]),
- (LDAPMod **)list_of_mods,NULL,NULL,referint_plugin_identity,0);
- slapi_modify_internal_pb(mod_result_pb);
-
- /* could check the result code here if want to log it or something later
- for now, continue no matter what result is */
-
- slapi_pblock_destroy(mod_result_pb);
-
- /* cleanup memory allocated for dnParts and newDN */
- if(dnParts != NULL){
- for(x=0; dnParts[x] != NULL; x++)
- {
- slapi_ch_free_string(&dnParts[x]);
+ values_add[0]=newDN;
+ values_add[1]=NULL;
+ attribute2.mod_type = attrName;
+ attribute2.mod_op = LDAP_MOD_ADD;
+ attribute2.mod_values = values_add;
+
+ /* add the new dn to list of mods and terminate list of mods */
+ list_of_mods[1] = &attribute2;
+ list_of_mods[2] = NULL;
+
+ }
+
+ /* try to cleanup entry */
+
+ /* Use new internal operation API */
+ mod_result_pb=slapi_pblock_new();
+ slapi_modify_internal_set_pb(mod_result_pb,slapi_entry_get_dn(search_entries[j]),
+ (LDAPMod **)list_of_mods,NULL,NULL,referint_plugin_identity,0);
+ slapi_modify_internal_pb(mod_result_pb);
+
+ /* could check the result code here if want to log it or something later
+ for now, continue no matter what result is */
+
+ slapi_pblock_destroy(mod_result_pb);
+
+ /* cleanup memory allocated for dnParts and newDN */
+ if(dnParts != NULL){
+ for(x=0; dnParts[x] != NULL; x++)
+ {
+ slapi_ch_free_string(&dnParts[x]);
+ }
+ slapi_ch_free((void **)&dnParts);
+ }
+ slapi_ch_free_string(&newDN);
}
- slapi_ch_free((void **)&dnParts);
}
- slapi_ch_free_string(&newDN);
-
}
@@ -480,6 +494,8 @@ int update_integrity(char **argv, char *origDN, char *newrDN, int logChanges){
free_and_return:
+ slapi_value_free(&oldDNslv);
+
/* free filter and search_results_pb */
slapi_ch_free_string(&filter);