[Patches] The way to remove gensec_update_ev()
Stefan Metzmacher
metze at samba.org
Tue Jun 13 22:04:55 UTC 2017
Hi,
here's the next chunk for the LDAP server.
Also available under:
https://git.samba.org/?p=metze/samba/wip.git;a=shortlog;h=refs/heads/master3-gensec-ok
It just passed a private autobuild.
Please review and push:-)
Thanks!
metze
Am 29.05.2017 um 10:40 schrieb Andrew Bartlett:
> On Mon, 2017-05-29 at 09:55 +0200, Stefan Metzmacher wrote:
>> Hi Andrew,
>>
>> it seems I was to optimistic while removing the
>> inhibit_timeout_processing hack. There's a bit more to do
>> before we can remove it.
>>
>> I have also a pending commit to fix a talloc_steal vs. talloc_reparent
>> and the removale of py_com.
>>
>> Please review and push.
>>
>> Thanks!
>> metze
>
> Thank you so much for getting back to me so promptly with that. I'll
> test it against the failing configuration in the morning and push it.
>
> Thanks!
>
> Andrew Bartlett
>
-------------- next part --------------
From c24c56d74eb2229cbf8f30fb2d02cc55814db1dd Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 20 Dec 2013 08:52:52 +0100
Subject: [PATCH 01/30] s4:auth/gensec: let GENSEC_FEATURE_SESSION_KEY result
in GSS_C_INTEG_FLAG
This is important to allow the 'new_spnego' with mech_list protection to work
for a SMB session setup.
This is not strictly needed as we always announce GENSEC_FEATURE_SESSION_KEY
in gensec_gssapi_have_feature(), but it's better to send GSS_C_INTEG_FLAG
over the wire.
This may prevent a ticket from a Samba client to an SMB server
(particularly a DC) being misused to connect to the LDAP server on that
DC, as the LDAP server will require GSSAPI signing of the connection.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/auth/gensec/gensec_gssapi.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index dd03a96..8bc5452 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -177,6 +177,9 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
gensec_gssapi_state->gss_want_flags |= GSS_C_SEQUENCE_FLAG;
}
+ if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) {
+ gensec_gssapi_state->gss_want_flags |= GSS_C_INTEG_FLAG;
+ }
if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
gensec_gssapi_state->gss_want_flags |= GSS_C_INTEG_FLAG;
}
--
1.9.1
From 8a5a072c56bc695d661f49d5991882823b48f7fd Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 11 May 2017 19:07:04 +0200
Subject: [PATCH 02/30] s4:ldap_server: use talloc_zero() in
ldapsrv_init_reply()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_backend.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c
index 1f0c7af..5e8ce64 100644
--- a/source4/ldap_server/ldap_backend.c
+++ b/source4/ldap_server/ldap_backend.c
@@ -237,11 +237,11 @@ struct ldapsrv_reply *ldapsrv_init_reply(struct ldapsrv_call *call, uint8_t type
{
struct ldapsrv_reply *reply;
- reply = talloc(call, struct ldapsrv_reply);
+ reply = talloc_zero(call, struct ldapsrv_reply);
if (!reply) {
return NULL;
}
- reply->msg = talloc(reply, struct ldap_message);
+ reply->msg = talloc_zero(reply, struct ldap_message);
if (reply->msg == NULL) {
talloc_free(reply);
return NULL;
--
1.9.1
From 0cc0b16f2818a7a2948389b791b2ff2c7d6b513b Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 11 May 2017 16:37:21 +0200
Subject: [PATCH 03/30] s4:ldap_server: introduce a ldapsrv_call_destructor()
This makes sure that a call doesn't become an stale
member of the conn->pending_calls list.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_server.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c
index 347a17d..062c3fc 100644
--- a/source4/ldap_server/ldap_server.c
+++ b/source4/ldap_server/ldap_server.c
@@ -254,6 +254,18 @@ failed:
return -1;
}
+static int ldapsrv_call_destructor(struct ldapsrv_call *call)
+{
+ if (call->conn == NULL) {
+ return 0;
+ }
+
+ DLIST_REMOVE(call->conn->pending_calls, call);
+
+ call->conn = NULL;
+ return 0;
+}
+
static struct tevent_req *ldapsrv_process_call_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct tevent_queue *call_queue,
@@ -504,6 +516,7 @@ static void ldapsrv_call_read_done(struct tevent_req *subreq)
ldapsrv_terminate_connection(conn, "no memory");
return;
}
+ talloc_set_destructor(call, ldapsrv_call_destructor);
call->conn = conn;
--
1.9.1
From 8e4d73d2c963ce8b4664b40173c9bae1c24a634f Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sat, 13 May 2017 08:20:00 +0200
Subject: [PATCH 04/30] s4:ldap_server: don't log Unbind and Abandon requests.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_backend.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c
index 5e8ce64..d4e9030 100644
--- a/source4/ldap_server/ldap_backend.c
+++ b/source4/ldap_server/ldap_backend.c
@@ -1257,6 +1257,8 @@ NTSTATUS ldapsrv_do_call(struct ldapsrv_call *call)
switch(call->request->type) {
case LDAP_TAG_BindRequest:
+ case LDAP_TAG_UnbindRequest:
+ case LDAP_TAG_AbandonRequest:
log = false;
break;
case LDAP_TAG_ExtendedResponse: {
--
1.9.1
From 6172e59eba6be35a8cdc3dc436ca166f1aeeefaa Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 11 May 2017 16:51:15 +0200
Subject: [PATCH 05/30] s4:ldap_server: add call->wait_send/recv infrastructure
If it is set by the dispatch functions, the core server
will use call->wait_send() and wait for it to finally
return frim call->wait_recv() before it asks for the
next incoming pdu.
This can be used to implement bind as async operations.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_server.c | 59 +++++++++++++++++++++++++++++++++++++--
source4/ldap_server/ldap_server.h | 6 ++++
2 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c
index 062c3fc..6a60532 100644
--- a/source4/ldap_server/ldap_server.c
+++ b/source4/ldap_server/ldap_server.c
@@ -578,7 +578,8 @@ static void ldapsrv_call_read_done(struct tevent_req *subreq)
conn->active_call = subreq;
}
-
+static void ldapsrv_call_wait_done(struct tevent_req *subreq);
+static void ldapsrv_call_writev_start(struct ldapsrv_call *call);
static void ldapsrv_call_writev_done(struct tevent_req *subreq);
static void ldapsrv_call_process_done(struct tevent_req *subreq)
@@ -588,7 +589,6 @@ static void ldapsrv_call_process_done(struct tevent_req *subreq)
struct ldapsrv_call);
struct ldapsrv_connection *conn = call->conn;
NTSTATUS status;
- DATA_BLOB blob = data_blob_null;
conn->active_call = NULL;
@@ -599,6 +599,61 @@ static void ldapsrv_call_process_done(struct tevent_req *subreq)
return;
}
+ if (call->wait_send != NULL) {
+ subreq = call->wait_send(call,
+ conn->connection->event.ctx,
+ call->wait_private);
+ if (subreq == NULL) {
+ ldapsrv_terminate_connection(conn,
+ "ldapsrv_call_process_done: "
+ "call->wait_send - no memory");
+ return;
+ }
+ tevent_req_set_callback(subreq,
+ ldapsrv_call_wait_done,
+ call);
+ conn->active_call = subreq;
+ return;
+ }
+
+ ldapsrv_call_writev_start(call);
+}
+
+static void ldapsrv_call_wait_done(struct tevent_req *subreq)
+{
+ struct ldapsrv_call *call =
+ tevent_req_callback_data(subreq,
+ struct ldapsrv_call);
+ struct ldapsrv_connection *conn = call->conn;
+ NTSTATUS status;
+
+ conn->active_call = NULL;
+
+ status = call->wait_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ const char *reason;
+
+ reason = talloc_asprintf(call, "ldapsrv_call_wait_done: "
+ "call->wait_recv() - %s",
+ nt_errstr(status));
+ if (reason == NULL) {
+ reason = nt_errstr(status);
+ }
+
+ ldapsrv_terminate_connection(conn, reason);
+ return;
+ }
+
+ ldapsrv_call_writev_start(call);
+}
+
+static void ldapsrv_call_writev_start(struct ldapsrv_call *call)
+{
+ struct ldapsrv_connection *conn = call->conn;
+ DATA_BLOB blob = data_blob_null;
+ struct tevent_req *subreq = NULL;
+
/* build all the replies into a single blob */
while (call->replies) {
DATA_BLOB b;
diff --git a/source4/ldap_server/ldap_server.h b/source4/ldap_server/ldap_server.h
index 337c974..d3e31fb 100644
--- a/source4/ldap_server/ldap_server.h
+++ b/source4/ldap_server/ldap_server.h
@@ -73,6 +73,12 @@ struct ldapsrv_call {
} *replies;
struct iovec out_iov;
+ struct tevent_req *(*wait_send)(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ void *private_data);
+ NTSTATUS (*wait_recv)(struct tevent_req *req);
+ void *wait_private;
+
struct tevent_req *(*postprocess_send)(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
void *private_data);
--
1.9.1
From 050fe7297d0325c23ec3aefba893a9ce1e0db749 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 13 Jun 2017 15:02:41 +0200
Subject: [PATCH 06/30] s4:ldap_server: improve ldapsrv_UnbindRequest
implementation
We should abandon outstanding requests and disconnect the connection.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 68 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 67 insertions(+), 1 deletion(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 986ecbf..bb6b049 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -23,6 +23,7 @@
#include "smbd/service.h"
#include <ldb.h>
#include <ldb_errors.h>
+#include "../lib/util/dlinklist.h"
#include "dsdb/samdb/samdb.h"
#include "auth/gensec/gensec.h"
#include "auth/gensec/gensec_tstream.h"
@@ -481,8 +482,73 @@ NTSTATUS ldapsrv_BindRequest(struct ldapsrv_call *call)
return NT_STATUS_OK;
}
+struct ldapsrv_unbind_wait_context {
+ uint8_t dummy;
+};
+
+struct ldapsrv_unbind_wait_state {
+ uint8_t dummy;
+};
+
+static struct tevent_req *ldapsrv_unbind_wait_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ void *private_data)
+{
+ struct ldapsrv_unbind_wait_context *unbind_wait =
+ talloc_get_type_abort(private_data,
+ struct ldapsrv_unbind_wait_context);
+ struct tevent_req *req;
+ struct ldapsrv_unbind_wait_state *state;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct ldapsrv_unbind_wait_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ (void)unbind_wait;
+
+ tevent_req_nterror(req, NT_STATUS_LOCAL_DISCONNECT);
+ return tevent_req_post(req, ev);
+}
+
+static NTSTATUS ldapsrv_unbind_wait_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
+}
+
+static NTSTATUS ldapsrv_unbind_wait_setup(struct ldapsrv_call *call)
+{
+ struct ldapsrv_unbind_wait_context *unbind_wait = NULL;
+
+ if (call->wait_private != NULL) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ unbind_wait = talloc_zero(call, struct ldapsrv_unbind_wait_context);
+ if (unbind_wait == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ call->wait_private = unbind_wait;
+ call->wait_send = ldapsrv_unbind_wait_send;
+ call->wait_recv = ldapsrv_unbind_wait_recv;
+ return NT_STATUS_OK;
+}
+
NTSTATUS ldapsrv_UnbindRequest(struct ldapsrv_call *call)
{
+ struct ldapsrv_call *c = NULL;
+ struct ldapsrv_call *n = NULL;
+
DEBUG(10, ("UnbindRequest\n"));
- return NT_STATUS_OK;
+
+ for (c = call->conn->pending_calls; c != NULL; c = n) {
+ n = c->next;
+
+ DLIST_REMOVE(call->conn->pending_calls, c);
+ TALLOC_FREE(c);
+ }
+
+ return ldapsrv_unbind_wait_setup(call);
}
--
1.9.1
From d64e976febb421245e64fa9bafe6f9682dfa65ec Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 11 May 2017 17:05:02 +0200
Subject: [PATCH 07/30] s4:auth: add authenticate_ldap_simple_bind_send/recv
TODO: we need to make the backend async.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/auth/auth.h | 12 +++++++++
source4/auth/ntlm/auth_simple.c | 60 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+)
diff --git a/source4/auth/auth.h b/source4/auth/auth.h
index c12e233..2dc0d8c 100644
--- a/source4/auth/auth.h
+++ b/source4/auth/auth.h
@@ -160,6 +160,18 @@ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
NTSTATUS auth4_init(void);
NTSTATUS auth_register(TALLOC_CTX *mem_ctx, const struct auth_operations *ops);
NTSTATUS server_service_auth_init(TALLOC_CTX *ctx);
+struct tevent_req *authenticate_ldap_simple_bind_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct imessaging_context *msg,
+ struct loadparm_context *lp_ctx,
+ struct tsocket_address *remote_address,
+ struct tsocket_address *local_address,
+ bool using_tls,
+ const char *dn,
+ const char *password);
+NTSTATUS authenticate_ldap_simple_bind_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct auth_session_info **session_info);
NTSTATUS authenticate_ldap_simple_bind(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct imessaging_context *msg,
diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c
index cd96113..142bd40 100644
--- a/source4/auth/ntlm/auth_simple.c
+++ b/source4/auth/ntlm/auth_simple.c
@@ -22,9 +22,49 @@
*/
#include "includes.h"
+#include <tevent.h>
+#include "lib/util/tevent_ntstatus.h"
#include "auth/auth.h"
#include "dsdb/samdb/samdb.h"
+struct authenticate_ldap_simple_bind_state {
+ struct auth_session_info *session_info;
+};
+
+_PUBLIC_ struct tevent_req *authenticate_ldap_simple_bind_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct imessaging_context *msg,
+ struct loadparm_context *lp_ctx,
+ struct tsocket_address *remote_address,
+ struct tsocket_address *local_address,
+ bool using_tls,
+ const char *dn,
+ const char *password)
+{
+ struct tevent_req *req = NULL;
+ struct authenticate_ldap_simple_bind_state *state = NULL;
+ NTSTATUS status;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct authenticate_ldap_simple_bind_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ status = authenticate_ldap_simple_bind(state, ev, msg, lp_ctx,
+ remote_address,
+ local_address,
+ using_tls,
+ dn, password,
+ &state->session_info);
+ if (tevent_req_nterror(req, status)) {
+ return tevent_req_post(req, ev);
+ }
+
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
+}
+
_PUBLIC_ NTSTATUS authenticate_ldap_simple_bind(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct imessaging_context *msg,
@@ -154,3 +194,23 @@ _PUBLIC_ NTSTATUS authenticate_ldap_simple_bind(TALLOC_CTX *mem_ctx,
return nt_status;
}
+_PUBLIC_ NTSTATUS authenticate_ldap_simple_bind_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct auth_session_info **session_info)
+{
+ struct authenticate_ldap_simple_bind_state *state =
+ tevent_req_data(req,
+ struct authenticate_ldap_simple_bind_state);
+ NTSTATUS status;
+
+ *session_info = NULL;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ tevent_req_received(req);
+ return status;
+ }
+
+ *session_info = talloc_move(mem_ctx, &state->session_info);
+ tevent_req_received(req);
+ return NT_STATUS_OK;
+}
--
1.9.1
From dc6496b72894a385d1ebc5c63998594e3a66cd95 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 11 May 2017 18:04:15 +0200
Subject: [PATCH 08/30] s4:ldap_server: implement async BindSimple
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 169 +++++++++++++++++++++++++++++++++++-----
1 file changed, 149 insertions(+), 20 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index bb6b049..23d34d2 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -60,21 +60,107 @@ static char *ldapsrv_bind_error_msg(TALLOC_CTX *mem_ctx,
return msg;
}
+struct ldapsrv_bind_wait_context {
+ struct ldapsrv_reply *reply;
+ struct tevent_req *req;
+ NTSTATUS status;
+ bool done;
+};
-static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
+struct ldapsrv_bind_wait_state {
+ uint8_t dummy;
+};
+
+static struct tevent_req *ldapsrv_bind_wait_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ void *private_data)
{
- struct ldap_BindRequest *req = &call->request->r.BindRequest;
- struct ldapsrv_reply *reply;
- struct ldap_BindResponse *resp;
+ struct ldapsrv_bind_wait_context *bind_wait =
+ talloc_get_type_abort(private_data,
+ struct ldapsrv_bind_wait_context);
+ struct tevent_req *req;
+ struct ldapsrv_bind_wait_state *state;
- int result;
- const char *errstr;
+ req = tevent_req_create(mem_ctx, &state,
+ struct ldapsrv_bind_wait_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ bind_wait->req = req;
- struct auth_session_info *session_info;
+ tevent_req_defer_callback(req, ev);
- NTSTATUS status;
+ if (!bind_wait->done) {
+ return req;
+ }
+
+ if (tevent_req_nterror(req, bind_wait->status)) {
+ return tevent_req_post(req, ev);
+ }
+
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
+}
+
+static NTSTATUS ldapsrv_bind_wait_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
+}
+
+static NTSTATUS ldapsrv_bind_wait_setup(struct ldapsrv_call *call,
+ struct ldapsrv_reply *reply)
+{
+ struct ldapsrv_bind_wait_context *bind_wait = NULL;
+
+ if (call->wait_private != NULL) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ bind_wait = talloc_zero(call, struct ldapsrv_bind_wait_context);
+ if (bind_wait == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ bind_wait->reply = reply;
+
+ call->wait_private = bind_wait;
+ call->wait_send = ldapsrv_bind_wait_send;
+ call->wait_recv = ldapsrv_bind_wait_recv;
+ return NT_STATUS_OK;
+}
+static void ldapsrv_bind_wait_finished(struct ldapsrv_call *call,
+ NTSTATUS status)
+{
+ struct ldapsrv_bind_wait_context *bind_wait =
+ talloc_get_type_abort(call->wait_private,
+ struct ldapsrv_bind_wait_context);
+
+ bind_wait->done = true;
+ bind_wait->status = status;
+
+ if (bind_wait->req == NULL) {
+ return;
+ }
+
+ if (tevent_req_nterror(bind_wait->req, status)) {
+ return;
+ }
+
+ tevent_req_done(bind_wait->req);
+}
+
+static void ldapsrv_BindSimple_done(struct tevent_req *subreq);
+
+static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
+{
+ struct ldap_BindRequest *req = &call->request->r.BindRequest;
+ struct ldapsrv_reply *reply = NULL;
+ struct ldap_BindResponse *resp = NULL;
+ int result;
+ const char *errstr = NULL;
+ NTSTATUS status;
bool using_tls = call->conn->sockets.active == call->conn->sockets.tls;
+ struct tevent_req *subreq = NULL;
DEBUG(10, ("BindSimple dn: %s\n",req->dn));
@@ -95,17 +181,61 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
goto do_reply;
}
- status = authenticate_ldap_simple_bind(call,
- call->conn->connection->event.ctx,
- call->conn->connection->msg_ctx,
- call->conn->lp_ctx,
- call->conn->connection->remote_address,
- call->conn->connection->local_address,
- using_tls,
- req->dn,
- req->creds.password,
- &session_info);
+ subreq = authenticate_ldap_simple_bind_send(call,
+ call->conn->connection->event.ctx,
+ call->conn->connection->msg_ctx,
+ call->conn->lp_ctx,
+ call->conn->connection->remote_address,
+ call->conn->connection->local_address,
+ using_tls,
+ req->dn,
+ req->creds.password);
+ if (subreq == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ tevent_req_set_callback(subreq, ldapsrv_BindSimple_done, call);
+ status = ldapsrv_bind_wait_setup(call, reply);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(subreq);
+ return status;
+ }
+
+ /*
+ * The rest will be async.
+ */
+ return NT_STATUS_OK;
+
+do_reply:
+ resp = &reply->msg->r.BindResponse;
+ resp->response.resultcode = result;
+ resp->response.errormessage = errstr;
+ resp->response.dn = NULL;
+ resp->response.referral = NULL;
+ resp->SASL.secblob = NULL;
+
+ ldapsrv_queue_reply(call, reply);
+ return NT_STATUS_OK;
+}
+
+static void ldapsrv_BindSimple_done(struct tevent_req *subreq)
+{
+ struct ldapsrv_call *call =
+ tevent_req_callback_data(subreq,
+ struct ldapsrv_call);
+ struct ldapsrv_bind_wait_context *bind_wait =
+ talloc_get_type_abort(call->wait_private,
+ struct ldapsrv_bind_wait_context);
+ struct ldapsrv_reply *reply = bind_wait->reply;
+ struct auth_session_info *session_info = NULL;
+ NTSTATUS status;
+ struct ldap_BindResponse *resp = NULL;
+ int result;
+ const char *errstr = NULL;
+
+ status = authenticate_ldap_simple_bind_recv(subreq,
+ call,
+ &session_info);
if (NT_STATUS_IS_OK(status)) {
result = LDAP_SUCCESS;
errstr = NULL;
@@ -132,7 +262,6 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
0x0C0903A9, status);
}
-do_reply:
resp = &reply->msg->r.BindResponse;
resp->response.resultcode = result;
resp->response.errormessage = errstr;
@@ -141,7 +270,7 @@ do_reply:
resp->SASL.secblob = NULL;
ldapsrv_queue_reply(call, reply);
- return NT_STATUS_OK;
+ ldapsrv_bind_wait_finished(call, NT_STATUS_OK);
}
struct ldapsrv_sasl_postprocess_context {
--
1.9.1
From 054a1822d5958475aa7d24e9b8de3fe37aae67db Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 11 May 2017 18:53:06 +0200
Subject: [PATCH 09/30] s4:auth: make authenticate_ldap_simple_bind*() use
auth_check_password_send/recv
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/auth/ntlm/auth_simple.c | 159 +++++++++++++++++++---------------------
1 file changed, 77 insertions(+), 82 deletions(-)
diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c
index 142bd40..c3bc25a 100644
--- a/source4/auth/ntlm/auth_simple.c
+++ b/source4/auth/ntlm/auth_simple.c
@@ -28,9 +28,14 @@
#include "dsdb/samdb/samdb.h"
struct authenticate_ldap_simple_bind_state {
+ bool using_tls;
+ struct auth4_context *auth_context;
+ struct auth_usersupplied_info *user_info;
struct auth_session_info *session_info;
};
+static void authenticate_ldap_simple_bind_done(struct tevent_req *subreq);
+
_PUBLIC_ struct tevent_req *authenticate_ldap_simple_bind_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct imessaging_context *msg,
@@ -43,6 +48,10 @@ _PUBLIC_ struct tevent_req *authenticate_ldap_simple_bind_send(TALLOC_CTX *mem_c
{
struct tevent_req *req = NULL;
struct authenticate_ldap_simple_bind_state *state = NULL;
+ struct auth_usersupplied_info *user_info = NULL;
+ const char *nt4_domain = NULL;
+ const char *nt4_username = NULL;
+ struct tevent_req *subreq = NULL;
NTSTATUS status;
req = tevent_req_create(mem_ctx, &state,
@@ -50,76 +59,23 @@ _PUBLIC_ struct tevent_req *authenticate_ldap_simple_bind_send(TALLOC_CTX *mem_c
if (req == NULL) {
return NULL;
}
+ state->using_tls = using_tls;
- status = authenticate_ldap_simple_bind(state, ev, msg, lp_ctx,
- remote_address,
- local_address,
- using_tls,
- dn, password,
- &state->session_info);
+ status = auth_context_create(state, ev, msg, lp_ctx,
+ &state->auth_context);
if (tevent_req_nterror(req, status)) {
return tevent_req_post(req, ev);
}
- tevent_req_done(req);
- return tevent_req_post(req, ev);
-}
-
-_PUBLIC_ NTSTATUS authenticate_ldap_simple_bind(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct imessaging_context *msg,
- struct loadparm_context *lp_ctx,
- struct tsocket_address *remote_address,
- struct tsocket_address *local_address,
- bool using_tls,
- const char *dn,
- const char *password,
- struct auth_session_info **session_info)
-{
- struct auth4_context *auth_context;
- struct auth_usersupplied_info *user_info;
- struct auth_user_info_dc *user_info_dc;
- NTSTATUS nt_status;
- uint8_t authoritative = 0;
- TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
- const char *nt4_domain = NULL;
- const char *nt4_username = NULL;
- uint32_t flags = 0;
- const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE;
- if (using_tls) {
- transport_protection = AUTHZ_TRANSPORT_PROTECTION_TLS;
- }
-
- if (!tmp_ctx) {
- return NT_STATUS_NO_MEMORY;
- }
-
- nt_status = auth_context_create(tmp_ctx,
- ev, msg,
- lp_ctx,
- &auth_context);
- if (!NT_STATUS_IS_OK(nt_status)) {
- talloc_free(tmp_ctx);
- return nt_status;
- }
-
- /*
- * We check the error after building the user_info so we can
- * log a failure to find the user correctly
- */
- nt_status = crack_auto_name_to_nt4_name(tmp_ctx, ev, lp_ctx, dn,
- &nt4_domain, &nt4_username);
-
- user_info = talloc_zero(tmp_ctx, struct auth_usersupplied_info);
- if (!user_info) {
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
+ user_info = talloc_zero(state, struct auth_usersupplied_info);
+ if (tevent_req_nomem(user_info, req)) {
+ return tevent_req_post(req, ev);
}
+ state->user_info = user_info;
user_info->client.account_name = dn;
/* No client.domain_name, use account_name instead */
- user_info->mapped.account_name = nt4_username;
- user_info->mapped.domain_name = nt4_domain;
+ /* user_info->mapped.* will be filled below */
user_info->workstation_name = NULL;
@@ -136,6 +92,9 @@ _PUBLIC_ NTSTATUS authenticate_ldap_simple_bind(TALLOC_CTX *mem_ctx,
user_info->password_state = AUTH_PASSWORD_PLAIN;
user_info->password.plaintext = talloc_strdup(user_info, password);
+ if (tevent_req_nomem(user_info->password.plaintext, req)) {
+ return tevent_req_post(req, ev);
+ }
user_info->flags = USER_INFO_CASE_INSENSITIVE_USERNAME |
USER_INFO_DONT_CHECK_UNIX_ACCOUNT;
@@ -146,39 +105,76 @@ _PUBLIC_ NTSTATUS authenticate_ldap_simple_bind(TALLOC_CTX *mem_ctx,
MSV1_0_CLEARTEXT_PASSWORD_ALLOWED |
MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED;
- /* This is a check for the crack names call above */
- if (!NT_STATUS_IS_OK(nt_status)) {
- log_authentication_event(auth_context->msg_ctx,
- auth_context->lp_ctx,
- user_info, nt_status,
+ status = crack_auto_name_to_nt4_name(state, ev, lp_ctx, dn,
+ &nt4_domain, &nt4_username);
+ if (!NT_STATUS_IS_OK(status)) {
+ log_authentication_event(msg, lp_ctx,
+ user_info, status,
NULL, NULL, NULL, NULL);
- talloc_free(tmp_ctx);
- return nt_status;
+ }
+ if (tevent_req_nterror(req, status)) {
+ return tevent_req_post(req, ev);
}
- /* Now that we have checked if the crack names worked, set mapped_state */
+ user_info->mapped.account_name = nt4_username;
+ user_info->mapped.domain_name = nt4_domain;
user_info->mapped_state = true;
- nt_status = auth_check_password(auth_context, tmp_ctx, user_info,
- &user_info_dc, &authoritative);
- if (!NT_STATUS_IS_OK(nt_status)) {
- talloc_free(tmp_ctx);
- return nt_status;
+ subreq = auth_check_password_send(state, ev,
+ state->auth_context,
+ state->user_info);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, authenticate_ldap_simple_bind_done, req);
+
+ return req;
+}
+
+static void authenticate_ldap_simple_bind_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req =
+ tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct authenticate_ldap_simple_bind_state *state =
+ tevent_req_data(req,
+ struct authenticate_ldap_simple_bind_state);
+ struct auth4_context *auth_context = state->auth_context;
+ struct auth_usersupplied_info *user_info = state->user_info;
+ const char *nt4_username = user_info->mapped.account_name;
+ const struct tsocket_address *remote_address = user_info->remote_host;
+ const struct tsocket_address *local_address = user_info->local_host;
+ const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE;
+ struct auth_user_info_dc *user_info_dc = NULL;
+ uint8_t authoritative = 0;
+ uint32_t flags = 0;
+ NTSTATUS nt_status;
+
+ if (state->using_tls) {
+ transport_protection = AUTHZ_TRANSPORT_PROTECTION_TLS;
+ }
+
+ nt_status = auth_check_password_recv(subreq, state,
+ &user_info_dc,
+ &authoritative);
+ TALLOC_FREE(subreq);
+ if (tevent_req_nterror(req, nt_status)) {
+ return;
}
flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
if (user_info_dc->info->authenticated) {
flags |= AUTH_SESSION_INFO_AUTHENTICATED;
}
+
nt_status = auth_context->generate_session_info(auth_context,
- tmp_ctx,
+ state,
user_info_dc,
nt4_username,
flags,
- session_info);
-
- if (NT_STATUS_IS_OK(nt_status)) {
- talloc_steal(mem_ctx, *session_info);
+ &state->session_info);
+ if (tevent_req_nterror(req, nt_status)) {
+ return;
}
log_successful_authz_event(auth_context->msg_ctx,
@@ -188,10 +184,9 @@ _PUBLIC_ NTSTATUS authenticate_ldap_simple_bind(TALLOC_CTX *mem_ctx,
"LDAP",
"simple bind",
transport_protection,
- *session_info);
+ state->session_info);
- talloc_free(tmp_ctx);
- return nt_status;
+ tevent_req_done(req);
}
_PUBLIC_ NTSTATUS authenticate_ldap_simple_bind_recv(struct tevent_req *req,
--
1.9.1
From e176b5885aafc51d54c091b7ee694d93c828445a Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 11 May 2017 19:04:27 +0200
Subject: [PATCH 10/30] s4:ldap_server: add use goto do_reply; to make the
logic in ldapsrv_BindSASL() more sane
The following patches will simplify the logic by avoiding else branches
by using early returns.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 23d34d2..3f2cd2b 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -401,6 +401,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
result = LDAP_OPERATIONS_ERROR;
errstr = talloc_asprintf(reply, "SASL: Failed to start authentication system: %s",
nt_errstr(status));
+ goto do_reply;
}
}
@@ -426,6 +427,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
if (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) {
result = LDAP_SASL_BIND_IN_PROGRESS;
errstr = NULL;
+ goto do_reply;
} else if (NT_STATUS_IS_OK(status)) {
struct ldapsrv_sasl_postprocess_context *context = NULL;
@@ -449,6 +451,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
errstr = talloc_asprintf(reply,
"SASL:[%s]: Sign or Seal are not allowed if TLS is used",
req->creds.SASL.mechanism);
+ goto do_reply;
}
if (context && conn->sockets.sasl) {
@@ -458,6 +461,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
errstr = talloc_asprintf(reply,
"SASL:[%s]: Sign or Seal are not allowed if SASL encryption has already been set up",
req->creds.SASL.mechanism);
+ goto do_reply;
}
if (context) {
@@ -484,14 +488,15 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
errstr = talloc_asprintf(reply,
"SASL:[%s]: not allowed if TLS is used.",
req->creds.SASL.mechanism);
- break;
+ goto do_reply;
+
case LDAP_SERVER_REQUIRE_STRONG_AUTH_YES:
status = NT_STATUS_NETWORK_ACCESS_DENIED;
result = LDAP_STRONG_AUTH_REQUIRED;
errstr = talloc_asprintf(reply,
"SASL:[%s]: Sign or Seal are required.",
req->creds.SASL.mechanism);
- break;
+ goto do_reply;
}
}
@@ -501,6 +506,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
errstr = talloc_asprintf(reply,
"SASL:[%s]: Failed to setup SASL socket: %s",
req->creds.SASL.mechanism, nt_errstr(status));
+ goto do_reply;
} else {
struct auth_session_info *old_session_info=NULL;
@@ -513,6 +519,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
errstr = talloc_asprintf(reply,
"SASL:[%s]: Failed to get session info: %s",
req->creds.SASL.mechanism, nt_errstr(status));
+ goto do_reply;
} else {
talloc_unlink(conn, old_session_info);
@@ -529,6 +536,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
"SASL:[%s]: Failed to advise samdb of new credentials: %s",
req->creds.SASL.mechanism,
nt_errstr(status));
+ goto do_reply;
}
}
}
@@ -549,8 +557,10 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
}
talloc_unlink(conn, conn->gensec);
conn->gensec = NULL;
+ goto do_reply;
}
+do_reply:
resp->response.resultcode = result;
resp->response.dn = NULL;
resp->response.errormessage = errstr;
--
1.9.1
From f251e71ab1b9b1b8a94e8ff707f428317bf4825a Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 11 May 2017 19:11:43 +0200
Subject: [PATCH 11/30] s4:ldap_server: always allocate resp->SASL.secblob
The code path with resp->SASL.secblob = NULL was completely untested
(and wrong) as ldapsrv_setup_gensec() is very unlikely to ever fail.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 3f2cd2b..4913629 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -382,7 +382,12 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
return NT_STATUS_NO_MEMORY;
}
resp = &reply->msg->r.BindResponse;
-
+ /* Windows 2000 mmc doesn't like secblob == NULL and reports a decoding error */
+ resp->SASL.secblob = talloc_zero(reply, DATA_BLOB);
+ if (resp->SASL.secblob == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
conn = call->conn;
/*
@@ -416,12 +421,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
status = gensec_update_ev(conn->gensec, reply, conn->connection->event.ctx,
input, &output);
- /* Windows 2000 mmc doesn't like secblob == NULL and reports a decoding error */
- resp->SASL.secblob = talloc(reply, DATA_BLOB);
- NT_STATUS_HAVE_NO_MEMORY(resp->SASL.secblob);
*resp->SASL.secblob = output;
- } else {
- resp->SASL.secblob = NULL;
}
if (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) {
--
1.9.1
From 9ca6a69d1bb44d4c630cb8334f0924879e083ca4 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 11 May 2017 19:13:49 +0200
Subject: [PATCH 12/30] s4:ldap_server: remove an useless indentation level
from gensec_update_ev()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 4913629..fb4593d 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -374,6 +374,8 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
int result = 0;
const char *errstr=NULL;
NTSTATUS status = NT_STATUS_OK;
+ DATA_BLOB input = data_blob_null;
+ DATA_BLOB output = data_blob_null;
DEBUG(10, ("BindSASL dn: %s\n",req->dn));
@@ -410,20 +412,14 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
}
}
- if (NT_STATUS_IS_OK(status)) {
- DATA_BLOB input = data_blob(NULL, 0);
- DATA_BLOB output = data_blob(NULL, 0);
-
- if (req->creds.SASL.secblob) {
- input = *req->creds.SASL.secblob;
- }
-
- status = gensec_update_ev(conn->gensec, reply, conn->connection->event.ctx,
- input, &output);
-
- *resp->SASL.secblob = output;
+ if (req->creds.SASL.secblob) {
+ input = *req->creds.SASL.secblob;
}
+ status = gensec_update_ev(conn->gensec, reply, conn->connection->event.ctx,
+ input, &output);
+ *resp->SASL.secblob = output;
+
if (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) {
result = LDAP_SASL_BIND_IN_PROGRESS;
errstr = NULL;
--
1.9.1
From c2e14005e1e1312d5807bbf8edbdd264bb874a20 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 11 May 2017 21:09:08 +0200
Subject: [PATCH 13/30] s4:ldap_server: move invalid credential handling before
the success handling.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index fb4593d..e36cb1c 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -424,7 +424,21 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
result = LDAP_SASL_BIND_IN_PROGRESS;
errstr = NULL;
goto do_reply;
- } else if (NT_STATUS_IS_OK(status)) {
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ status = nt_status_squash(status);
+ if (result == 0) {
+ result = LDAP_INVALID_CREDENTIALS;
+ errstr = ldapsrv_bind_error_msg(reply, HRES_SEC_E_LOGON_DENIED,
+ 0x0C0904DC, status);
+ }
+ talloc_unlink(conn, conn->gensec);
+ conn->gensec = NULL;
+ goto do_reply;
+ }
+
+ {
struct ldapsrv_sasl_postprocess_context *context = NULL;
result = LDAP_SUCCESS;
@@ -544,16 +558,6 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
}
talloc_unlink(conn, conn->gensec);
conn->gensec = NULL;
- } else {
- status = nt_status_squash(status);
- if (result == 0) {
- result = LDAP_INVALID_CREDENTIALS;
- errstr = ldapsrv_bind_error_msg(reply, HRES_SEC_E_LOGON_DENIED,
- 0x0C0904DC, status);
- }
- talloc_unlink(conn, conn->gensec);
- conn->gensec = NULL;
- goto do_reply;
}
do_reply:
--
1.9.1
From 7cac23931a37313a258bd750517dd75ab49a534d Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 12 May 2017 16:04:02 +0200
Subject: [PATCH 14/30] s4:ldap_server: avoid pointless check arround
LDAP_INVALID_CREDENTIALS
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index e36cb1c..06b52fe 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -428,11 +428,9 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
if (!NT_STATUS_IS_OK(status)) {
status = nt_status_squash(status);
- if (result == 0) {
- result = LDAP_INVALID_CREDENTIALS;
- errstr = ldapsrv_bind_error_msg(reply, HRES_SEC_E_LOGON_DENIED,
- 0x0C0904DC, status);
- }
+ result = LDAP_INVALID_CREDENTIALS;
+ errstr = ldapsrv_bind_error_msg(reply, HRES_SEC_E_LOGON_DENIED,
+ 0x0C0904DC, status);
talloc_unlink(conn, conn->gensec);
conn->gensec = NULL;
goto do_reply;
--
1.9.1
From 061888b46db040d8db2609dd5b9c5ca972b13c5d Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 12 May 2017 12:44:05 +0200
Subject: [PATCH 15/30] s4:ldap_server: make sure we destroy the gensec context
on error
If the client tries a new bind we need to start with a fresh context.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 06b52fe..5c390b6 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -431,8 +431,6 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
result = LDAP_INVALID_CREDENTIALS;
errstr = ldapsrv_bind_error_msg(reply, HRES_SEC_E_LOGON_DENIED,
0x0C0904DC, status);
- talloc_unlink(conn, conn->gensec);
- conn->gensec = NULL;
goto do_reply;
}
@@ -559,6 +557,18 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
}
do_reply:
+ if (result != LDAP_SASL_BIND_IN_PROGRESS) {
+ /*
+ * We should destroy the gensec context
+ * when we hit a fatal error.
+ *
+ * Note: conn->gensec is already cleared
+ * for the LDAP_SUCCESS case.
+ */
+ talloc_unlink(conn, conn->gensec);
+ conn->gensec = NULL;
+ }
+
resp->response.resultcode = result;
resp->response.dn = NULL;
resp->response.errormessage = errstr;
--
1.9.1
From 216c9e59f830119b966a0216bdb3039a1b85d959 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 11 May 2017 21:11:00 +0200
Subject: [PATCH 16/30] s4:ldap_server: remove indentation level for the valid
credential case
Check with git show -w.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 181 ++++++++++++++++++++--------------------
1 file changed, 89 insertions(+), 92 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 5c390b6..337ce12 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -371,6 +371,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
struct ldapsrv_reply *reply;
struct ldap_BindResponse *resp;
struct ldapsrv_connection *conn;
+ struct ldapsrv_sasl_postprocess_context *context = NULL;
int result = 0;
const char *errstr=NULL;
NTSTATUS status = NT_STATUS_OK;
@@ -434,127 +435,123 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
goto do_reply;
}
- {
- struct ldapsrv_sasl_postprocess_context *context = NULL;
+ result = LDAP_SUCCESS;
+ errstr = NULL;
- result = LDAP_SUCCESS;
- errstr = NULL;
+ if (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) ||
+ gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
- if (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) ||
- gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
+ context = talloc(call, struct ldapsrv_sasl_postprocess_context);
+
+ if (!context) {
+ status = NT_STATUS_NO_MEMORY;
+ }
+ }
- context = talloc(call, struct ldapsrv_sasl_postprocess_context);
+ if (context && conn->sockets.tls) {
+ TALLOC_FREE(context);
+ status = NT_STATUS_NOT_SUPPORTED;
+ result = LDAP_UNWILLING_TO_PERFORM;
+ errstr = talloc_asprintf(reply,
+ "SASL:[%s]: Sign or Seal are not allowed if TLS is used",
+ req->creds.SASL.mechanism);
+ goto do_reply;
+ }
- if (!context) {
+ if (context && conn->sockets.sasl) {
+ TALLOC_FREE(context);
+ status = NT_STATUS_NOT_SUPPORTED;
+ result = LDAP_UNWILLING_TO_PERFORM;
+ errstr = talloc_asprintf(reply,
+ "SASL:[%s]: Sign or Seal are not allowed if SASL encryption has already been set up",
+ req->creds.SASL.mechanism);
+ goto do_reply;
+ }
+
+ if (context) {
+ context->conn = conn;
+ status = gensec_create_tstream(context,
+ context->conn->gensec,
+ context->conn->sockets.raw,
+ &context->sasl);
+ if (NT_STATUS_IS_OK(status)) {
+ if (!talloc_reference(context->sasl, conn->gensec)) {
status = NT_STATUS_NO_MEMORY;
}
}
-
- if (context && conn->sockets.tls) {
- TALLOC_FREE(context);
- status = NT_STATUS_NOT_SUPPORTED;
- result = LDAP_UNWILLING_TO_PERFORM;
+ } else {
+ switch (call->conn->require_strong_auth) {
+ case LDAP_SERVER_REQUIRE_STRONG_AUTH_NO:
+ break;
+ case LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS:
+ if (call->conn->sockets.active == call->conn->sockets.tls) {
+ break;
+ }
+ status = NT_STATUS_NETWORK_ACCESS_DENIED;
+ result = LDAP_STRONG_AUTH_REQUIRED;
errstr = talloc_asprintf(reply,
- "SASL:[%s]: Sign or Seal are not allowed if TLS is used",
- req->creds.SASL.mechanism);
+ "SASL:[%s]: not allowed if TLS is used.",
+ req->creds.SASL.mechanism);
goto do_reply;
- }
- if (context && conn->sockets.sasl) {
- TALLOC_FREE(context);
- status = NT_STATUS_NOT_SUPPORTED;
- result = LDAP_UNWILLING_TO_PERFORM;
+ case LDAP_SERVER_REQUIRE_STRONG_AUTH_YES:
+ status = NT_STATUS_NETWORK_ACCESS_DENIED;
+ result = LDAP_STRONG_AUTH_REQUIRED;
errstr = talloc_asprintf(reply,
- "SASL:[%s]: Sign or Seal are not allowed if SASL encryption has already been set up",
- req->creds.SASL.mechanism);
+ "SASL:[%s]: Sign or Seal are required.",
+ req->creds.SASL.mechanism);
goto do_reply;
}
+ }
- if (context) {
- context->conn = conn;
- status = gensec_create_tstream(context,
- context->conn->gensec,
- context->conn->sockets.raw,
- &context->sasl);
- if (NT_STATUS_IS_OK(status)) {
- if (!talloc_reference(context->sasl, conn->gensec)) {
- status = NT_STATUS_NO_MEMORY;
- }
- }
- } else {
- switch (call->conn->require_strong_auth) {
- case LDAP_SERVER_REQUIRE_STRONG_AUTH_NO:
- break;
- case LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS:
- if (call->conn->sockets.active == call->conn->sockets.tls) {
- break;
- }
- status = NT_STATUS_NETWORK_ACCESS_DENIED;
- result = LDAP_STRONG_AUTH_REQUIRED;
- errstr = talloc_asprintf(reply,
- "SASL:[%s]: not allowed if TLS is used.",
- req->creds.SASL.mechanism);
- goto do_reply;
-
- case LDAP_SERVER_REQUIRE_STRONG_AUTH_YES:
- status = NT_STATUS_NETWORK_ACCESS_DENIED;
- result = LDAP_STRONG_AUTH_REQUIRED;
- errstr = talloc_asprintf(reply,
- "SASL:[%s]: Sign or Seal are required.",
- req->creds.SASL.mechanism);
- goto do_reply;
- }
- }
+ if (result != LDAP_SUCCESS) {
+ } else if (!NT_STATUS_IS_OK(status)) {
+ result = LDAP_OPERATIONS_ERROR;
+ errstr = talloc_asprintf(reply,
+ "SASL:[%s]: Failed to setup SASL socket: %s",
+ req->creds.SASL.mechanism, nt_errstr(status));
+ goto do_reply;
+ } else {
+ struct auth_session_info *old_session_info=NULL;
- if (result != LDAP_SUCCESS) {
- } else if (!NT_STATUS_IS_OK(status)) {
+ old_session_info = conn->session_info;
+ conn->session_info = NULL;
+ status = gensec_session_info(conn->gensec, conn, &conn->session_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ conn->session_info = old_session_info;
result = LDAP_OPERATIONS_ERROR;
errstr = talloc_asprintf(reply,
- "SASL:[%s]: Failed to setup SASL socket: %s",
+ "SASL:[%s]: Failed to get session info: %s",
req->creds.SASL.mechanism, nt_errstr(status));
goto do_reply;
} else {
- struct auth_session_info *old_session_info=NULL;
+ talloc_unlink(conn, old_session_info);
+
+ /* don't leak the old LDB */
+ talloc_unlink(conn, conn->ldb);
+
+ call->conn->authz_logged = true;
+
+ status = ldapsrv_backend_Init(conn);
- old_session_info = conn->session_info;
- conn->session_info = NULL;
- status = gensec_session_info(conn->gensec, conn, &conn->session_info);
if (!NT_STATUS_IS_OK(status)) {
- conn->session_info = old_session_info;
result = LDAP_OPERATIONS_ERROR;
errstr = talloc_asprintf(reply,
- "SASL:[%s]: Failed to get session info: %s",
- req->creds.SASL.mechanism, nt_errstr(status));
+ "SASL:[%s]: Failed to advise samdb of new credentials: %s",
+ req->creds.SASL.mechanism,
+ nt_errstr(status));
goto do_reply;
- } else {
- talloc_unlink(conn, old_session_info);
-
- /* don't leak the old LDB */
- talloc_unlink(conn, conn->ldb);
-
- call->conn->authz_logged = true;
-
- status = ldapsrv_backend_Init(conn);
-
- if (!NT_STATUS_IS_OK(status)) {
- result = LDAP_OPERATIONS_ERROR;
- errstr = talloc_asprintf(reply,
- "SASL:[%s]: Failed to advise samdb of new credentials: %s",
- req->creds.SASL.mechanism,
- nt_errstr(status));
- goto do_reply;
- }
}
}
+ }
- if (NT_STATUS_IS_OK(status) && context) {
- call->postprocess_send = ldapsrv_sasl_postprocess_send;
- call->postprocess_recv = ldapsrv_sasl_postprocess_recv;
- call->postprocess_private = context;
- }
- talloc_unlink(conn, conn->gensec);
- conn->gensec = NULL;
+ if (NT_STATUS_IS_OK(status) && context) {
+ call->postprocess_send = ldapsrv_sasl_postprocess_send;
+ call->postprocess_recv = ldapsrv_sasl_postprocess_recv;
+ call->postprocess_private = context;
}
+ talloc_unlink(conn, conn->gensec);
+ conn->gensec = NULL;
do_reply:
if (result != LDAP_SASL_BIND_IN_PROGRESS) {
--
1.9.1
From e0706b4f0085c34691286f09116fdfa60af15989 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 11 May 2017 21:14:00 +0200
Subject: [PATCH 17/30] s4:ldap_server: only set *resp->SASL.secblob = output
for OK or MORE_PROCESSING_REQUIRED
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 337ce12..451f9d5 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -419,9 +419,9 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
status = gensec_update_ev(conn->gensec, reply, conn->connection->event.ctx,
input, &output);
- *resp->SASL.secblob = output;
if (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) {
+ *resp->SASL.secblob = output;
result = LDAP_SASL_BIND_IN_PROGRESS;
errstr = NULL;
goto do_reply;
@@ -553,6 +553,8 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
talloc_unlink(conn, conn->gensec);
conn->gensec = NULL;
+ *resp->SASL.secblob = output;
+
do_reply:
if (result != LDAP_SASL_BIND_IN_PROGRESS) {
/*
--
1.9.1
From c833b071fd05cf2a61ec28841e1ef3658caac4c3 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 11 May 2017 21:17:40 +0200
Subject: [PATCH 18/30] s4:ldap_server: drop the connection if we fail to
allocate ldapsrv_sasl_postprocess_context
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 451f9d5..64ee1b3 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -442,9 +442,8 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
context = talloc(call, struct ldapsrv_sasl_postprocess_context);
-
- if (!context) {
- status = NT_STATUS_NO_MEMORY;
+ if (context == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
}
--
1.9.1
From 9f0e76089bcce23d734087b5dc138e81eb948c80 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 11 May 2017 21:18:07 +0200
Subject: [PATCH 19/30] s4:ldap_server: use talloc_zero for
ldapsrv_sasl_postprocess_context
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 64ee1b3..e259727 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -441,7 +441,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
if (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) ||
gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
- context = talloc(call, struct ldapsrv_sasl_postprocess_context);
+ context = talloc_zero(call, struct ldapsrv_sasl_postprocess_context);
if (context == NULL) {
return NT_STATUS_NO_MEMORY;
}
--
1.9.1
From d9431efc628b6fcb51c3953dede8911c942f9b0a Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 12 May 2017 12:04:59 +0200
Subject: [PATCH 20/30] s4:ldap_server: do the transport validation before
calling gensec_create_tstream()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index e259727..6a88891 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -467,18 +467,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
goto do_reply;
}
- if (context) {
- context->conn = conn;
- status = gensec_create_tstream(context,
- context->conn->gensec,
- context->conn->sockets.raw,
- &context->sasl);
- if (NT_STATUS_IS_OK(status)) {
- if (!talloc_reference(context->sasl, conn->gensec)) {
- status = NT_STATUS_NO_MEMORY;
- }
- }
- } else {
+ if (context == NULL) {
switch (call->conn->require_strong_auth) {
case LDAP_SERVER_REQUIRE_STRONG_AUTH_NO:
break;
@@ -503,6 +492,19 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
}
}
+ if (context != NULL) {
+ context->conn = conn;
+ status = gensec_create_tstream(context,
+ context->conn->gensec,
+ context->conn->sockets.raw,
+ &context->sasl);
+ if (NT_STATUS_IS_OK(status)) {
+ if (!talloc_reference(context->sasl, conn->gensec)) {
+ status = NT_STATUS_NO_MEMORY;
+ }
+ }
+ }
+
if (result != LDAP_SUCCESS) {
} else if (!NT_STATUS_IS_OK(status)) {
result = LDAP_OPERATIONS_ERROR;
--
1.9.1
From bee3340a40c47745fe35ed3bb7a5237ea57c9ed6 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 12 May 2017 12:07:31 +0200
Subject: [PATCH 21/30] s4:ldap_server: remove pointless (result !=
LDAP_SUCCESS) check
We set result = LDAP_SUCCESS above and have goto do_reply;
in all cases where we overwrite 'result'.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 6a88891..7f14384 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -505,8 +505,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
}
}
- if (result != LDAP_SUCCESS) {
- } else if (!NT_STATUS_IS_OK(status)) {
+ if (!NT_STATUS_IS_OK(status)) {
result = LDAP_OPERATIONS_ERROR;
errstr = talloc_asprintf(reply,
"SASL:[%s]: Failed to setup SASL socket: %s",
--
1.9.1
From 795dfd345bce05d852ffe9ca114603cbf0cba627 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 12 May 2017 12:09:38 +0200
Subject: [PATCH 22/30] s4:ldap_server: terminate the connection if
talloc_reference fails
talloc_reference will be removed completely in the next commits...
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 7f14384..25fe528 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -500,7 +500,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
&context->sasl);
if (NT_STATUS_IS_OK(status)) {
if (!talloc_reference(context->sasl, conn->gensec)) {
- status = NT_STATUS_NO_MEMORY;
+ return NT_STATUS_NO_MEMORY;
}
}
}
--
1.9.1
From 19ac233dfee85381b8f4f40101165ff697328180 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 13 Jun 2017 15:28:53 +0200
Subject: [PATCH 23/30] s4:ldap_server: only touch conn->session_info on
success in ldapsrv_BindSASL()
The old conn->session_info (as well as conn->ldb) should only be changed
after a successful Bind().
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 25fe528..352e67d 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -377,6 +377,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
NTSTATUS status = NT_STATUS_OK;
DATA_BLOB input = data_blob_null;
DATA_BLOB output = data_blob_null;
+ struct auth_session_info *session_info = NULL;
DEBUG(10, ("BindSASL dn: %s\n",req->dn));
@@ -512,20 +513,17 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
req->creds.SASL.mechanism, nt_errstr(status));
goto do_reply;
} else {
- struct auth_session_info *old_session_info=NULL;
- old_session_info = conn->session_info;
- conn->session_info = NULL;
- status = gensec_session_info(conn->gensec, conn, &conn->session_info);
+ status = gensec_session_info(conn->gensec, call, &session_info);
if (!NT_STATUS_IS_OK(status)) {
- conn->session_info = old_session_info;
result = LDAP_OPERATIONS_ERROR;
errstr = talloc_asprintf(reply,
"SASL:[%s]: Failed to get session info: %s",
req->creds.SASL.mechanism, nt_errstr(status));
goto do_reply;
} else {
- talloc_unlink(conn, old_session_info);
+ talloc_unlink(conn, conn->session_info);
+ conn->session_info = talloc_steal(conn, session_info);
/* don't leak the old LDB */
talloc_unlink(conn, conn->ldb);
--
1.9.1
From 1ec9a7c22bb77675a4d7290b8b31ac5d71f80471 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 12 May 2017 12:26:12 +0200
Subject: [PATCH 24/30] s4:ldap_server: make the gensec_create_tstream() error
checking more clear
Check with 'git show -w'.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 352e67d..cd6b7e4 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -499,21 +499,20 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
context->conn->gensec,
context->conn->sockets.raw,
&context->sasl);
- if (NT_STATUS_IS_OK(status)) {
- if (!talloc_reference(context->sasl, conn->gensec)) {
- return NT_STATUS_NO_MEMORY;
- }
- }
- }
-
- if (!NT_STATUS_IS_OK(status)) {
- result = LDAP_OPERATIONS_ERROR;
- errstr = talloc_asprintf(reply,
+ if (!NT_STATUS_IS_OK(status)) {
+ result = LDAP_OPERATIONS_ERROR;
+ errstr = talloc_asprintf(reply,
"SASL:[%s]: Failed to setup SASL socket: %s",
req->creds.SASL.mechanism, nt_errstr(status));
- goto do_reply;
- } else {
+ goto do_reply;
+ }
+ if (!talloc_reference(context->sasl, conn->gensec)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ {
status = gensec_session_info(conn->gensec, call, &session_info);
if (!NT_STATUS_IS_OK(status)) {
result = LDAP_OPERATIONS_ERROR;
--
1.9.1
From 026a7dd94b60ef5dd437f2937c3293da02f725ab Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 12 May 2017 12:27:26 +0200
Subject: [PATCH 25/30] s4:ldap_server: remove useless indentation level
arround gensec_session_info()
Check with git show -w
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 44 ++++++++++++++++++++---------------------
1 file changed, 21 insertions(+), 23 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index cd6b7e4..c33eaac 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -512,33 +512,31 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
}
}
- {
- status = gensec_session_info(conn->gensec, call, &session_info);
- if (!NT_STATUS_IS_OK(status)) {
- result = LDAP_OPERATIONS_ERROR;
- errstr = talloc_asprintf(reply,
- "SASL:[%s]: Failed to get session info: %s",
- req->creds.SASL.mechanism, nt_errstr(status));
- goto do_reply;
- } else {
- talloc_unlink(conn, conn->session_info);
- conn->session_info = talloc_steal(conn, session_info);
+ status = gensec_session_info(conn->gensec, call, &session_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ result = LDAP_OPERATIONS_ERROR;
+ errstr = talloc_asprintf(reply,
+ "SASL:[%s]: Failed to get session info: %s",
+ req->creds.SASL.mechanism, nt_errstr(status));
+ goto do_reply;
+ } else {
+ talloc_unlink(conn, conn->session_info);
+ conn->session_info = talloc_steal(conn, session_info);
- /* don't leak the old LDB */
- talloc_unlink(conn, conn->ldb);
+ /* don't leak the old LDB */
+ talloc_unlink(conn, conn->ldb);
- call->conn->authz_logged = true;
+ call->conn->authz_logged = true;
- status = ldapsrv_backend_Init(conn);
+ status = ldapsrv_backend_Init(conn);
- if (!NT_STATUS_IS_OK(status)) {
- result = LDAP_OPERATIONS_ERROR;
- errstr = talloc_asprintf(reply,
- "SASL:[%s]: Failed to advise samdb of new credentials: %s",
- req->creds.SASL.mechanism,
- nt_errstr(status));
- goto do_reply;
- }
+ if (!NT_STATUS_IS_OK(status)) {
+ result = LDAP_OPERATIONS_ERROR;
+ errstr = talloc_asprintf(reply,
+ "SASL:[%s]: Failed to advise samdb of new credentials: %s",
+ req->creds.SASL.mechanism,
+ nt_errstr(status));
+ goto do_reply;
}
}
--
1.9.1
From 38cc0616f19d8d668a4471fa2a86ea6b7bde17e8 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 12 May 2017 12:27:26 +0200
Subject: [PATCH 26/30] s4:ldap_server: remove useless indentation level
arround ldapsrv_backend_Init()
Check with git show -w
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index c33eaac..51440cb 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -519,25 +519,25 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
"SASL:[%s]: Failed to get session info: %s",
req->creds.SASL.mechanism, nt_errstr(status));
goto do_reply;
- } else {
- talloc_unlink(conn, conn->session_info);
- conn->session_info = talloc_steal(conn, session_info);
+ }
- /* don't leak the old LDB */
- talloc_unlink(conn, conn->ldb);
+ talloc_unlink(conn, conn->session_info);
+ conn->session_info = talloc_steal(conn, session_info);
- call->conn->authz_logged = true;
+ /* don't leak the old LDB */
+ talloc_unlink(conn, conn->ldb);
- status = ldapsrv_backend_Init(conn);
+ call->conn->authz_logged = true;
- if (!NT_STATUS_IS_OK(status)) {
- result = LDAP_OPERATIONS_ERROR;
- errstr = talloc_asprintf(reply,
- "SASL:[%s]: Failed to advise samdb of new credentials: %s",
- req->creds.SASL.mechanism,
- nt_errstr(status));
- goto do_reply;
- }
+ status = ldapsrv_backend_Init(conn);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ result = LDAP_OPERATIONS_ERROR;
+ errstr = talloc_asprintf(reply,
+ "SASL:[%s]: Failed to advise samdb of new credentials: %s",
+ req->creds.SASL.mechanism,
+ nt_errstr(status));
+ goto do_reply;
}
if (NT_STATUS_IS_OK(status) && context) {
--
1.9.1
From 2b8d14cf8cb753f37c30cf83b8ce9712aa967df5 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 12 May 2017 12:31:25 +0200
Subject: [PATCH 27/30] s4:ldap_server: remove useless NT_STATUS_IS_OK(status)
check
We checked a few lines above already, check with:
git show -U10
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 51440cb..3ba7ea3 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -540,7 +540,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
goto do_reply;
}
- if (NT_STATUS_IS_OK(status) && context) {
+ if (context != NULL) {
call->postprocess_send = ldapsrv_sasl_postprocess_send;
call->postprocess_recv = ldapsrv_sasl_postprocess_recv;
call->postprocess_private = context;
--
1.9.1
From a41a835e411f56f1173ddb040048227fbba1db2e Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 12 May 2017 12:38:59 +0200
Subject: [PATCH 28/30] s4:ldap_server: avoid using talloc_reference()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 3ba7ea3..7137642 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -506,10 +506,6 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
req->creds.SASL.mechanism, nt_errstr(status));
goto do_reply;
}
-
- if (!talloc_reference(context->sasl, conn->gensec)) {
- return NT_STATUS_NO_MEMORY;
- }
}
status = gensec_session_info(conn->gensec, call, &session_info);
@@ -541,11 +537,19 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
}
if (context != NULL) {
+ const void *ptr = NULL;
+
+ ptr = talloc_reparent(conn, context->sasl, conn->gensec);
+ if (ptr == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
call->postprocess_send = ldapsrv_sasl_postprocess_send;
call->postprocess_recv = ldapsrv_sasl_postprocess_recv;
call->postprocess_private = context;
+ } else {
+ talloc_unlink(conn, conn->gensec);
}
- talloc_unlink(conn, conn->gensec);
conn->gensec = NULL;
*resp->SASL.secblob = output;
--
1.9.1
From b84ffe319f1f553f0b40ca24ec659d38fa1d0572 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 12 May 2017 12:41:13 +0200
Subject: [PATCH 29/30] s4:ldap_server: set result = LDAP_SUCCESS at the end,
when we're really done
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 7137642..9336d16 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -436,9 +436,6 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
goto do_reply;
}
- result = LDAP_SUCCESS;
- errstr = NULL;
-
if (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) ||
gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
@@ -553,6 +550,8 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
conn->gensec = NULL;
*resp->SASL.secblob = output;
+ result = LDAP_SUCCESS;
+ errstr = NULL;
do_reply:
if (result != LDAP_SASL_BIND_IN_PROGRESS) {
--
1.9.1
From 57a8578cc41cce595192c96a046c0dffb9157897 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 12 May 2017 13:15:27 +0200
Subject: [PATCH 30/30] s4:ldap_server: implement async BindSASL
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source4/ldap_server/ldap_bind.c | 77 ++++++++++++++++++++++++++++++++++++-----
1 file changed, 69 insertions(+), 8 deletions(-)
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 9336d16..21cbb7b 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -365,19 +365,19 @@ static NTSTATUS ldapsrv_setup_gensec(struct ldapsrv_connection *conn,
return status;
}
+static void ldapsrv_BindSASL_done(struct tevent_req *subreq);
+
static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
{
struct ldap_BindRequest *req = &call->request->r.BindRequest;
struct ldapsrv_reply *reply;
struct ldap_BindResponse *resp;
struct ldapsrv_connection *conn;
- struct ldapsrv_sasl_postprocess_context *context = NULL;
int result = 0;
const char *errstr=NULL;
NTSTATUS status = NT_STATUS_OK;
DATA_BLOB input = data_blob_null;
- DATA_BLOB output = data_blob_null;
- struct auth_session_info *session_info = NULL;
+ struct tevent_req *subreq = NULL;
DEBUG(10, ("BindSASL dn: %s\n",req->dn));
@@ -418,8 +418,67 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
input = *req->creds.SASL.secblob;
}
- status = gensec_update_ev(conn->gensec, reply, conn->connection->event.ctx,
- input, &output);
+ subreq = gensec_update_send(call, conn->connection->event.ctx,
+ conn->gensec, input);
+ if (subreq == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ tevent_req_set_callback(subreq, ldapsrv_BindSASL_done, call);
+
+ status = ldapsrv_bind_wait_setup(call, reply);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(subreq);
+ return status;
+ }
+
+ /*
+ * The rest will be async.
+ */
+ return NT_STATUS_OK;
+
+do_reply:
+ if (result != LDAP_SASL_BIND_IN_PROGRESS) {
+ /*
+ * We should destroy the gensec context
+ * when we hit a fatal error.
+ *
+ * Note: conn->gensec is already cleared
+ * for the LDAP_SUCCESS case.
+ */
+ talloc_unlink(conn, conn->gensec);
+ conn->gensec = NULL;
+ }
+
+ resp->response.resultcode = result;
+ resp->response.dn = NULL;
+ resp->response.errormessage = errstr;
+ resp->response.referral = NULL;
+
+ ldapsrv_queue_reply(call, reply);
+ return NT_STATUS_OK;
+}
+
+static void ldapsrv_BindSASL_done(struct tevent_req *subreq)
+{
+ struct ldapsrv_call *call =
+ tevent_req_callback_data(subreq,
+ struct ldapsrv_call);
+ struct ldapsrv_bind_wait_context *bind_wait =
+ talloc_get_type_abort(call->wait_private,
+ struct ldapsrv_bind_wait_context);
+ struct ldap_BindRequest *req = &call->request->r.BindRequest;
+ struct ldapsrv_reply *reply = bind_wait->reply;
+ struct ldap_BindResponse *resp = &reply->msg->r.BindResponse;
+ struct ldapsrv_connection *conn = call->conn;
+ struct auth_session_info *session_info = NULL;
+ struct ldapsrv_sasl_postprocess_context *context = NULL;
+ NTSTATUS status;
+ int result;
+ const char *errstr = NULL;
+ DATA_BLOB output = data_blob_null;
+
+ status = gensec_update_recv(subreq, call, &output);
+ TALLOC_FREE(subreq);
if (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) {
*resp->SASL.secblob = output;
@@ -441,7 +500,8 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
context = talloc_zero(call, struct ldapsrv_sasl_postprocess_context);
if (context == NULL) {
- return NT_STATUS_NO_MEMORY;
+ ldapsrv_bind_wait_finished(call, NT_STATUS_NO_MEMORY);
+ return;
}
}
@@ -538,7 +598,8 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
ptr = talloc_reparent(conn, context->sasl, conn->gensec);
if (ptr == NULL) {
- return NT_STATUS_NO_MEMORY;
+ ldapsrv_bind_wait_finished(call, NT_STATUS_NO_MEMORY);
+ return;
}
call->postprocess_send = ldapsrv_sasl_postprocess_send;
@@ -572,7 +633,7 @@ do_reply:
resp->response.referral = NULL;
ldapsrv_queue_reply(call, reply);
- return NT_STATUS_OK;
+ ldapsrv_bind_wait_finished(call, NT_STATUS_OK);
}
NTSTATUS ldapsrv_BindRequest(struct ldapsrv_call *call)
--
1.9.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20170614/0bb04677/signature.sig>
More information about the samba-technical
mailing list