summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2017-06-16 17:18:17 +0200
committerAndreas Schneider <asn@cryptomilk.org>2017-08-07 15:20:03 +0200
commite8264d9678dff1cf56f7ac97d8a1a59b9532b6b8 (patch)
tree8c61041d4550982fc4f9d7efa4d4dcfc7b0d7831
parent7d43aecb5002902486a6c57ff14a1dcbd64b0f40 (diff)
downloadsamba-e8264d9678dff1cf56f7ac97d8a1a59b9532b6b8.tar.gz
auth/common: add support for auth4_ctx->check_ntlm_password_send/recv()
Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org>
-rw-r--r--auth/common_auth.h10
-rw-r--r--auth/ntlmssp/ntlmssp_server.c65
-rw-r--r--source3/auth/auth_generic.c49
3 files changed, 117 insertions, 7 deletions
diff --git a/auth/common_auth.h b/auth/common_auth.h
index 507971794f3..3de227ee354 100644
--- a/auth/common_auth.h
+++ b/auth/common_auth.h
@@ -131,6 +131,16 @@ struct auth4_context {
uint8_t *pauthoritative,
void **server_returned_info,
DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key);
+ struct tevent_req *(*check_ntlm_password_send)(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct auth4_context *auth_ctx,
+ const struct auth_usersupplied_info *user_info);
+ NTSTATUS (*check_ntlm_password_recv)(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ uint8_t *pauthoritative,
+ void **server_returned_info,
+ DATA_BLOB *nt_session_key,
+ DATA_BLOB *lm_session_key);
NTSTATUS (*get_ntlm_challenge)(struct auth4_context *auth_ctx, uint8_t chal[8]);
diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c
index 4990f77f66f..417352bf259 100644
--- a/auth/ntlmssp/ntlmssp_server.c
+++ b/auth/ntlmssp/ntlmssp_server.c
@@ -296,6 +296,9 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security
}
struct ntlmssp_server_auth_state {
+ struct gensec_security *gensec_security;
+ struct gensec_ntlmssp_context *gensec_ntlmssp;
+ DATA_BLOB in;
struct auth_usersupplied_info *user_info;
DATA_BLOB user_session_key;
DATA_BLOB lm_session_key;
@@ -310,6 +313,7 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
struct gensec_ntlmssp_context *gensec_ntlmssp,
struct ntlmssp_server_auth_state *state,
const DATA_BLOB request);
+static void ntlmssp_server_auth_done(struct tevent_req *subreq);
static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
struct gensec_ntlmssp_context *gensec_ntlmssp,
struct ntlmssp_server_auth_state *state,
@@ -334,6 +338,9 @@ struct tevent_req *ntlmssp_server_auth_send(TALLOC_CTX *mem_ctx,
if (req == NULL) {
return NULL;
}
+ state->gensec_security = gensec_security;
+ state->gensec_ntlmssp = gensec_ntlmssp;
+ state->in = in;
status = ntlmssp_server_preauth(gensec_security,
gensec_ntlmssp,
@@ -342,6 +349,21 @@ struct tevent_req *ntlmssp_server_auth_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
+ if (auth_context->check_ntlm_password_send != NULL) {
+ struct tevent_req *subreq = NULL;
+
+ subreq = auth_context->check_ntlm_password_send(state, ev,
+ auth_context,
+ state->user_info);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq,
+ ntlmssp_server_auth_done,
+ req);
+ return req;
+ }
+
if (auth_context->check_ntlm_password == NULL) {
tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
return tevent_req_post(req, ev);
@@ -794,6 +816,49 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
return NT_STATUS_OK;
}
+static void ntlmssp_server_auth_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req =
+ tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct ntlmssp_server_auth_state *state =
+ tevent_req_data(req,
+ struct ntlmssp_server_auth_state);
+ struct gensec_security *gensec_security = state->gensec_security;
+ struct gensec_ntlmssp_context *gensec_ntlmssp = state->gensec_ntlmssp;
+ struct auth4_context *auth_context = gensec_security->auth_context;
+ uint8_t authoritative = 0;
+ NTSTATUS status;
+
+ status = auth_context->check_ntlm_password_recv(subreq,
+ gensec_ntlmssp,
+ &authoritative,
+ &gensec_ntlmssp->server_returned_info,
+ &state->user_session_key,
+ &state->lm_session_key);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_INFO("Checking NTLMSSP password for %s\\%s failed: %s\n",
+ state->user_info->client.domain_name,
+ state->user_info->client.account_name,
+ nt_errstr(status));
+ }
+ if (tevent_req_nterror(req, status)) {
+ return;
+ }
+ talloc_steal(state, state->user_session_key.data);
+ talloc_steal(state, state->lm_session_key.data);
+
+ status = ntlmssp_server_postauth(state->gensec_security,
+ state->gensec_ntlmssp,
+ state, state->in);
+ if (tevent_req_nterror(req, status)) {
+ return;
+ }
+
+ tevent_req_done(req);
+}
+
/**
* Next state function for the Authenticate packet
* (after authentication - figures out the session keys etc)
diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
index 6dedeedd302..167d4e00367 100644
--- a/source3/auth/auth_generic.c
+++ b/source3/auth/auth_generic.c
@@ -22,6 +22,8 @@
*/
#include "includes.h"
+#include <tevent.h>
+#include "../lib/util/tevent_ntstatus.h"
#include "auth.h"
#include "../lib/tsocket/tsocket.h"
#include "auth/gensec/gensec.h"
@@ -413,14 +415,47 @@ NTSTATUS auth_check_password_session_info(struct auth4_context *auth_context,
void *server_info;
uint8_t authoritative = 0;
- nt_status = auth_context->check_ntlm_password(auth_context,
- talloc_tos(),
- user_info,
- &authoritative,
- &server_info, NULL, NULL);
+ if (auth_context->check_ntlm_password_send != NULL) {
+ struct tevent_context *ev = NULL;
+ struct tevent_req *subreq = NULL;
+ bool ok;
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
+ ev = samba_tevent_context_init(talloc_tos());
+ if (ev == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ subreq = auth_context->check_ntlm_password_send(ev, ev,
+ auth_context,
+ user_info);
+ if (subreq == NULL) {
+ TALLOC_FREE(ev);
+ return NT_STATUS_NO_MEMORY;
+ }
+ ok = tevent_req_poll_ntstatus(subreq, ev, &nt_status);
+ if (!ok) {
+ TALLOC_FREE(ev);
+ return nt_status;
+ }
+ nt_status = auth_context->check_ntlm_password_recv(subreq,
+ talloc_tos(),
+ &authoritative,
+ &server_info,
+ NULL, NULL);
+ TALLOC_FREE(ev);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
+ } else {
+ nt_status = auth_context->check_ntlm_password(auth_context,
+ talloc_tos(),
+ user_info,
+ &authoritative,
+ &server_info,
+ NULL, NULL);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
}
nt_status = auth_context->generate_session_info(auth_context,