|
|
a2f18f |
From 91e8872841e18eb96f2680fba180d636bb0a2a67 Mon Sep 17 00:00:00 2001
|
|
|
a2f18f |
From: Noriko Hosoi <nhosoi@redhat.com>
|
|
|
a2f18f |
Date: Fri, 18 Sep 2015 15:19:51 -0700
|
|
|
a2f18f |
Subject: [PATCH 61/61] Ticket #48188 - segfault in ns-slapd due to accessing
|
|
|
a2f18f |
Slapi_DN freed in pre bind plug-in
|
|
|
a2f18f |
|
|
|
a2f18f |
Description: Additional fixes based upon the comments by rmeggins@redhat.com
|
|
|
a2f18f |
(Thank you, Rich!!).
|
|
|
a2f18f |
https://fedorahosted.org/389/ticket/48188?replyto=24#comment:24
|
|
|
a2f18f |
1. Implemented the case 2)
|
|
|
a2f18f |
If the plugin changes the SLAPI_BIND_TARGET_SDN *value*,
|
|
|
a2f18f |
we need to select a different backend. It is possible
|
|
|
a2f18f |
(but not very useful) for the plugin to change the pointer,
|
|
|
a2f18f |
but use the same value.
|
|
|
a2f18f |
2. Added an api slapi_be_select_exact which returns NULL if
|
|
|
a2f18f |
there is no matching backend.
|
|
|
a2f18f |
|
|
|
a2f18f |
https://fedorahosted.org/389/ticket/48188
|
|
|
a2f18f |
|
|
|
a2f18f |
Reviewed by rmeggins@redhat.com (Thank you!)
|
|
|
a2f18f |
|
|
|
a2f18f |
(cherry picked from commit 8212a8913b748cd1f5e986a754c37ef41db8272a)
|
|
|
a2f18f |
(cherry picked from commit a215c006e0900caaa555def9e047e295844d8652)
|
|
|
a2f18f |
---
|
|
|
a2f18f |
ldap/servers/slapd/bind.c | 47 +++++++++++++++++++++++++++++----------
|
|
|
a2f18f |
ldap/servers/slapd/mapping_tree.c | 19 ++++++++++++++++
|
|
|
a2f18f |
ldap/servers/slapd/slapi-plugin.h | 1 +
|
|
|
a2f18f |
3 files changed, 55 insertions(+), 12 deletions(-)
|
|
|
a2f18f |
|
|
|
a2f18f |
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
|
|
|
a2f18f |
index 4ec276a..474b508 100644
|
|
|
a2f18f |
--- a/ldap/servers/slapd/bind.c
|
|
|
a2f18f |
+++ b/ldap/servers/slapd/bind.c
|
|
|
a2f18f |
@@ -107,6 +107,7 @@ do_bind( Slapi_PBlock *pb )
|
|
|
a2f18f |
int auto_bind = 0;
|
|
|
a2f18f |
int minssf = 0;
|
|
|
a2f18f |
int minssf_exclude_rootdse = 0;
|
|
|
a2f18f |
+ Slapi_DN *original_sdn = NULL;
|
|
|
a2f18f |
|
|
|
a2f18f |
LDAPDebug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );
|
|
|
a2f18f |
|
|
|
a2f18f |
@@ -660,10 +661,9 @@ do_bind( Slapi_PBlock *pb )
|
|
|
a2f18f |
goto free_and_return;
|
|
|
a2f18f |
}
|
|
|
a2f18f |
|
|
|
a2f18f |
- if (referral)
|
|
|
a2f18f |
- {
|
|
|
a2f18f |
- send_referrals_from_entry(pb,referral);
|
|
|
a2f18f |
- slapi_entry_free(referral);
|
|
|
a2f18f |
+ if (referral) {
|
|
|
a2f18f |
+ send_referrals_from_entry(pb,referral);
|
|
|
a2f18f |
+ slapi_entry_free(referral);
|
|
|
a2f18f |
goto free_and_return;
|
|
|
a2f18f |
}
|
|
|
a2f18f |
|
|
|
a2f18f |
@@ -671,29 +671,50 @@ do_bind( Slapi_PBlock *pb )
|
|
|
a2f18f |
|
|
|
a2f18f |
/* not root dn - pass to the backend */
|
|
|
a2f18f |
if ( be->be_bind != NULL ) {
|
|
|
a2f18f |
-
|
|
|
a2f18f |
+ original_sdn = slapi_sdn_dup(sdn);
|
|
|
a2f18f |
/*
|
|
|
a2f18f |
* call the pre-bind plugins. if they succeed, call
|
|
|
a2f18f |
* the backend bind function. then call the post-bind
|
|
|
a2f18f |
* plugins.
|
|
|
a2f18f |
*/
|
|
|
a2f18f |
if ( plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN ) == 0 ) {
|
|
|
a2f18f |
+ int sdn_updated = 0;
|
|
|
a2f18f |
rc = 0;
|
|
|
a2f18f |
|
|
|
a2f18f |
/* Check if a pre_bind plugin mapped the DN to another backend */
|
|
|
a2f18f |
Slapi_DN *pb_sdn;
|
|
|
a2f18f |
slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &pb_sdn);
|
|
|
a2f18f |
- if (pb_sdn != sdn) {
|
|
|
a2f18f |
+ if (!pb_sdn) {
|
|
|
a2f18f |
+ PR_snprintf(errorbuf, sizeof(errorbuf), "Pre-bind plug-in set NULL dn\n");
|
|
|
a2f18f |
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL);
|
|
|
a2f18f |
+ goto free_and_return;
|
|
|
a2f18f |
+ } else if ((pb_sdn != sdn) || (sdn_updated = slapi_sdn_compare(original_sdn, pb_sdn))) {
|
|
|
a2f18f |
/*
|
|
|
a2f18f |
* Slapi_DN set in pblock was changed by a pre bind plug-in.
|
|
|
a2f18f |
* It is a plug-in's responsibility to free the original Slapi_DN.
|
|
|
a2f18f |
*/
|
|
|
a2f18f |
sdn = pb_sdn;
|
|
|
a2f18f |
dn = slapi_sdn_get_dn(sdn);
|
|
|
a2f18f |
-
|
|
|
a2f18f |
- slapi_be_Unlock(be);
|
|
|
a2f18f |
- be = slapi_be_select(sdn);
|
|
|
a2f18f |
- slapi_be_Rlock(be);
|
|
|
a2f18f |
+ if (!dn) {
|
|
|
a2f18f |
+ PR_snprintf(errorbuf, sizeof(errorbuf), "Pre-bind plug-in set corrupted dn\n");
|
|
|
a2f18f |
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL);
|
|
|
a2f18f |
+ goto free_and_return;
|
|
|
a2f18f |
+ }
|
|
|
a2f18f |
+ if (!sdn_updated) { /* pb_sdn != sdn; need to compare the dn's. */
|
|
|
a2f18f |
+ sdn_updated = slapi_sdn_compare(original_sdn, sdn);
|
|
|
a2f18f |
+ }
|
|
|
a2f18f |
+ if (sdn_updated) { /* call slapi_be_select only when the DN is updated. */
|
|
|
a2f18f |
+ slapi_be_Unlock(be);
|
|
|
a2f18f |
+ be = slapi_be_select_exact(sdn);
|
|
|
a2f18f |
+ if (be) {
|
|
|
a2f18f |
+ slapi_be_Rlock(be);
|
|
|
a2f18f |
+ slapi_pblock_set( pb, SLAPI_BACKEND, be );
|
|
|
a2f18f |
+ } else {
|
|
|
a2f18f |
+ PR_snprintf(errorbuf, sizeof(errorbuf), "No matching backend for %s\n", dn);
|
|
|
a2f18f |
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL);
|
|
|
a2f18f |
+ goto free_and_return;
|
|
|
a2f18f |
+ }
|
|
|
a2f18f |
+ }
|
|
|
a2f18f |
}
|
|
|
a2f18f |
|
|
|
a2f18f |
/*
|
|
|
a2f18f |
@@ -845,10 +866,12 @@ account_locked:
|
|
|
a2f18f |
}
|
|
|
a2f18f |
|
|
|
a2f18f |
free_and_return:;
|
|
|
a2f18f |
- if (be)
|
|
|
a2f18f |
+ slapi_sdn_free(&original_sdn);
|
|
|
a2f18f |
+ if (be) {
|
|
|
a2f18f |
slapi_be_Unlock(be);
|
|
|
a2f18f |
+ }
|
|
|
a2f18f |
if (bind_sdn_in_pb) {
|
|
|
a2f18f |
- slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn;;
|
|
|
a2f18f |
+ slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn;;
|
|
|
a2f18f |
}
|
|
|
a2f18f |
slapi_sdn_free(&sdn;;
|
|
|
a2f18f |
slapi_ch_free_string( &saslmech );
|
|
|
a2f18f |
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
|
|
|
a2f18f |
index 165eba1..20c2cc3 100644
|
|
|
a2f18f |
--- a/ldap/servers/slapd/mapping_tree.c
|
|
|
a2f18f |
+++ b/ldap/servers/slapd/mapping_tree.c
|
|
|
a2f18f |
@@ -3095,6 +3095,25 @@ slapi_be_select( const Slapi_DN *sdn ) /* JCM - The name of this should change??
|
|
|
a2f18f |
return be;
|
|
|
a2f18f |
}
|
|
|
a2f18f |
|
|
|
a2f18f |
+Slapi_Backend *
|
|
|
a2f18f |
+slapi_be_select_exact(const Slapi_DN *sdn)
|
|
|
a2f18f |
+{
|
|
|
a2f18f |
+ Slapi_Backend *be = NULL;
|
|
|
a2f18f |
+ mapping_tree_node *node = NULL;
|
|
|
a2f18f |
+
|
|
|
a2f18f |
+ if (!sdn) {
|
|
|
a2f18f |
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "slapi_be_select_exact: Empty Slapi_DN is given.\n");
|
|
|
a2f18f |
+ return NULL;
|
|
|
a2f18f |
+ }
|
|
|
a2f18f |
+ node = slapi_get_mapping_tree_node_by_dn(sdn);
|
|
|
a2f18f |
+
|
|
|
a2f18f |
+ if (node && node->mtn_be) {
|
|
|
a2f18f |
+ be = node->mtn_be[0];
|
|
|
a2f18f |
+ }
|
|
|
a2f18f |
+
|
|
|
a2f18f |
+ return be;
|
|
|
a2f18f |
+}
|
|
|
a2f18f |
+
|
|
|
a2f18f |
/* Check if the dn targets an internal reserved backends */
|
|
|
a2f18f |
int
|
|
|
a2f18f |
slapi_on_internal_backends(const Slapi_DN *sdn)
|
|
|
a2f18f |
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
|
|
|
a2f18f |
index 6b04610..564da44 100644
|
|
|
a2f18f |
--- a/ldap/servers/slapd/slapi-plugin.h
|
|
|
a2f18f |
+++ b/ldap/servers/slapd/slapi-plugin.h
|
|
|
a2f18f |
@@ -6338,6 +6338,7 @@ Slapi_Backend *slapi_be_new( const char *type, const char *name,
|
|
|
a2f18f |
int isprivate, int logchanges );
|
|
|
a2f18f |
void slapi_be_free(Slapi_Backend **be);
|
|
|
a2f18f |
Slapi_Backend *slapi_be_select( const Slapi_DN *sdn );
|
|
|
a2f18f |
+Slapi_Backend *slapi_be_select_exact(const Slapi_DN *sdn);
|
|
|
a2f18f |
Slapi_Backend *slapi_be_select_by_instance_name( const char *name );
|
|
|
a2f18f |
int slapi_be_exist(const Slapi_DN *sdn);
|
|
|
a2f18f |
void slapi_be_delete_onexit(Slapi_Backend *be);
|
|
|
a2f18f |
--
|
|
|
a2f18f |
1.9.3
|
|
|
a2f18f |
|