diff options
author | Nathan Kinder <nkinder@redhat.com> | 2010-04-08 15:55:29 -0700 |
---|---|---|
committer | Nathan Kinder <nkinder@redhat.com> | 2010-04-09 07:49:03 -0700 |
commit | c53b8b31c8655d8b387c4b213caee885778c3872 (patch) | |
tree | 67813a4f60b725162ac86f4aa9d4675af19365a0 /ldap/servers/slapd/mapping_tree.c | |
parent | b433e4c852a2ef78558dffc1ccbaf464c1186934 (diff) | |
download | ds-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.c | 42 |
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 |