#include "includes.h"
static const uint8 *auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state)
{
AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context;
return auth_ntlmssp_state->auth_context->get_ntlm_challenge(auth_ntlmssp_state->auth_context);
}
static BOOL auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
{
AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context;
struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
return auth_context->challenge_may_be_modified;
}
static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
{
AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context;
struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
SMB_ASSERT(challenge->length == 8);
auth_context->challenge = data_blob_talloc(auth_context->mem_ctx,
challenge->data, challenge->length);
auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)";
DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by));
DEBUG(5, ("challenge is: \n"));
dump_data(5, (const char *)auth_context->challenge.data, auth_context->challenge.length);
return NT_STATUS_OK;
}
static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key)
{
AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context;
uint32 auth_flags = AUTH_FLAG_NONE;
auth_usersupplied_info *user_info = NULL;
DATA_BLOB plaintext_password = data_blob(NULL, 0);
NTSTATUS nt_status;
if (auth_ntlmssp_state->ntlmssp_state->lm_resp.length) {
auth_flags |= AUTH_FLAG_LM_RESP;
}
if (auth_ntlmssp_state->ntlmssp_state->nt_resp.length == 24) {
auth_flags |= AUTH_FLAG_NTLM_RESP;
} else if (auth_ntlmssp_state->ntlmssp_state->nt_resp.length > 24) {
auth_flags |= AUTH_FLAG_NTLMv2_RESP;
}
set_remote_machine_name(auth_ntlmssp_state->ntlmssp_state->workstation, True);
sub_set_smb_name(auth_ntlmssp_state->ntlmssp_state->user);
reload_services(True);
nt_status = make_user_info_map(&user_info,
auth_ntlmssp_state->ntlmssp_state->user,
auth_ntlmssp_state->ntlmssp_state->domain,
auth_ntlmssp_state->ntlmssp_state->workstation,
auth_ntlmssp_state->ntlmssp_state->lm_resp,
auth_ntlmssp_state->ntlmssp_state->nt_resp,
plaintext_password,
auth_flags, True);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context,
user_info, &auth_ntlmssp_state->server_info);
free_user_info(&user_info);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
if (auth_ntlmssp_state->server_info->nt_session_key.length) {
DEBUG(10, ("Got NT session key of length %u\n", auth_ntlmssp_state->server_info->nt_session_key.length));
*nt_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx,
auth_ntlmssp_state->server_info->nt_session_key.data,
auth_ntlmssp_state->server_info->nt_session_key.length);
}
if (auth_ntlmssp_state->server_info->lm_session_key.length) {
DEBUG(10, ("Got LM session key of length %u\n", auth_ntlmssp_state->server_info->lm_session_key.length));
*lm_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx,
auth_ntlmssp_state->server_info->lm_session_key.data,
auth_ntlmssp_state->server_info->lm_session_key.length);
}
return nt_status;
}
NTSTATUS auth_ntlmssp_start(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
{
NTSTATUS nt_status;
TALLOC_CTX *mem_ctx;
mem_ctx = talloc_init("AUTH NTLMSSP context");
*auth_ntlmssp_state = talloc_zero(mem_ctx, sizeof(**auth_ntlmssp_state));
if (!*auth_ntlmssp_state) {
DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
talloc_destroy(mem_ctx);
return NT_STATUS_NO_MEMORY;
}
ZERO_STRUCTP(*auth_ntlmssp_state);
(*auth_ntlmssp_state)->mem_ctx = mem_ctx;
if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_start(&(*auth_ntlmssp_state)->ntlmssp_state))) {
return nt_status;
}
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&(*auth_ntlmssp_state)->auth_context))) {
return nt_status;
}
(*auth_ntlmssp_state)->ntlmssp_state->auth_context = (*auth_ntlmssp_state);
(*auth_ntlmssp_state)->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
(*auth_ntlmssp_state)->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
(*auth_ntlmssp_state)->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
(*auth_ntlmssp_state)->ntlmssp_state->check_password = auth_ntlmssp_check_password;
(*auth_ntlmssp_state)->ntlmssp_state->server_role = lp_server_role();
return NT_STATUS_OK;
}
void auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
{
TALLOC_CTX *mem_ctx = (*auth_ntlmssp_state)->mem_ctx;
if ((*auth_ntlmssp_state)->ntlmssp_state) {
ntlmssp_end(&(*auth_ntlmssp_state)->ntlmssp_state);
}
if ((*auth_ntlmssp_state)->auth_context) {
((*auth_ntlmssp_state)->auth_context->free)(&(*auth_ntlmssp_state)->auth_context);
}
if ((*auth_ntlmssp_state)->server_info) {
free_server_info(&(*auth_ntlmssp_state)->server_info);
}
talloc_destroy(mem_ctx);
*auth_ntlmssp_state = NULL;
}
NTSTATUS auth_ntlmssp_update(AUTH_NTLMSSP_STATE *auth_ntlmssp_state,
const DATA_BLOB request, DATA_BLOB *reply)
{
return ntlmssp_update(auth_ntlmssp_state->ntlmssp_state, request, reply);
}