ldap/servers/slapd/bind.c | 58 +++++++++++++++++++++++++++++++-------
ldap/servers/slapd/mapping_tree.c | 19 ++++++++++++
ldap/servers/slapd/slapi-plugin.h | 1
3 files changed, 68 insertions(+), 10 deletions(-)
New commits:
commit 8212a8913b748cd1f5e986a754c37ef41db8272a
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Fri Sep 18 15:19:51 2015 -0700
Ticket #48188 - segfault in ns-slapd due to accessing Slapi_DN freed in pre bind plug-in
Description: Additional fixes based upon the comments by rmeggins(a)redhat.com
(Thank you, Rich!!).
https://fedorahosted.org/389/ticket/48188?replyto=24#comment:24
1. Implemented the case 2)
If the plugin changes the SLAPI_BIND_TARGET_SDN *value*,
we need to select a different backend. It is possible
(but not very useful) for the plugin to change the pointer,
but use the same value.
2. Added an api slapi_be_select_exact which returns NULL if
there is no matching backend.
https://fedorahosted.org/389/ticket/48188
Reviewed by rmeggins(a)redhat.com (Thank you!)
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
index 4ec276a..474b508 100644
--- a/ldap/servers/slapd/bind.c
+++ b/ldap/servers/slapd/bind.c
@@ -107,6 +107,7 @@ do_bind( Slapi_PBlock *pb )
int auto_bind = 0;
int minssf = 0;
int minssf_exclude_rootdse = 0;
+ Slapi_DN *original_sdn = NULL;
LDAPDebug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );
@@ -660,10 +661,9 @@ do_bind( Slapi_PBlock *pb )
goto free_and_return;
}
- if (referral)
- {
- send_referrals_from_entry(pb,referral);
- slapi_entry_free(referral);
+ if (referral) {
+ send_referrals_from_entry(pb,referral);
+ slapi_entry_free(referral);
goto free_and_return;
}
@@ -671,29 +671,50 @@ do_bind( Slapi_PBlock *pb )
/* not root dn - pass to the backend */
if ( be->be_bind != NULL ) {
-
+ original_sdn = slapi_sdn_dup(sdn);
/*
* call the pre-bind plugins. if they succeed, call
* the backend bind function. then call the post-bind
* plugins.
*/
if ( plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN ) == 0 ) {
+ int sdn_updated = 0;
rc = 0;
/* Check if a pre_bind plugin mapped the DN to another backend */
Slapi_DN *pb_sdn;
slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &pb_sdn);
- if (pb_sdn != sdn) {
+ if (!pb_sdn) {
+ PR_snprintf(errorbuf, sizeof(errorbuf), "Pre-bind plug-in set NULL dn\n");
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL);
+ goto free_and_return;
+ } else if ((pb_sdn != sdn) || (sdn_updated = slapi_sdn_compare(original_sdn, pb_sdn))) {
/*
* Slapi_DN set in pblock was changed by a pre bind plug-in.
* It is a plug-in's responsibility to free the original Slapi_DN.
*/
sdn = pb_sdn;
dn = slapi_sdn_get_dn(sdn);
-
- slapi_be_Unlock(be);
- be = slapi_be_select(sdn);
- slapi_be_Rlock(be);
+ if (!dn) {
+ PR_snprintf(errorbuf, sizeof(errorbuf), "Pre-bind plug-in set corrupted dn\n");
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL);
+ goto free_and_return;
+ }
+ if (!sdn_updated) { /* pb_sdn != sdn; need to compare the dn's. */
+ sdn_updated = slapi_sdn_compare(original_sdn, sdn);
+ }
+ if (sdn_updated) { /* call slapi_be_select only when the DN is updated. */
+ slapi_be_Unlock(be);
+ be = slapi_be_select_exact(sdn);
+ if (be) {
+ slapi_be_Rlock(be);
+ slapi_pblock_set( pb, SLAPI_BACKEND, be );
+ } else {
+ PR_snprintf(errorbuf, sizeof(errorbuf), "No matching backend for %s\n", dn);
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL);
+ goto free_and_return;
+ }
+ }
}
/*
@@ -845,10 +866,12 @@ account_locked:
}
free_and_return:;
- if (be)
+ slapi_sdn_free(&original_sdn);
+ if (be) {
slapi_be_Unlock(be);
+ }
if (bind_sdn_in_pb) {
- slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn);
+ slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn);
}
slapi_sdn_free(&sdn);
slapi_ch_free_string( &saslmech );
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
index 165eba1..20c2cc3 100644
--- a/ldap/servers/slapd/mapping_tree.c
+++ b/ldap/servers/slapd/mapping_tree.c
@@ -3095,6 +3095,25 @@ slapi_be_select( const Slapi_DN *sdn ) /* JCM - The name of this should change??
return be;
}
+Slapi_Backend *
+slapi_be_select_exact(const Slapi_DN *sdn)
+{
+ Slapi_Backend *be = NULL;
+ mapping_tree_node *node = NULL;
+
+ if (!sdn) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "slapi_be_select_exact: Empty Slapi_DN is given.\n");
+ return NULL;
+ }
+ node = slapi_get_mapping_tree_node_by_dn(sdn);
+
+ if (node && node->mtn_be) {
+ be = node->mtn_be[0];
+ }
+
+ return be;
+}
+
/* Check if the dn targets an internal reserved backends */
int
slapi_on_internal_backends(const Slapi_DN *sdn)
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 4134c1b..72f3920 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -6339,6 +6339,7 @@ Slapi_Backend *slapi_be_new( const char *type, const char *name,
int isprivate, int logchanges );
void slapi_be_free(Slapi_Backend **be);
Slapi_Backend *slapi_be_select( const Slapi_DN *sdn );
+Slapi_Backend *slapi_be_select_exact(const Slapi_DN *sdn);
Slapi_Backend *slapi_be_select_by_instance_name( const char *name );
int slapi_be_exist(const Slapi_DN *sdn);
void slapi_be_delete_onexit(Slapi_Backend *be);
commit 40e0d0f80d6fd1271431e105580293747c43c327
Author: Simo Sorce <simo(a)redhat.com>
Date: Fri Sep 18 11:13:43 2015 -0700
Ticket #48188 - segfault in ns-slapd due to accessing Slapi_DN freed in pre bind plug-in
This patch is based upon the patch provided by Simo Sorce <simo(a)redhat.com> for
Ticket #48272 - Allow PRE_BIND plugins to mangle DNs
Description:
Allow a pre_bind plugin to map a DN to another
This is useful for plugins that deal with virtual trees or non-standard
clients binding with values that are not proper DNs and similar situations.
Signed-off-by: Simo Sorce <simo(a)redhat.com>
2 changes are made to the original patch:
1. removed "slapi_sdn_free(&sdn)" with this comment:
* It is a plug-in's responsibility to free the original Slapi_DN.
Note: slapi-nis already freed the original sdn.
2. reset dn from the new sdn.
dn = slapi_sdn_get_dn(sdn);
https://fedorahosted.org/389/ticket/48188
Reviewed by rmeggins(a)redhat.com and lkrispen(a)redhat.com.
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
index 1bd604f..4ec276a 100644
--- a/ldap/servers/slapd/bind.c
+++ b/ldap/servers/slapd/bind.c
@@ -669,7 +669,7 @@ do_bind( Slapi_PBlock *pb )
slapi_pblock_set( pb, SLAPI_BACKEND, be );
- /* not root dn - pass to the backend */
+ /* not root dn - pass to the backend */
if ( be->be_bind != NULL ) {
/*
@@ -677,10 +677,25 @@ do_bind( Slapi_PBlock *pb )
* the backend bind function. then call the post-bind
* plugins.
*/
- if ( plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN )
- == 0 ) {
+ if ( plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN ) == 0 ) {
rc = 0;
+ /* Check if a pre_bind plugin mapped the DN to another backend */
+ Slapi_DN *pb_sdn;
+ slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &pb_sdn);
+ if (pb_sdn != sdn) {
+ /*
+ * Slapi_DN set in pblock was changed by a pre bind plug-in.
+ * It is a plug-in's responsibility to free the original Slapi_DN.
+ */
+ sdn = pb_sdn;
+ dn = slapi_sdn_get_dn(sdn);
+
+ slapi_be_Unlock(be);
+ be = slapi_be_select(sdn);
+ slapi_be_Rlock(be);
+ }
+
/*
* Is this account locked ?
* could be locked through the account inactivation
--
389 commits mailing list
389-commits@%(host_name)s
http://lists.fedoraproject.org/postorius/389-commits@lists.fedoraproject.org
ldap/servers/plugins/replication/repl5_replica_config.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
New commits:
commit d9f03f5fddfc8ba7009c9dcc584686e43d6339e8
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Sep 18 11:56:29 2015 -0400
Ticket 48217 - cleanallruv - fix regression with server shutdown
Bug Description: Recent checks for server shutdown were added to cleanallruv task,
but we did not properly check for "shutdown" at the end of the task.
This caused the server to think the task successfully finished,
when in fact it did not.
Fix Description: Properly check for shutdown at the end of the task, and handler it
appropriately.
https://fedorahosted.org/389/ticket/48217
Reviewed by: nhosoi(Thanks!)
(cherry picked from commit c41d36de0ca438bf23e4e810bfec0fd59cbc790b)
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 446da3f..8d3c481 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1948,7 +1948,7 @@ done:
/*
* If the replicas are cleaned, release the rid
*/
- if(!aborted){
+ if(!aborted && !slapi_is_shutting_down()){
delete_cleaned_rid_config(data);
/* make sure all the replicas have been "pre_cleaned" before finishing */
check_replicas_are_done_cleaning(data);
@@ -3005,7 +3005,7 @@ replica_abort_task_thread(void *arg)
}
/*
- * Now send the cleanruv extended op to all the agreements
+ * Now send the abort cleanruv extended op to all the agreements
*/
while(agmt_not_notified && !slapi_is_shutting_down()){
agmt_obj = agmtlist_get_first_agreement_for_replica (data->replica);
@@ -3013,7 +3013,7 @@ replica_abort_task_thread(void *arg)
agmt_not_notified = 0;
break;
}
- while (agmt_obj){
+ while (agmt_obj && !slapi_is_shutting_down()){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
@@ -3058,7 +3058,7 @@ replica_abort_task_thread(void *arg)
} /* while */
done:
- if(agmt_not_notified){
+ if(agmt_not_notified || slapi_is_shutting_down()){
/* failure */
cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID,"Abort task failed, will resume the task at the next server startup.");
} else {
--
389 commits mailing list
389-commits@%(host_name)s
http://lists.fedoraproject.org/postorius/389-commits@lists.fedoraproject.org
ldap/servers/plugins/replication/repl5_replica_config.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
New commits:
commit c41d36de0ca438bf23e4e810bfec0fd59cbc790b
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Sep 18 11:56:29 2015 -0400
Ticket 48217 - cleanallruv - fix regression with server shutdown
Bug Description: Recent checks for server shutdown were added to cleanallruv task,
but we did not properly check for "shutdown" at the end of the task.
This caused the server to think the task successfully finished,
when in fact it did not.
Fix Description: Properly check for shutdown at the end of the task, and handler it
appropriately.
https://fedorahosted.org/389/ticket/48217
Reviewed by: nhosoi(Thanks!)
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 446da3f..8d3c481 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1948,7 +1948,7 @@ done:
/*
* If the replicas are cleaned, release the rid
*/
- if(!aborted){
+ if(!aborted && !slapi_is_shutting_down()){
delete_cleaned_rid_config(data);
/* make sure all the replicas have been "pre_cleaned" before finishing */
check_replicas_are_done_cleaning(data);
@@ -3005,7 +3005,7 @@ replica_abort_task_thread(void *arg)
}
/*
- * Now send the cleanruv extended op to all the agreements
+ * Now send the abort cleanruv extended op to all the agreements
*/
while(agmt_not_notified && !slapi_is_shutting_down()){
agmt_obj = agmtlist_get_first_agreement_for_replica (data->replica);
@@ -3013,7 +3013,7 @@ replica_abort_task_thread(void *arg)
agmt_not_notified = 0;
break;
}
- while (agmt_obj){
+ while (agmt_obj && !slapi_is_shutting_down()){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
@@ -3058,7 +3058,7 @@ replica_abort_task_thread(void *arg)
} /* while */
done:
- if(agmt_not_notified){
+ if(agmt_not_notified || slapi_is_shutting_down()){
/* failure */
cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID,"Abort task failed, will resume the task at the next server startup.");
} else {
--
389 commits mailing list
389-commits@%(host_name)s
http://lists.fedoraproject.org/postorius/389-commits@lists.fedoraproject.org