浏览代码

Resolves: bug 457846
Bug Description: The Windows Sync API should have plug-in points - part 2
Reviewed by: nkinder (Thanks!)
Fix Description: Some additional changes to the api
The modify callbacks were not sufficient to handle all cases. We need to have access to the DS entry. This changes the API to add the DS entry to the modify callbacks. I also had to change the handling of the userAccountControl - it cannot just overwrite the value, it must set the appropriate bit in the bit mask.
Platforms tested: RHEL5
Flag Day: no
Doc impact: yes - plugin guide

Rich Megginson 17 年之前
父节点
当前提交
433007641e

+ 8 - 4
ldap/servers/plugins/replication/windows_private.c

@@ -1141,7 +1141,9 @@ winsync_plugin_call_get_new_ds_group_dn_cb(const Repl_Agmt *ra, const Slapi_Entr
 
 
 void
 void
 winsync_plugin_call_pre_ad_mod_user_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
 winsync_plugin_call_pre_ad_mod_user_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
-                                            const Slapi_DN *local_dn, LDAPMod * const *origmods,
+                                            const Slapi_DN *local_dn,
+                                            const Slapi_Entry *ds_entry,
+                                            LDAPMod * const *origmods,
                                             Slapi_DN *remote_dn, LDAPMod ***modstosend)
                                             Slapi_DN *remote_dn, LDAPMod ***modstosend)
 {
 {
     winsync_pre_ad_mod_mods_cb thefunc =
     winsync_pre_ad_mod_mods_cb thefunc =
@@ -1154,14 +1156,16 @@ winsync_plugin_call_pre_ad_mod_user_mods_cb(const Repl_Agmt *ra, const Slapi_Ent
     }
     }
 
 
     (*thefunc)(windows_private_get_api_cookie(ra), rawentry, local_dn,
     (*thefunc)(windows_private_get_api_cookie(ra), rawentry, local_dn,
-               origmods, remote_dn, modstosend);
+               ds_entry, origmods, remote_dn, modstosend);
 
 
     return;
     return;
 }
 }
 
 
 void
 void
 winsync_plugin_call_pre_ad_mod_group_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
 winsync_plugin_call_pre_ad_mod_group_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry,
-                                             const Slapi_DN *local_dn, LDAPMod * const *origmods,
+                                             const Slapi_DN *local_dn,
+                                             const Slapi_Entry *ds_entry,
+                                             LDAPMod * const *origmods,
                                              Slapi_DN *remote_dn, LDAPMod ***modstosend)
                                              Slapi_DN *remote_dn, LDAPMod ***modstosend)
 {
 {
     winsync_pre_ad_mod_mods_cb thefunc =
     winsync_pre_ad_mod_mods_cb thefunc =
@@ -1174,7 +1178,7 @@ winsync_plugin_call_pre_ad_mod_group_mods_cb(const Repl_Agmt *ra, const Slapi_En
     }
     }
 
 
     (*thefunc)(windows_private_get_api_cookie(ra), rawentry, local_dn,
     (*thefunc)(windows_private_get_api_cookie(ra), rawentry, local_dn,
-               origmods, remote_dn, modstosend);
+               ds_entry, origmods, remote_dn, modstosend);
 
 
     return;
     return;
 }
 }

+ 18 - 1
ldap/servers/plugins/replication/windows_protocol_util.c

@@ -810,9 +810,24 @@ send_accountcontrol_modify(Slapi_DN *sdn, Private_Repl_Protocol *prp)
 {
 {
 	ConnResult mod_return = 0;
 	ConnResult mod_return = 0;
 	Slapi_Mods smods = {0};
 	Slapi_Mods smods = {0};
+	Slapi_Entry *remote_entry = NULL;
+	int retval;
+	unsigned long acctval = 0;
+	char acctvalstr[32];
+
+	/* have to first retrieve the existing entry - userAccountControl is
+	   a bit array, and we must preserve the existing values if any */
+	/* Get the remote entry */
+	retval = windows_get_remote_entry(prp, sdn, &remote_entry);
+	if (0 == retval && remote_entry) {
+		acctval = slapi_entry_attr_get_ulong(remote_entry, "userAccountControl");
+	}
+	slapi_entry_free(remote_entry);
+	acctval |= 0x0200; /* normal account == 512 */
 
 
     slapi_mods_init (&smods, 0);
     slapi_mods_init (&smods, 0);
-	slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "userAccountControl", "512");
+	PR_snprintf(acctvalstr, sizeof(acctvalstr), "%lu", acctval);
+	slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "userAccountControl", acctvalstr);
 
 
 	mod_return = windows_conn_send_modify(prp->conn, slapi_sdn_get_dn(sdn), slapi_mods_get_ldapmods_byref(&smods), NULL, NULL );
 	mod_return = windows_conn_send_modify(prp->conn, slapi_sdn_get_dn(sdn), slapi_mods_get_ldapmods_byref(&smods), NULL, NULL );
 
 
@@ -1209,6 +1224,7 @@ windows_replay_update(Private_Repl_Protocol *prp, slapi_operation_parameters *op
 					winsync_plugin_call_pre_ad_mod_user_mods_cb(prp->agmt,
 					winsync_plugin_call_pre_ad_mod_user_mods_cb(prp->agmt,
 																windows_private_get_raw_entry(prp->agmt),
 																windows_private_get_raw_entry(prp->agmt),
 																local_dn,
 																local_dn,
+																local_entry,
 																op->p.p_modify.modify_mods,
 																op->p.p_modify.modify_mods,
 																remote_dn,
 																remote_dn,
 																&mapped_mods);
 																&mapped_mods);
@@ -1216,6 +1232,7 @@ windows_replay_update(Private_Repl_Protocol *prp, slapi_operation_parameters *op
 					winsync_plugin_call_pre_ad_mod_group_mods_cb(prp->agmt,
 					winsync_plugin_call_pre_ad_mod_group_mods_cb(prp->agmt,
 																 windows_private_get_raw_entry(prp->agmt),
 																 windows_private_get_raw_entry(prp->agmt),
 																 local_dn,
 																 local_dn,
+																 local_entry,
 																 op->p.p_modify.modify_mods,
 																 op->p.p_modify.modify_mods,
 																 remote_dn,
 																 remote_dn,
 																 &mapped_mods);
 																 &mapped_mods);

+ 2 - 3
ldap/servers/plugins/replication/windowsrepl.h

@@ -149,8 +149,8 @@ void winsync_plugin_call_get_new_ds_user_dn_cb(const Repl_Agmt *ra, const Slapi_
 void winsync_plugin_call_get_new_ds_group_dn_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry,
 void winsync_plugin_call_get_new_ds_group_dn_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, Slapi_Entry *ad_entry,
                                                 char **new_dn_string, const Slapi_DN *ds_suffix, const Slapi_DN *ad_suffix);
                                                 char **new_dn_string, const Slapi_DN *ds_suffix, const Slapi_DN *ad_suffix);
 
 
-void winsync_plugin_call_pre_ad_mod_user_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, LDAPMod * const *origmods, Slapi_DN *remote_dn, LDAPMod ***modstosend);
-void winsync_plugin_call_pre_ad_mod_group_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, LDAPMod * const *origmods, Slapi_DN *remote_dn, LDAPMod ***modstosend);
+void winsync_plugin_call_pre_ad_mod_user_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, const Slapi_Entry *ds_entry, LDAPMod * const *origmods, Slapi_DN *remote_dn, LDAPMod ***modstosend);
+void winsync_plugin_call_pre_ad_mod_group_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, const Slapi_Entry *ds_entry, LDAPMod * const *origmods, Slapi_DN *remote_dn, LDAPMod ***modstosend);
 
 
 int winsync_plugin_call_can_add_entry_to_ad_cb(const Repl_Agmt *ra, const Slapi_Entry *local_entry, const Slapi_DN *remote_dn);
 int winsync_plugin_call_can_add_entry_to_ad_cb(const Repl_Agmt *ra, const Slapi_Entry *local_entry, const Slapi_DN *remote_dn);
 void winsync_plugin_call_begin_update_cb(const Repl_Agmt *ra, const Slapi_DN *ds_subtree,
 void winsync_plugin_call_begin_update_cb(const Repl_Agmt *ra, const Slapi_DN *ds_subtree,
@@ -210,4 +210,3 @@ void winsync_plugin_call_destroy_agmt_cb(const Repl_Agmt *ra,
   ++send_updates
   ++send_updates
   ++++windows_replay_update
   ++++windows_replay_update
 */
 */
-/* #define WINSYNC_TEST 1 */ /* fake ad is really just a regular ds */

+ 5 - 2
ldap/servers/plugins/replication/winsync-plugin.h

@@ -139,8 +139,9 @@ typedef void (*winsync_get_new_dn_cb)(void *cookie, const Slapi_Entry *rawentry,
  * to AD.  This case is different than the pre add or pre mod callbacks
  * to AD.  This case is different than the pre add or pre mod callbacks
  * above because in this context, we may only have the list of modifications
  * above because in this context, we may only have the list of modifications
  * and the DN to which the mods were applied.
  * and the DN to which the mods were applied.
- * rawentry  - the raw AD entry, read directly from AD - may be NULL
+ * rawentry - the raw AD entry, read directly from AD - may be NULL
  * local_dn - the original local DN used in the modification
  * local_dn - the original local DN used in the modification
+ * ds_entry - the current DS entry that has the operation nsUniqueID
  * origmods - the original mod list
  * origmods - the original mod list
  * remote_dn - this is the DN which will be used with the remote modify operation
  * remote_dn - this is the DN which will be used with the remote modify operation
  *             to AD - the winsync code may have already attempted to calculate its value
  *             to AD - the winsync code may have already attempted to calculate its value
@@ -148,7 +149,7 @@ typedef void (*winsync_get_new_dn_cb)(void *cookie, const Slapi_Entry *rawentry,
  *              code will already have done its default mapping to these values
  *              code will already have done its default mapping to these values
  * 
  * 
  */
  */
-typedef void (*winsync_pre_ad_mod_mods_cb)(void *cookie, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, LDAPMod * const *origmods, Slapi_DN *remote_dn, LDAPMod ***modstosend);
+typedef void (*winsync_pre_ad_mod_mods_cb)(void *cookie, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, const Slapi_Entry *ds_entry, LDAPMod * const *origmods, Slapi_DN *remote_dn, LDAPMod ***modstosend);
 #define WINSYNC_PLUGIN_PRE_AD_MOD_USER_MODS_CB 14
 #define WINSYNC_PLUGIN_PRE_AD_MOD_USER_MODS_CB 14
 #define WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_MODS_CB 15
 #define WINSYNC_PLUGIN_PRE_AD_MOD_GROUP_MODS_CB 15
 
 
@@ -403,6 +404,7 @@ test_winsync_get_new_ds_group_dn_cb(void *cbdata, const Slapi_Entry *rawentry,
 
 
 static void
 static void
 test_winsync_pre_ad_mod_user_mods_cb(void *cbdata, const Slapi_Entry *rawentry,
 test_winsync_pre_ad_mod_user_mods_cb(void *cbdata, const Slapi_Entry *rawentry,
+                                     const Slapi_Entry *ds_entry,
                                      const Slapi_DN *local_dn, LDAPMod * const *origmods,
                                      const Slapi_DN *local_dn, LDAPMod * const *origmods,
                                      Slapi_DN *remote_dn, LDAPMod ***modstosend)
                                      Slapi_DN *remote_dn, LDAPMod ***modstosend)
 {
 {
@@ -417,6 +419,7 @@ test_winsync_pre_ad_mod_user_mods_cb(void *cbdata, const Slapi_Entry *rawentry,
 
 
 static void
 static void
 test_winsync_pre_ad_mod_group_mods_cb(void *cbdata, const Slapi_Entry *rawentry,
 test_winsync_pre_ad_mod_group_mods_cb(void *cbdata, const Slapi_Entry *rawentry,
+                                     const Slapi_Entry *ds_entry,
                                      const Slapi_DN *local_dn, LDAPMod * const *origmods,
                                      const Slapi_DN *local_dn, LDAPMod * const *origmods,
                                      Slapi_DN *remote_dn, LDAPMod ***modstosend)
                                      Slapi_DN *remote_dn, LDAPMod ***modstosend)
 {
 {