summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Kinder <nkinder@redhat.com>2006-02-20 19:36:24 +0000
committerNathan Kinder <nkinder@redhat.com>2006-02-20 19:36:24 +0000
commit836e08dc192bd3a9c8a10c3869c5efc48bf13024 (patch)
treeca230d96283b8c964a10e739b045956baf6ad585
parentfb511a7f2c7c628b0ee2dc15ebcdded807e199ba (diff)
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
-rw-r--r--ldap/servers/plugins/replication/windows_connection.c14
-rw-r--r--ldap/servers/plugins/replication/windows_protocol_util.c78
2 files changed, 80 insertions, 12 deletions
diff --git a/ldap/servers/plugins/replication/windows_connection.c b/ldap/servers/plugins/replication/windows_connection.c
index 58408a49..4583c102 100644
--- a/ldap/servers/plugins/replication/windows_connection.c
+++ b/ldap/servers/plugins/replication/windows_connection.c
@@ -557,7 +557,19 @@ windows_LDAPMessage2Entry(LDAP * ld, LDAPMessage * msg, int attrsonly) {
{
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);
diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c
index 827f7ab8..e3227f89 100644
--- a/ldap/servers/plugins/replication/windows_protocol_util.c
+++ b/ldap/servers/plugins/replication/windows_protocol_util.c
@@ -2496,6 +2496,7 @@ windows_generate_update_mods(Private_Repl_Protocol *prp,Slapi_Entry *remote_entr
{
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 @@ windows_generate_update_mods(Private_Repl_Protocol *prp,Slapi_Entry *remote_entr
*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 @@ windows_update_remote_entry(Private_Repl_Protocol *prp,Slapi_Entry *remote_entry
/* 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 @@ windows_update_local_entry(Private_Repl_Protocol *prp,Slapi_Entry *remote_entry,
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 @@ windows_update_local_entry(Private_Repl_Protocol *prp,Slapi_Entry *remote_entry,
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 @@ windows_update_local_entry(Private_Repl_Protocol *prp,Slapi_Entry *remote_entry,
} 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_process_dirsync_entry(Private_Repl_Protocol *prp,Slapi_Entry *e, int is_
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;