summaryrefslogtreecommitdiffstats
path: root/ldap/servers/slapd/mapping_tree.c
diff options
context:
space:
mode:
authorNathan Kinder <nkinder@redhat.com>2010-04-08 15:55:29 -0700
committerNathan Kinder <nkinder@redhat.com>2010-04-09 07:49:03 -0700
commitc53b8b31c8655d8b387c4b213caee885778c3872 (patch)
tree67813a4f60b725162ac86f4aa9d4675af19365a0 /ldap/servers/slapd/mapping_tree.c
parentb433e4c852a2ef78558dffc1ccbaf464c1186934 (diff)
downloadds-c53b8b31c8655d8b387c4b213caee885778c3872.tar.gz
ds-c53b8b31c8655d8b387c4b213caee885778c3872.tar.xz
ds-c53b8b31c8655d8b387c4b213caee885778c3872.zip
Bug 578863 - Password modify extop needs to send referrals on replicas
The password modify extended operation was modifying the local database on a read-only replica instead of returning a referral. The server is designed to let the plugin ID used for updating password retry info make local updates instead of returning a referral. This plugin ID was being used by the password extop code, which it should not be doing. The second issue is that we need to check if a referral needs to be sent as early as possible when processing the extop request. We don't want to reject the change if an entry does not exist before checking if a referral is necessary since the server we refer to may have the target entry present. This required adding a new helper function that allows one to see if a write operation to a particular DN would require a referral to be sent. The password modify extop code leverages this new function to get the referrals and return them to the client if necessary.
Diffstat (limited to 'ldap/servers/slapd/mapping_tree.c')
-rw-r--r--ldap/servers/slapd/mapping_tree.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
index 8b4c541b..645618c2 100644
--- a/ldap/servers/slapd/mapping_tree.c
+++ b/ldap/servers/slapd/mapping_tree.c
@@ -1925,6 +1925,48 @@ static int sdn_is_nulldn(const Slapi_DN *sdn){
return 0;
}
+/* Checks if a write operation for a particular DN would
+ * require a referral to be sent. */
+int slapi_dn_write_needs_referral(Slapi_DN *target_sdn, Slapi_Entry **referral)
+{
+ mapping_tree_node *target_node = NULL;
+ int ret = 0;
+
+ if(mapping_tree_freed){
+ /* shutdown detected */
+ goto done;
+ }
+
+ if(!mapping_tree_inited) {
+ mapping_tree_init();
+ }
+
+ if (target_sdn) {
+ mtn_lock();
+
+ /* Get the mapping tree node that is the best match for the target dn. */
+ target_node = slapi_get_mapping_tree_node_by_dn(target_sdn);
+ if (target_node == NULL) {
+ target_node = mapping_tree_root;
+ }
+
+ /* See if we need to return a referral. */
+ if ((target_node->mtn_state == MTN_REFERRAL) ||
+ (target_node->mtn_state == MTN_REFERRAL_ON_UPDATE)) {
+ *referral = (target_node->mtn_referral_entry ?
+ slapi_entry_dup(target_node->mtn_referral_entry) :
+ NULL);
+ if (*referral) {
+ ret = 1;
+ }
+ }
+
+ mtn_unlock();
+ }
+
+ done:
+ return ret;
+}
/*
* Description:
* The reason we have a mapping tree. This function selects a backend or