summaryrefslogtreecommitdiff
path: root/source4/auth/gensec/spnego.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-08-20 06:14:14 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:33:36 -0500
commit7e36c7e6075814c0b4eb6e37ece6ed4fd4ed09e2 (patch)
tree987e6d15bb3cde5f568ff2b4d2430f67542677be /source4/auth/gensec/spnego.c
parent40f56f63bec5a609229033dc4c0854bb4fb16f06 (diff)
downloadsamba-7e36c7e6075814c0b4eb6e37ece6ed4fd4ed09e2.tar.gz
samba-7e36c7e6075814c0b4eb6e37ece6ed4fd4ed09e2.tar.bz2
samba-7e36c7e6075814c0b4eb6e37ece6ed4fd4ed09e2.zip
r9416: Cleanups inspired by jra's work to migrate Samba4's NTLMSSP code back
into Samba3. The NTLMSSP sign/seal code now assumes that GENSEC has already checked to see if SIGN or SEAL should be permitted. This simplfies the code ensures that no matter what the mech, the correct code paths have been set in place. Also remove duplication caused by the NTLMv2 code's history, and document why some of the things a bit funny. In SPNEGO, create a new routine to handle the negTokenInit creation. We no longer send an OID for a mech we can't start (like kerberos on the server without a valid trust account). Andrew Bartlett (This used to be commit fe45ef608f961a6950d4d19b4cb5e7c27b38ba5f)
Diffstat (limited to 'source4/auth/gensec/spnego.c')
-rw-r--r--source4/auth/gensec/spnego.c101
1 files changed, 50 insertions, 51 deletions
diff --git a/source4/auth/gensec/spnego.c b/source4/auth/gensec/spnego.c
index 2d1d779e43..1a7cb1f0ed 100644
--- a/source4/auth/gensec/spnego.c
+++ b/source4/auth/gensec/spnego.c
@@ -394,60 +394,74 @@ static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_
return NT_STATUS_INVALID_PARAMETER;
}
-/** create a client negTokenInit
+/** create a negTokenInit
*
- * This is the case, where the client is the first one who sends data
+ * This is the same packet, no matter if the client or server sends it first, but it is always the first packet
*/
-
-static NTSTATUS gensec_spnego_client_negTokenInit(struct gensec_security *gensec_security,
+static NTSTATUS gensec_spnego_create_negTokenInit(struct gensec_security *gensec_security,
struct spnego_state *spnego_state,
TALLOC_CTX *out_mem_ctx,
const DATA_BLOB in, DATA_BLOB *out)
{
- DATA_BLOB null_data_blob = data_blob(NULL, 0);
- NTSTATUS nt_status;
+ int i;
+ NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER;
+ DATA_BLOB null_data_blob = data_blob(NULL,0);
const char **mechTypes = NULL;
DATA_BLOB unwrapped_out = data_blob(NULL, 0);
mechTypes = gensec_security_oids(out_mem_ctx, GENSEC_OID_SPNEGO);
- if (!mechTypes) {
- DEBUG(1, ("no GENSEC OID backends available\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- nt_status = gensec_subcontext_start(spnego_state,
- gensec_security,
- &spnego_state->sub_sec_security);
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- }
- /* select our preferred mech */
- nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security,
- mechTypes[0]);
- if (!NT_STATUS_IS_OK(nt_status)) {
- talloc_free(spnego_state->sub_sec_security);
- spnego_state->sub_sec_security = NULL;
- return nt_status;
- }
- nt_status = gensec_update(spnego_state->sub_sec_security,
- out_mem_ctx, in, &unwrapped_out);
- if (NT_STATUS_IS_OK(nt_status) || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ const struct gensec_security_ops_wrapper *all_sec
+ = gensec_security_by_oid_list(out_mem_ctx,
+ mechTypes,
+ GENSEC_OID_SPNEGO);
+ for (i=0; all_sec && all_sec[i].op; i++) {
struct spnego_data spnego_out;
+ nt_status = gensec_subcontext_start(spnego_state,
+ gensec_security,
+ &spnego_state->sub_sec_security);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
+ /* select the sub context */
+ nt_status = gensec_start_mech_by_ops(spnego_state->sub_sec_security,
+ all_sec[i].op);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ talloc_free(spnego_state->sub_sec_security);
+ spnego_state->sub_sec_security = NULL;
+ continue;
+ }
+
+ nt_status = gensec_update(spnego_state->sub_sec_security,
+ out_mem_ctx,
+ null_data_blob,
+ &unwrapped_out);
+
+ if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER)
+ && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)
+ && !NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(3, ("SPNEGO(%s) creating NEG_TOKEN_INIT failed: %s\n",
+ spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status)));
+ talloc_free(spnego_state->sub_sec_security);
+ spnego_state->sub_sec_security = NULL;
+ /* Pretend we never started it (lets the first run find some incompatible demand) */
+
+ continue;
+ }
spnego_out.type = SPNEGO_NEG_TOKEN_INIT;
- spnego_out.negTokenInit.mechTypes = mechTypes;
+ spnego_out.negTokenInit.mechTypes = gensec_security_oids_from_ops_wrapped(out_mem_ctx,
+ &all_sec[i]);
spnego_out.negTokenInit.reqFlags = 0;
spnego_out.negTokenInit.mechListMIC = null_data_blob;
spnego_out.negTokenInit.mechToken = unwrapped_out;
if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) {
- DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_INIT\n"));
+ DEBUG(1, ("Failed to write NEG_TOKEN_INIT\n"));
return NT_STATUS_INVALID_PARAMETER;
}
/* set next state */
spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG;
- spnego_state->state_position = SPNEGO_CLIENT_TARG;
if (NT_STATUS_IS_OK(nt_status)) {
spnego_state->no_response_expected = True;
@@ -535,8 +549,8 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA
out_mem_ctx, in, out);
case SPNEGO_SERVER_START:
{
+ NTSTATUS nt_status;
if (in.length) {
- NTSTATUS nt_status;
len = spnego_read_data(in, &spnego);
if (len == -1) {
@@ -571,25 +585,9 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA
return nt_status;
} else {
- const char **mechlist = gensec_security_oids(out_mem_ctx, GENSEC_OID_SPNEGO);
-
- spnego_out.type = SPNEGO_NEG_TOKEN_INIT;
- spnego_out.negTokenInit.mechTypes = mechlist;
- spnego_out.negTokenInit.reqFlags = 0;
- spnego_out.negTokenInit.mechListMIC
- = data_blob_string_const(talloc_asprintf(out_mem_ctx, "%s$@%s", lp_netbios_name(), lp_realm()));
- spnego_out.negTokenInit.mechToken = data_blob(NULL, 0);
-
- if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) {
- DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_INIT\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* set next state */
- spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG;
spnego_state->state_position = SPNEGO_SERVER_TARG;
-
- return NT_STATUS_MORE_PROCESSING_REQUIRED;
+ return gensec_spnego_create_negTokenInit(gensec_security, spnego_state,
+ out_mem_ctx, in, out);
}
}
@@ -602,7 +600,8 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA
if (!in.length) {
/* client to produce negTokenInit */
- return gensec_spnego_client_negTokenInit(gensec_security, spnego_state,
+ spnego_state->state_position = SPNEGO_CLIENT_TARG;
+ return gensec_spnego_create_negTokenInit(gensec_security, spnego_state,
out_mem_ctx, in, out);
}