svn commit: samba r4890 - in branches/SAMBA_4_0/source/libcli/auth: .

abartlet at samba.org abartlet at samba.org
Fri Jan 21 11:10:03 GMT 2005


Author: abartlet
Date: 2005-01-21 11:10:03 +0000 (Fri, 21 Jan 2005)
New Revision: 4890

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=4890

Log:
Try to cope with mechanism mismatch in the client speaks first version
of the SPNEGO state-machine.  (Such as on LDAP and HTTP)

Andrew Bartlett

Modified:
   branches/SAMBA_4_0/source/libcli/auth/spnego.c


Changeset:
Modified: branches/SAMBA_4_0/source/libcli/auth/spnego.c
===================================================================
--- branches/SAMBA_4_0/source/libcli/auth/spnego.c	2005-01-21 06:58:16 UTC (rev 4889)
+++ branches/SAMBA_4_0/source/libcli/auth/spnego.c	2005-01-21 11:10:03 UTC (rev 4890)
@@ -287,12 +287,64 @@
 	
 }
 
-static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_security,
-						 struct spnego_state *spnego_state, 
-						 TALLOC_CTX *out_mem_ctx, 
-						 const char **mechType,
-						 const DATA_BLOB unwrapped_in, DATA_BLOB *unwrapped_out) 
+/* 
+   Parse the netTokenInit from the client, to the server.  
+
+   
+*/
+
+static NTSTATUS gensec_spnego_server_parse_negTokenInit(struct gensec_security *gensec_security,
+							struct spnego_state *spnego_state, 
+							TALLOC_CTX *out_mem_ctx, 
+							const char **mechType,
+							const DATA_BLOB unwrapped_in, DATA_BLOB *unwrapped_out) 
 {
+	NTSTATUS nt_status;
+
+	if (!mechType || !mechType[0]) {
+		DEBUG(1, ("SPNEGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\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 the sub context */
+	nt_status = gensec_start_mech_by_oid(spnego_state->sub_sec_security,
+					     mechType[0]);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		talloc_free(spnego_state->sub_sec_security);
+		spnego_state->sub_sec_security = NULL;
+		return nt_status;
+	}
+
+	if (!unwrapped_in.length) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+		
+	nt_status = gensec_update(spnego_state->sub_sec_security,
+				  out_mem_ctx, 
+				  unwrapped_in,
+				  unwrapped_out);
+
+	if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(nt_status)) {
+		DEBUG(1, ("SPNEGO(%s) 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;
+	}
+	return nt_status;
+}
+
+static NTSTATUS gensec_spnego_client_parse_negTokenInit(struct gensec_security *gensec_security,
+							struct spnego_state *spnego_state, 
+							TALLOC_CTX *out_mem_ctx, 
+							const char **mechType,
+							const DATA_BLOB unwrapped_in, DATA_BLOB *unwrapped_out) 
+{
 	int i;
 	NTSTATUS nt_status;
 	DATA_BLOB null_data_blob = data_blob(NULL,0);
@@ -440,6 +492,40 @@
 		}
 		spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED;
 		spnego_state->state_position = SPNEGO_DONE;
+	} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER)) {
+		if (spnego_state->sub_sec_security) {
+			/* we have a mech, but we just didn't get the input parameter */
+			spnego_out.negTokenTarg.supportedMech
+				= spnego_state->sub_sec_security->ops->oid;
+		} else {
+			const char **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;
+			}
+
+			/* we should be sending the whole list here */
+			spnego_out.negTokenTarg.supportedMech = mechTypes[0];
+		}
+			
+		spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;
+		spnego_state->state_position = SPNEGO_SERVER_TARG;
+		nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED;
 	} else {
 		spnego_out.negTokenTarg.negResult = SPNEGO_REJECT;
 		DEBUG(2, ("SPNEGO login failed: %s\n", nt_errstr(nt_status)));
@@ -500,7 +586,7 @@
 				return NT_STATUS_INVALID_PARAMETER;
 			}
 			
-			nt_status = gensec_spnego_parse_negTokenInit(gensec_security,
+			nt_status = gensec_spnego_server_parse_negTokenInit(gensec_security,
 								     spnego_state,
 								     out_mem_ctx, 
 								     spnego.negTokenInit.mechTypes,
@@ -580,7 +666,7 @@
 			}
 		}
 
-		nt_status = gensec_spnego_parse_negTokenInit(gensec_security,
+		nt_status = gensec_spnego_client_parse_negTokenInit(gensec_security,
 							     spnego_state,
 							     out_mem_ctx, 
 							     spnego.negTokenInit.mechTypes,
@@ -640,6 +726,11 @@
 			return NT_STATUS_INVALID_PARAMETER;
 		}
 
+		if (!spnego_state->sub_sec_security) {
+			DEBUG(1, ("SPNEGO: Did not setup a mech in NEG_TOKEN_INIT\n"));
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+
 		nt_status = gensec_update(spnego_state->sub_sec_security,
 					  out_mem_ctx, 
 					  spnego.negTokenTarg.responseToken,



More information about the samba-cvs mailing list