[Fedora-directory-commits] ldapserver/ldap/servers/plugins/replication windows_connection.c, 1.12, 1.13 windows_protocol_util.c, 1.23, 1.24

Nathan Kinder (nkinder) fedora-directory-commits at redhat.com
Mon Feb 20 19:36:32 UTC 2006


Author: nkinder

Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/replication
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv26379

Modified Files:
	windows_connection.c windows_protocol_util.c 
Log Message:
Bug(s) fixed: 181827
Bug Description: If you delete an attribute from an entry on AD, the attribute
   doesn't get deleted on the DS side.  The replication code doesn't even notice
   that the entry changed.
Reviewed by: Rich, Noriko, Pete (thanks!)
Files: see diffs
Branch: HEAD, Directory71Branch
Fix Description: The dirsync search control passes back deleted attributes with no
   values.  If you try to add a Slapi_Attr with no values to a Slapi_Entry, it doesn't
   get added.    This fix stuffs the deleted attributes into the deleted attributes list
   in the Slapi_Entry and checks for them when creating the modification
   operations to be performed on the local entry.
Flag Day: no
Doc impact: no
QA impact: A regression test needs to be added
New Tests integrated into TET: none



Index: windows_connection.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/replication/windows_connection.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- windows_connection.c	27 Oct 2005 19:09:07 -0000	1.12
+++ windows_connection.c	20 Feb 2006 19:36:24 -0000	1.13
@@ -557,7 +557,19 @@
 				{
 					type_to_use = a;
 				}
-				slapi_entry_add_values( e, type_to_use, aVal);
+
+				/* If the list of attribute values is null, we need to delete this attribute
+				 * from the local entry.
+                                 */
+				if (aVal == NULL) {
+					/* Windows will send us an attribute with no values if it was deleted
+					 * on the AD side.  Add this attribute to the deleted attributes list */
+					Slapi_Attr *attr = slapi_attr_new();
+					slapi_attr_init(attr, type_to_use);
+					entry_add_deleted_attribute_wsi(e, attr);
+				} else { 
+					slapi_entry_add_values( e, type_to_use, aVal);
+				} 
                 
 				ldap_memfree(a);
 				ldap_value_free_len(aVal);


Index: windows_protocol_util.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/replication/windows_protocol_util.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- windows_protocol_util.c	22 Nov 2005 03:40:08 -0000	1.23
+++ windows_protocol_util.c	20 Feb 2006 19:36:24 -0000	1.24
@@ -2496,6 +2496,7 @@
 {
 	int retval = 0;
 	Slapi_Attr *attr = NULL;
+	Slapi_Attr *del_attr = NULL;
 	int is_user = 0;
 	int is_group = 0;
 	int rc = 0;
@@ -2638,17 +2639,48 @@
 				*do_modify = 1;
 			}
 		}
+
 		if (vs) 
 		{
 			slapi_valueset_free(vs);
 			vs = NULL;
 		}
-		if (local_type)
-		{
-			slapi_ch_free((void**)&local_type);
-			local_type = NULL;
-		}
+
+		slapi_ch_free_string(&local_type);
 	}
+
+        /* Check if any attributes were deleted from the remote entry */
+        entry_first_deleted_attribute(remote_entry, &del_attr);
+        while (del_attr != NULL) {
+                Slapi_Attr *local_attr = NULL;
+                char *type = NULL;
+                char *local_type = NULL;
+                int mapdn = 0;
+
+                /* Map remote type to local type */
+		slapi_attr_get_type(del_attr, &type);
+                if ( is_straight_mapped_attr(type,is_user,is_nt4) ) {
+                        local_type = slapi_ch_strdup(type);
+                } else {
+                        windows_map_attr_name(type , to_windows, is_user, 0 /* not create */, &local_type, &mapdn);
+                }
+
+                /* Check if this attr exists in the local entry */
+                if (local_type) {
+                        slapi_entry_attr_find(local_entry, local_type, &local_attr);
+                        if (local_attr) {
+                                slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,
+                                        "windows_generate_update_mods: deleting %s attribute from local entry\n", local_type);
+                                /* Delete this attr from the local entry */
+                                slapi_mods_add_mod_values(smods, LDAP_MOD_DELETE, local_type, NULL);
+				*do_modify = 1;
+                        }
+                }
+
+                entry_next_deleted_attribute(remote_entry, &del_attr);
+		slapi_ch_free_string(&local_type);
+        }
+
 	if (slapi_is_loglevel_set(SLAPI_LOG_REPL) && *do_modify)
 	{
 		slapi_mods_dump(smods,"windows sync");
@@ -2669,14 +2701,18 @@
 	/* Now perform the modify if we need to */
 	if (0 == retval && do_modify)
 	{
+		char dnbuf[BUFSIZ];
+		char *dn = slapi_sdn_get_dn(slapi_entry_get_sdn_const(remote_entry));
 		slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,
-			"windows_update_remote_entry: modifying entry %s\n", slapi_sdn_get_dn(slapi_entry_get_sdn_const(remote_entry)));
+			"windows_update_remote_entry: modifying entry %s\n", escape_string(dn, dnbuf));
 
 		retval = windows_conn_send_modify(prp->conn, slapi_sdn_get_dn(slapi_entry_get_sdn_const(remote_entry)),slapi_mods_get_ldapmods_byref(&smods), NULL,NULL);
 	} else
 	{
+		char dnbuf[BUFSIZ];
+		char *dn = slapi_sdn_get_dn(slapi_entry_get_sdn_const(remote_entry));
 		slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,
-			"no mods generated for entry: %s\n", slapi_sdn_get_dn(slapi_entry_get_sdn_const(remote_entry)));
+			"no mods generated for remote entry: %s\n", escape_string(dn, dnbuf));
 	}
     slapi_mods_done(&smods);
 	return retval;
@@ -2701,8 +2737,10 @@
 		pb = slapi_pblock_new();
 		if (pb)
 		{
+			char dnbuf[BUFSIZ];
+			char *dn = slapi_sdn_get_dn(slapi_entry_get_sdn_const(local_entry));
 			slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,
-				"modifying entry: %s\n", slapi_sdn_get_dn(slapi_entry_get_sdn_const(local_entry)));
+				"modifying entry: %s\n", escape_string(dn, dnbuf));
 			slapi_modify_internal_set_pb (pb, slapi_entry_get_ndn(local_entry), slapi_mods_get_ldapmods_byref(&smods), NULL, NULL,
 					repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
 			slapi_modify_internal_pb (pb);		
@@ -2710,7 +2748,7 @@
 			if (rc) 
 			{
 				slapi_log_error(SLAPI_LOG_FATAL, windows_repl_plugin_name,
-					"windows_update_local_entry: failed to modify entry %s\n", slapi_sdn_get_dn(slapi_entry_get_sdn_const(local_entry)));
+					"windows_update_local_entry: failed to modify entry %s\n", escape_string(dn, dnbuf));
 			}
 			slapi_pblock_destroy(pb);
 		} else 
@@ -2721,8 +2759,10 @@
 
 	} else
 	{
+		char dnbuf[BUFSIZ];
+		char *dn = slapi_sdn_get_dn(slapi_entry_get_sdn_const(local_entry));
 		slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,
-			"no mods generated for entry: %s\n", slapi_sdn_get_dn(slapi_entry_get_sdn_const(remote_entry)));
+			"no mods generated for local entry: %s\n", escape_string(dn, dnbuf));
 	}
     slapi_mods_done(&smods);
 	return retval;
@@ -2959,6 +2999,22 @@
 					windows_get_remote_entry(prp,slapi_entry_get_sdn_const(e),&remote_entry);
 					if (remote_entry)
 					{
+						/* We need to check for any deleted attrs from the dirsync entry
+						 * and pass them into the newly fetched remote entry. */
+						Slapi_Attr *attr = NULL;
+						Slapi_Attr *rem_attr = NULL;
+						entry_first_deleted_attribute(e, &attr);
+						while (attr != NULL) {
+							/* We need to dup the attr and add it to the remote entry.
+							 * rem_attr is now owned by remote_entry, so don't free it */
+							rem_attr = slapi_attr_dup(attr);
+							if (rem_attr) {
+								entry_add_deleted_attribute_wsi(remote_entry, rem_attr);
+								rem_attr = NULL;
+							}
+							entry_next_deleted_attribute(e, &attr);
+						}
+
 						rc = windows_update_local_entry(prp, remote_entry, local_entry);
 						slapi_entry_free(remote_entry);
 						remote_entry = NULL;




More information about the Fedora-directory-commits mailing list