1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-26 01:49:31 +03:00

auth/ntlmssp: provide a "ntlmssp_resume_ccache" backend

These can be used to implement the winbindd side of
the WINBINDD_CCACHE_NTLMAUTH call.

It can properly get the initial NEGOTIATE messages
injected if available.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
(cherry picked from commit b3d4523ff7)
This commit is contained in:
Stefan Metzmacher
2015-11-25 21:41:23 +01:00
parent 3585e415e9
commit 7fcefea18f
4 changed files with 146 additions and 0 deletions

View File

@ -47,6 +47,10 @@ static const struct ntlmssp_callbacks {
.role = NTLMSSP_CLIENT,
.command = NTLMSSP_INITIAL,
.sync_fn = ntlmssp_client_initial,
},{
.role = NTLMSSP_CLIENT,
.command = NTLMSSP_NEGOTIATE,
.sync_fn = gensec_ntlmssp_resume_ccache,
},{
.role = NTLMSSP_SERVER,
.command = NTLMSSP_NEGOTIATE,
@ -82,6 +86,15 @@ static NTSTATUS gensec_ntlmssp_update_find(struct gensec_security *gensec_securi
if (!input.length) {
switch (gensec_ntlmssp->ntlmssp_state->role) {
case NTLMSSP_CLIENT:
if (gensec_ntlmssp->ntlmssp_state->resume_ccache) {
/*
* make sure gensec_ntlmssp_resume_ccache()
* will be called
*/
ntlmssp_command = NTLMSSP_NEGOTIATE;
break;
}
ntlmssp_command = NTLMSSP_INITIAL;
break;
case NTLMSSP_SERVER:
@ -194,6 +207,15 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = {
.priority = GENSEC_NTLMSSP
};
static const struct gensec_security_ops gensec_ntlmssp_resume_ccache_ops = {
.name = "ntlmssp_resume_ccache",
.client_start = gensec_ntlmssp_resume_ccache_start,
.update = gensec_ntlmssp_update,
.session_key = gensec_ntlmssp_session_key,
.have_feature = gensec_ntlmssp_have_feature,
.enabled = true,
.priority = GENSEC_NTLMSSP
};
_PUBLIC_ NTSTATUS gensec_ntlmssp_init(void)
{
@ -206,6 +228,13 @@ _PUBLIC_ NTSTATUS gensec_ntlmssp_init(void)
return ret;
}
ret = gensec_register(&gensec_ntlmssp_resume_ccache_ops);
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(0,("Failed to register '%s' gensec backend!\n",
gensec_ntlmssp_resume_ccache_ops.name));
return ret;
}
return ret;
}

View File

@ -62,6 +62,7 @@ struct ntlmssp_state
bool unicode;
bool use_ntlmv2;
bool use_ccache;
bool resume_ccache;
bool use_nt_response; /* Set to 'False' to debug what happens when the NT response is omited */
bool allow_lm_key; /* The LM_KEY code is not very secure... */

View File

@ -114,6 +114,98 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security,
return NT_STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security,
TALLOC_CTX *out_mem_ctx,
DATA_BLOB in, DATA_BLOB *out)
{
struct gensec_ntlmssp_context *gensec_ntlmssp =
talloc_get_type_abort(gensec_security->private_data,
struct gensec_ntlmssp_context);
struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
uint32_t neg_flags = 0;
uint32_t ntlmssp_command;
NTSTATUS status;
bool ok;
*out = data_blob_null;
if (in.length == 0) {
/*
* This is compat code for older callers
* which were missing the "initial_blob"
*/
ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
return NT_STATUS_MORE_PROCESSING_REQUIRED;
}
/* parse the NTLMSSP packet */
if (in.length > UINT16_MAX) {
DEBUG(1, ("%s: reject large request of length %u\n",
__func__, (unsigned int)in.length));
return NT_STATUS_INVALID_PARAMETER;
}
ok = msrpc_parse(ntlmssp_state, &in, "Cdd",
"NTLMSSP",
&ntlmssp_command,
&neg_flags);
if (!ok) {
DEBUG(1, ("%s: failed to parse NTLMSSP Negotiate of length %u\n",
__func__, (unsigned int)in.length));
dump_data(2, in.data, in.length);
return NT_STATUS_INVALID_PARAMETER;
}
if (ntlmssp_command != NTLMSSP_NEGOTIATE) {
DEBUG(1, ("%s: no NTLMSSP Negotiate message (length %u)\n",
__func__, (unsigned int)in.length));
dump_data(2, in.data, in.length);
return NT_STATUS_INVALID_PARAMETER;
}
ntlmssp_state->neg_flags = neg_flags;
DEBUG(3, ("Imported Negotiate flags:\n"));
debug_ntlmssp_flags(neg_flags);
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
ntlmssp_state->unicode = true;
} else {
ntlmssp_state->unicode = false;
}
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
gensec_security->want_features |= GENSEC_FEATURE_SIGN;
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
}
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
gensec_security->want_features |= GENSEC_FEATURE_SEAL;
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
}
if (DEBUGLEVEL >= 10) {
struct NEGOTIATE_MESSAGE *negotiate = talloc(
ntlmssp_state, struct NEGOTIATE_MESSAGE);
if (negotiate != NULL) {
status = ntlmssp_pull_NEGOTIATE_MESSAGE(
&in, negotiate, negotiate);
if (NT_STATUS_IS_OK(status)) {
NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
negotiate);
}
TALLOC_FREE(negotiate);
}
}
ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
return NT_STATUS_MORE_PROCESSING_REQUIRED;
}
/**
* Next state function for the Challenge Packet. Generate an auth packet.
*
@ -476,3 +568,22 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
return NT_STATUS_OK;
}
NTSTATUS gensec_ntlmssp_resume_ccache_start(struct gensec_security *gensec_security)
{
struct gensec_ntlmssp_context *gensec_ntlmssp = NULL;
NTSTATUS status;
status = gensec_ntlmssp_client_start(gensec_security);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data,
struct gensec_ntlmssp_context);
gensec_ntlmssp->ntlmssp_state->use_ccache = false;
gensec_ntlmssp->ntlmssp_state->resume_ccache = true;
gensec_ntlmssp->ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
return NT_STATUS_OK;
}

View File

@ -88,6 +88,10 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security,
TALLOC_CTX *out_mem_ctx,
DATA_BLOB in, DATA_BLOB *out) ;
NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security,
TALLOC_CTX *out_mem_ctx,
DATA_BLOB in, DATA_BLOB *out);
/**
* Next state function for the Challenge Packet. Generate an auth packet.
*
@ -101,6 +105,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
TALLOC_CTX *out_mem_ctx,
const DATA_BLOB in, DATA_BLOB *out) ;
NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security);
NTSTATUS gensec_ntlmssp_resume_ccache_start(struct gensec_security *gensec_security);
/* The following definitions come from auth/ntlmssp/gensec_ntlmssp_server.c */