The branch, master has been updated via 52bd61d s4:ldap_server: implement async BindSASL via 9f23a88 s4:ldap_server: set result = LDAP_SUCCESS at the end, when we're really done via 772b816 s4:ldap_server: avoid using talloc_reference() via 489bc70 s4:ldap_server: remove useless NT_STATUS_IS_OK(status) check via 126fd7e s4:ldap_server: remove useless indentation level arround ldapsrv_backend_Init() via eaa8acf s4:ldap_server: remove useless indentation level arround gensec_session_info() via a280367 s4:ldap_server: make the gensec_create_tstream() error checking more clear via 461abf3 s4:ldap_server: only touch conn->session_info on success in ldapsrv_BindSASL() via 5de8074 s4:ldap_server: terminate the connection if talloc_reference fails via 3df94e6 s4:ldap_server: remove pointless (result != LDAP_SUCCESS) check via 3999362 s4:ldap_server: do the transport validation before calling gensec_create_tstream() via dc56e88 s4:ldap_server: use talloc_zero for ldapsrv_sasl_postprocess_context via bd0a987 s4:ldap_server: drop the connection if we fail to allocate ldapsrv_sasl_postprocess_context via 85a6e73 s4:ldap_server: only set *resp->SASL.secblob = output for OK or MORE_PROCESSING_REQUIRED via 00a3872 s4:ldap_server: remove indentation level for the valid credential case via 7605c67 s4:ldap_server: make sure we destroy the gensec context on error via e8d4312 s4:ldap_server: avoid pointless check arround LDAP_INVALID_CREDENTIALS via b271794 s4:ldap_server: move invalid credential handling before the success handling. via bf531df s4:ldap_server: remove an useless indentation level from gensec_update_ev() via d4cf947 s4:ldap_server: always allocate resp->SASL.secblob via be8fff9 s4:ldap_server: add use goto do_reply; to make the logic in ldapsrv_BindSASL() more sane via c0fa0b8 s4:auth: make authenticate_ldap_simple_bind*() use auth_check_password_send/recv via cb7198d s4:ldap_server: implement async BindSimple via 6e165ca s4:auth: add authenticate_ldap_simple_bind_send/recv via c6e2779 s4:ldap_server: improve ldapsrv_UnbindRequest implementation via 900ab85 s4:ldap_server: add call->wait_send/recv infrastructure via 4c9eeb0 s4:ldap_server: don't log Unbind and Abandon requests. via 82929a4 s4:ldap_server: introduce a ldapsrv_call_destructor() via ace49db s4:ldap_server: use talloc_zero() in ldapsrv_init_reply() via 7bf0308 s4:auth/gensec: let GENSEC_FEATURE_SESSION_KEY result in GSS_C_INTEG_FLAG from e244ba4 repl: Set GET_ALL_GROUP_MEMBERSHIP flag in the drepl server
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 52bd61d7f4d2ce00b06cad34606d7884dc462850 Author: Stefan Metzmacher <me...@samba.org> Date: Fri May 12 13:15:27 2017 +0200 s4:ldap_server: implement async BindSASL Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> Autobuild-User(master): Andrew Bartlett <abart...@samba.org> Autobuild-Date(master): Thu Jun 15 13:18:47 CEST 2017 on sn-devel-144 commit 9f23a88fd3b01a7f553f7587826a5b4bad174a41 Author: Stefan Metzmacher <me...@samba.org> Date: Fri May 12 12:41:13 2017 +0200 s4:ldap_server: set result = LDAP_SUCCESS at the end, when we're really done Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 772b816c4488db36f48de98a88c3962aadc0f7ca Author: Stefan Metzmacher <me...@samba.org> Date: Fri May 12 12:38:59 2017 +0200 s4:ldap_server: avoid using talloc_reference() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 489bc70c43e366d1a82485ce20360eebd45f1b10 Author: Stefan Metzmacher <me...@samba.org> Date: Fri May 12 12:31:25 2017 +0200 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 <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 126fd7e45d19b591fda65fe59e0aad96d102a895 Author: Stefan Metzmacher <me...@samba.org> Date: Fri May 12 12:27:26 2017 +0200 s4:ldap_server: remove useless indentation level arround ldapsrv_backend_Init() Check with git show -w Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit eaa8acf6e3488618c6e4f76576b19230037d364f Author: Stefan Metzmacher <me...@samba.org> Date: Fri May 12 12:27:26 2017 +0200 s4:ldap_server: remove useless indentation level arround gensec_session_info() Check with git show -w Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit a2803671774fc4c02dfb42ea2527dc89964b4731 Author: Stefan Metzmacher <me...@samba.org> Date: Fri May 12 12:26:12 2017 +0200 s4:ldap_server: make the gensec_create_tstream() error checking more clear Check with 'git show -w'. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 461abf3ce337b147db7c3c9bffb972bae678f7df Author: Stefan Metzmacher <me...@samba.org> Date: Tue Jun 13 15:28:53 2017 +0200 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 <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 5de8074b3917e46cf68762c1b52775e5533a90cb Author: Stefan Metzmacher <me...@samba.org> Date: Fri May 12 12:09:38 2017 +0200 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 <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 3df94e62f478e43ce95923c1c48ba0fef8909142 Author: Stefan Metzmacher <me...@samba.org> Date: Fri May 12 12:07:31 2017 +0200 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 <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 399936239c24cc71430d1187d05e8d38284bda62 Author: Stefan Metzmacher <me...@samba.org> Date: Fri May 12 12:04:59 2017 +0200 s4:ldap_server: do the transport validation before calling gensec_create_tstream() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit dc56e8874fbb07385bed79419529c93fb7f4c561 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 11 21:18:07 2017 +0200 s4:ldap_server: use talloc_zero for ldapsrv_sasl_postprocess_context Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit bd0a987c5cd301d6ed4c53f7ff1118cce81901a3 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 11 21:17:40 2017 +0200 s4:ldap_server: drop the connection if we fail to allocate ldapsrv_sasl_postprocess_context Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 85a6e73695d6c16bdb896bbb4c7b95d1dc74de60 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 11 21:14:00 2017 +0200 s4:ldap_server: only set *resp->SASL.secblob = output for OK or MORE_PROCESSING_REQUIRED Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 00a387272afe6939948669174ec61277d310c290 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 11 21:11:00 2017 +0200 s4:ldap_server: remove indentation level for the valid credential case Check with git show -w. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 7605c67e079339c5e1b5b13199a705ece23c0ad6 Author: Stefan Metzmacher <me...@samba.org> Date: Fri May 12 12:44:05 2017 +0200 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 <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit e8d431250edebf96c1d80aacf2f676c93da907f4 Author: Stefan Metzmacher <me...@samba.org> Date: Fri May 12 16:04:02 2017 +0200 s4:ldap_server: avoid pointless check arround LDAP_INVALID_CREDENTIALS Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit b271794ca8ae2ea052a6fc87d89f506dcbae171f Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 11 21:09:08 2017 +0200 s4:ldap_server: move invalid credential handling before the success handling. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit bf531dfd4e2cd97a8f57030ea597c75a3d3336ac Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 11 19:13:49 2017 +0200 s4:ldap_server: remove an useless indentation level from gensec_update_ev() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit d4cf947c08e64f9a5f71fced0e75ca101c367ef8 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 11 19:11:43 2017 +0200 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 <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit be8fff9dbcd781f24da7176dac37b7a37d8a7074 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 11 19:04:27 2017 +0200 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 <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit c0fa0b88d033e374cd28730d435b5ed0e6af2ff9 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 11 18:53:06 2017 +0200 s4:auth: make authenticate_ldap_simple_bind*() use auth_check_password_send/recv Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit cb7198df2e3e712ca9f0e210f6d0ac6450a39a83 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 11 18:04:15 2017 +0200 s4:ldap_server: implement async BindSimple Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 6e165ca85ae8049a7fb9a5535c168d1b9cb5ec26 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 11 17:05:02 2017 +0200 s4:auth: add authenticate_ldap_simple_bind_send/recv TODO: we need to make the backend async. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit c6e27794d629b71671474f8044535bf04b60921d Author: Stefan Metzmacher <me...@samba.org> Date: Tue Jun 13 15:02:41 2017 +0200 s4:ldap_server: improve ldapsrv_UnbindRequest implementation We should abandon outstanding requests and disconnect the connection. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 900ab851a77ca0cb272fa1a6b0894cac7c41510f Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 11 16:51:15 2017 +0200 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 <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 4c9eeb0d3e26742aa025e86ad677d6dbc3478fcf Author: Stefan Metzmacher <me...@samba.org> Date: Sat May 13 08:20:00 2017 +0200 s4:ldap_server: don't log Unbind and Abandon requests. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 82929a4bdd87f878db880c31317cca4305a65207 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 11 16:37:21 2017 +0200 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 <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit ace49db796a121bd35741e86e3e0aa98be48e81f Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 11 19:07:04 2017 +0200 s4:ldap_server: use talloc_zero() in ldapsrv_init_reply() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 7bf0308a319df4359fb8f22954da16873b975dc2 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Dec 20 08:52:52 2013 +0100 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 <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> ----------------------------------------------------------------------- Summary of changes: source4/auth/auth.h | 12 + source4/auth/gensec/gensec_gssapi.c | 3 + source4/auth/ntlm/auth_simple.c | 181 ++++++++---- source4/ldap_server/ldap_backend.c | 6 +- source4/ldap_server/ldap_bind.c | 555 +++++++++++++++++++++++++++--------- source4/ldap_server/ldap_server.c | 72 ++++- source4/ldap_server/ldap_server.h | 6 + 7 files changed, 626 insertions(+), 209 deletions(-) Changeset truncated at 500 lines: 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/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; } diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c index cd96113..c3bc25a 100644 --- a/source4/auth/ntlm/auth_simple.c +++ b/source4/auth/ntlm/auth_simple.c @@ -22,64 +22,60 @@ */ #include "includes.h" +#include <tevent.h> +#include "lib/util/tevent_ntstatus.h" #include "auth/auth.h" #include "dsdb/samdb/samdb.h" -_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 authenticate_ldap_simple_bind_state { + bool using_tls; 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); + 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, + 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; + struct auth_usersupplied_info *user_info = NULL; 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; - } + struct tevent_req *subreq = NULL; + NTSTATUS status; - if (!tmp_ctx) { - return NT_STATUS_NO_MEMORY; + req = tevent_req_create(mem_ctx, &state, + struct authenticate_ldap_simple_bind_state); + if (req == NULL) { + return NULL; } + state->using_tls = using_tls; - 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; + status = auth_context_create(state, ev, msg, lp_ctx, + &state->auth_context); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); } - /* - * 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; @@ -96,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; @@ -106,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, @@ -148,9 +184,28 @@ _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, + 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; +} diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c index 1f0c7af..d4e9030 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; @@ -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: { diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c index 986ecbf..21cbb7b 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" @@ -59,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)); @@ -94,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; -- Samba Shared Repository