|
|
b69e47 |
From 22f1ff8d87a7daf9fbbe2ddfbd195a6bfdae1cd6 Mon Sep 17 00:00:00 2001
|
|
|
b69e47 |
From: William Brown <firstyear@redhat.com>
|
|
|
b69e47 |
Date: Tue, 14 Mar 2017 14:01:33 +1000
|
|
|
b69e47 |
Subject: [PATCH 3/5] Ticket 49165 pw_verify did not handle external auth
|
|
|
b69e47 |
|
|
|
b69e47 |
Bug Description: During the change to improve sasl and simple bind,
|
|
|
b69e47 |
we externalised the backend selection outside of do_bind. In an
|
|
|
b69e47 |
auto_bind scenario however, this mean the be was null, causing the
|
|
|
b69e47 |
dn to always be invalidated.
|
|
|
b69e47 |
|
|
|
b69e47 |
Fix Description: Add a pw_validate_be_dn function, that correctly
|
|
|
b69e47 |
checks if we are anonymous, a real be dn, or rootdn. This then allows
|
|
|
b69e47 |
the correct authentication of autobinds.
|
|
|
b69e47 |
|
|
|
b69e47 |
https://pagure.io/389-ds-base/issue/49165
|
|
|
b69e47 |
|
|
|
b69e47 |
Author: wibrown
|
|
|
b69e47 |
|
|
|
b69e47 |
Review by: mreynolds (Thanks!)
|
|
|
b69e47 |
|
|
|
b69e47 |
(cherry picked from commit 8dbfff1ff4152afb018490886a612c448ea2a1b0)
|
|
|
b69e47 |
---
|
|
|
b69e47 |
ldap/servers/slapd/bind.c | 9 +++++--
|
|
|
b69e47 |
ldap/servers/slapd/dn.c | 5 ++++
|
|
|
b69e47 |
ldap/servers/slapd/pw_verify.c | 57 +++++++++++++++++++++++++++++++++++++--
|
|
|
b69e47 |
ldap/servers/slapd/pw_verify.h | 1 +
|
|
|
b69e47 |
ldap/servers/slapd/slapi-plugin.h | 9 +++++++
|
|
|
b69e47 |
5 files changed, 77 insertions(+), 4 deletions(-)
|
|
|
b69e47 |
|
|
|
b69e47 |
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
|
|
|
b69e47 |
index b4bb363..5c4fada 100644
|
|
|
b69e47 |
--- a/ldap/servers/slapd/bind.c
|
|
|
b69e47 |
+++ b/ldap/servers/slapd/bind.c
|
|
|
b69e47 |
@@ -656,7 +656,12 @@ do_bind( Slapi_PBlock *pb )
|
|
|
b69e47 |
/* We could be serving multiple database backends. Select the appropriate one */
|
|
|
b69e47 |
/* pw_verify_be_dn will select the backend we need for us. */
|
|
|
b69e47 |
|
|
|
b69e47 |
- rc = pw_verify_be_dn(pb, &referral);
|
|
|
b69e47 |
+ if (auto_bind) {
|
|
|
b69e47 |
+ /* We have no password material. We should just check who we are binding as. */
|
|
|
b69e47 |
+ rc = pw_validate_be_dn(pb, &referral);
|
|
|
b69e47 |
+ } else {
|
|
|
b69e47 |
+ rc = pw_verify_be_dn(pb, &referral);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
|
|
|
b69e47 |
if (rc == SLAPI_BIND_NO_BACKEND) {
|
|
|
b69e47 |
send_nobackend_ldap_result( pb );
|
|
|
b69e47 |
@@ -715,7 +720,7 @@ do_bind( Slapi_PBlock *pb )
|
|
|
b69e47 |
*
|
|
|
b69e47 |
*/
|
|
|
b69e47 |
slapi_pblock_get(pb, SLAPI_BACKEND, &be);
|
|
|
b69e47 |
- if (!slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA)) {
|
|
|
b69e47 |
+ if (!isroot && !slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA)) {
|
|
|
b69e47 |
bind_target_entry = get_entry(pb, slapi_sdn_get_ndn(sdn));
|
|
|
b69e47 |
myrc = slapi_check_account_lock(pb, bind_target_entry, pw_response_requested, 1, 1);
|
|
|
b69e47 |
if (1 == myrc) { /* account is locked */
|
|
|
b69e47 |
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
|
|
|
b69e47 |
index d043f2a..fa3909f 100644
|
|
|
b69e47 |
--- a/ldap/servers/slapd/dn.c
|
|
|
b69e47 |
+++ b/ldap/servers/slapd/dn.c
|
|
|
b69e47 |
@@ -1738,6 +1738,11 @@ slapi_dn_isroot( const char *dn )
|
|
|
b69e47 |
return( rc );
|
|
|
b69e47 |
}
|
|
|
b69e47 |
|
|
|
b69e47 |
+int32_t
|
|
|
b69e47 |
+slapi_sdn_isroot(const Slapi_DN *sdn) {
|
|
|
b69e47 |
+ return slapi_dn_isroot(slapi_sdn_get_ndn(sdn));
|
|
|
b69e47 |
+}
|
|
|
b69e47 |
+
|
|
|
b69e47 |
int
|
|
|
b69e47 |
slapi_is_rootdse( const char *dn )
|
|
|
b69e47 |
{
|
|
|
b69e47 |
diff --git a/ldap/servers/slapd/pw_verify.c b/ldap/servers/slapd/pw_verify.c
|
|
|
b69e47 |
index 93e5ff3..529bb83 100644
|
|
|
b69e47 |
--- a/ldap/servers/slapd/pw_verify.c
|
|
|
b69e47 |
+++ b/ldap/servers/slapd/pw_verify.c
|
|
|
b69e47 |
@@ -88,8 +88,61 @@ pw_verify_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
|
|
b69e47 |
return rc;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
|
|
|
b69e47 |
+/*
|
|
|
b69e47 |
+ * Resolve the dn we have been requested to bind with and verify it's
|
|
|
b69e47 |
+ * valid, and has a backend.
|
|
|
b69e47 |
+ *
|
|
|
b69e47 |
+ * We are checking:
|
|
|
b69e47 |
+ * * is this anonymous?
|
|
|
b69e47 |
+ * * is this the rootdn?
|
|
|
b69e47 |
+ * * is this a real dn, which associates to a real backend.
|
|
|
b69e47 |
+ *
|
|
|
b69e47 |
+ * This is used in SASL autobinds, so we need to handle this validation.
|
|
|
b69e47 |
+ */
|
|
|
b69e47 |
+
|
|
|
b69e47 |
int
|
|
|
b69e47 |
-pw_verify_dn()
|
|
|
b69e47 |
+pw_validate_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
|
|
b69e47 |
{
|
|
|
b69e47 |
- return LDAP_OPERATIONS_ERROR;
|
|
|
b69e47 |
+ int rc = 0;
|
|
|
b69e47 |
+ Slapi_Backend *be = NULL;
|
|
|
b69e47 |
+ Slapi_DN *pb_sdn;
|
|
|
b69e47 |
+ struct berval *cred;
|
|
|
b69e47 |
+ ber_tag_t method;
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &pb_sdn);
|
|
|
b69e47 |
+ slapi_pblock_get(pb, SLAPI_BIND_CREDENTIALS, &cred);
|
|
|
b69e47 |
+ slapi_pblock_get(pb, SLAPI_BIND_METHOD, &method);
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ if (pb_sdn != NULL || cred != NULL) {
|
|
|
b69e47 |
+ return LDAP_OPERATIONS_ERROR;
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ if (*referral) {
|
|
|
b69e47 |
+ return SLAPI_BIND_REFERRAL;
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ /* We need a slapi_sdn_isanon? */
|
|
|
b69e47 |
+ if (method == LDAP_AUTH_SIMPLE && cred->bv_len == 0) {
|
|
|
b69e47 |
+ return SLAPI_BIND_ANONYMOUS;
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ if (slapi_sdn_isroot(pb_sdn)) {
|
|
|
b69e47 |
+ /* This is a real identity */
|
|
|
b69e47 |
+ return SLAPI_BIND_SUCCESS;
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ if (slapi_mapping_tree_select(pb, &be, referral, NULL, 0) != LDAP_SUCCESS) {
|
|
|
b69e47 |
+ return SLAPI_BIND_NO_BACKEND;
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ slapi_be_Unlock(be);
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ slapi_pblock_set(pb, SLAPI_BACKEND, be);
|
|
|
b69e47 |
+ slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database);
|
|
|
b69e47 |
+ /* Make sure the result handlers are setup */
|
|
|
b69e47 |
+ set_db_default_result_handlers(pb);
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ /* The backend associated with this identity is real. */
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ return SLAPI_BIND_SUCCESS;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
diff --git a/ldap/servers/slapd/pw_verify.h b/ldap/servers/slapd/pw_verify.h
|
|
|
b69e47 |
index fc34fd1..5137027 100644
|
|
|
b69e47 |
--- a/ldap/servers/slapd/pw_verify.h
|
|
|
b69e47 |
+++ b/ldap/servers/slapd/pw_verify.h
|
|
|
b69e47 |
@@ -11,5 +11,6 @@
|
|
|
b69e47 |
|
|
|
b69e47 |
int pw_verify_root_dn(const char *dn, const Slapi_Value *cred);
|
|
|
b69e47 |
int pw_verify_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral);
|
|
|
b69e47 |
+int pw_validate_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral);
|
|
|
b69e47 |
|
|
|
b69e47 |
#endif /* _SLAPD_PW_VERIFY_H_ */
|
|
|
b69e47 |
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
|
|
|
b69e47 |
index b223f65..1bd8fc8 100644
|
|
|
b69e47 |
--- a/ldap/servers/slapd/slapi-plugin.h
|
|
|
b69e47 |
+++ b/ldap/servers/slapd/slapi-plugin.h
|
|
|
b69e47 |
@@ -3800,6 +3800,15 @@ int slapi_dn_isparent( const char *parentdn, const char *childdn );
|
|
|
b69e47 |
int slapi_dn_isroot( const char *dn );
|
|
|
b69e47 |
|
|
|
b69e47 |
/**
|
|
|
b69e47 |
+ * Determines if an SDN is the root DN.
|
|
|
b69e47 |
+ *
|
|
|
b69e47 |
+ * \param sdn The DN to check
|
|
|
b69e47 |
+ * \return \c 1 if the DN is the root DN.
|
|
|
b69e47 |
+ * \return \c 0 if the DN is not the root DN.
|
|
|
b69e47 |
+ */
|
|
|
b69e47 |
+int32_t slapi_sdn_isroot( const Slapi_DN *sdn );
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+/**
|
|
|
b69e47 |
* Checks if a DN is the backend suffix.
|
|
|
b69e47 |
*
|
|
|
b69e47 |
* \param pb A parameter block with the backend set.
|
|
|
b69e47 |
--
|
|
|
b69e47 |
2.9.3
|
|
|
b69e47 |
|