svn commit: samba r9039 - in trunk/source: include rpc_server smbd

jra at samba.org jra at samba.org
Thu Aug 4 03:04:58 GMT 2005


Author: jra
Date: 2005-08-04 03:04:58 +0000 (Thu, 04 Aug 2005)
New Revision: 9039

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

Log:
Added comments to 2 factor auth in sesssetup.c.
We now create the reply blob for the SPNEGO ntlmssp blob - now
to learn how to return it...
Jeremy.

Modified:
   trunk/source/include/ntdomain.h
   trunk/source/rpc_server/srv_pipe.c
   trunk/source/smbd/sesssetup.c


Changeset:
Modified: trunk/source/include/ntdomain.h
===================================================================
--- trunk/source/include/ntdomain.h	2005-08-04 02:59:19 UTC (rev 9038)
+++ trunk/source/include/ntdomain.h	2005-08-04 03:04:58 UTC (rev 9039)
@@ -185,11 +185,6 @@
 	uint32 ntlmssp_seq_num;
 };
 
-/* auth state for spnego ntlmssp. */
-struct spnego_ntlmssp_auth_struct {
-	AUTH_NTLMSSP_STATE *auth_ntlmssp_state;
-};
-
 /* auth state for all bind types. */
 
 struct pipe_auth_data {
@@ -197,7 +192,7 @@
 	union {
 		struct ntlmssp_auth_struct *ntlmssp_auth;
 		struct schannel_auth_struct *schannel_auth;
-		struct spnego_ntlmssp_auth_struct *spnego_auth;
+		AUTH_NTLMSSP_STATE *auth_ntlmssp_state;
 	} a_u;
 	void (*auth_data_free_func)(struct pipe_auth_data *);
 };

Modified: trunk/source/rpc_server/srv_pipe.c
===================================================================
--- trunk/source/rpc_server/srv_pipe.c	2005-08-04 02:59:19 UTC (rev 9038)
+++ trunk/source/rpc_server/srv_pipe.c	2005-08-04 03:04:58 UTC (rev 9039)
@@ -839,6 +839,7 @@
 /*******************************************************************
  Register commands to an RPC pipe
 *******************************************************************/
+
 NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *srv, const struct api_struct *cmds, int size)
 {
         struct rpc_table *rpc_entry;
@@ -898,26 +899,33 @@
 
 static void free_pipe_spnego_auth_data(struct pipe_auth_data *auth)
 {
-	AUTH_NTLMSSP_STATE *a = auth->a_u.spnego_auth->auth_ntlmssp_state;
+	AUTH_NTLMSSP_STATE *a = auth->a_u.auth_ntlmssp_state;
 
 	if (a) {
 		auth_ntlmssp_end(&a);
 	}
+	auth->a_u.auth_ntlmssp_state = NULL;
 }
 
 /*******************************************************************
- Handle a SPNEGO bind auth.
+ Handle the first part of a SPNEGO bind auth.
 *******************************************************************/
 
 static BOOL pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth)
 {
-        DATA_BLOB secblob;
 	DATA_BLOB blob;
+       	DATA_BLOB secblob;
+       	DATA_BLOB response;
+       	DATA_BLOB chal;
 	char *OIDs[ASN1_MAX_OIDS];
         int i;
+	NTSTATUS status;
         BOOL got_kerberos_mechanism = False;
+	AUTH_NTLMSSP_STATE *a = NULL;
 
 	ZERO_STRUCT(secblob);
+	ZERO_STRUCT(chal);
+	ZERO_STRUCT(response);
 
 	/* Grab the SPNEGO blob. */
 	blob = data_blob(NULL,p->hdr.auth_len);
@@ -925,20 +933,17 @@
 	if (!prs_copy_data_out(blob.data, rpc_in_p, p->hdr.auth_len)) {
 		DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to pull %u bytes - the SPNEGO auth header.\n",
 			(unsigned int)p->hdr.auth_len ));
-		data_blob_free(&blob);
-		return False;
+		goto err;
 	}
 
 	if (blob.data[0] != ASN1_APPLICATION(0)) {
-		data_blob_free(&blob);
-		return False;
+		goto err;
 	}
 
 	/* parse out the OIDs and the first sec blob */
 	if (!parse_negTokenTarg(blob, OIDs, &secblob)) {
 		DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to parse the security blob.\n"));
-		data_blob_free(&blob);
-		return False;
+		goto err;
         }
 
 	if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
@@ -958,35 +963,56 @@
 		return ret;
 	}
 
-	if (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP && p->auth.a_u.spnego_auth) {
+	if (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP && p->auth.a_u.auth_ntlmssp_state) {
 		/* Free any previous auth type. */
 		free_pipe_spnego_auth_data(&p->auth);
 	}
 
-	p->auth.a_u.spnego_auth = TALLOC_P(p->pipe_state_mem_ctx, struct spnego_ntlmssp_auth_struct);
-	if (!p->auth.a_u.spnego_auth) {
-		return False;
+	/* Initialize the NTLM engine. */
+	status = auth_ntlmssp_start(&a);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto err;
 	}
 
+	/*
+	 * Pass the first security blob of data to it.
+	 * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED
+	 * which means we need another packet to complete the bind.
+	 */
+
+        status = auth_ntlmssp_update(a, secblob, &chal);
+
+	if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+		DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n"));
+		goto err;
+	}
+
+	/* Generate the response blob we need for step 2 of the bind. */
+	response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP);
+
+	p->auth.a_u.auth_ntlmssp_state = a;
 	p->auth.auth_data_free_func = &free_pipe_spnego_auth_data;
 	p->auth.auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
 
+	data_blob_free(&blob);
+	data_blob_free(&secblob);
+	data_blob_free(&chal);
+	data_blob_free(&response);
+
+	/* We can't set pipe_bound True yet - we need a response packet... */
 	return False;
-#if 0
-	nt_status = auth_ntlmssp_start(auth_ntlmssp_state);
-	if (!NT_STATUS_IS_OK(nt_status)) {
-		return ERROR_NT(nt_status);
-	}
 
-        nt_status = auth_ntlmssp_update(*auth_ntlmssp_state, secblob, &chal);
+ err:
 
-        data_blob_free(&secblob);
+	data_blob_free(&blob);
+	data_blob_free(&secblob);
+	data_blob_free(&chal);
+	data_blob_free(&response);
 
-        reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, auth_ntlmssp_state, &chal, nt_status);
-        data_blob_free(&chal);
-	data_blob_free(&secblob);
-	return True;
-#endif
+	p->auth.a_u.auth_ntlmssp_state = NULL;
+	p->auth.auth_type = PIPE_AUTH_TYPE_NONE;
+
+	return False;
 }
 
 /*******************************************************************
@@ -1015,9 +1041,6 @@
 		return False;
 	}
 
-	p->auth.auth_data_free_func = NULL;
-	p->auth.auth_type = PIPE_AUTH_TYPE_SCHANNEL;
-
 	memset(p->auth.a_u.schannel_auth->sess_key, 0, sizeof(p->auth.a_u.schannel_auth->sess_key));
 	memcpy(p->auth.a_u.schannel_auth->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key));
 
@@ -1053,6 +1076,9 @@
 		neg.domain, neg.myname));
 
 	/* We're finished with this bind - no more packets. */
+	p->auth.auth_data_free_func = NULL;
+	p->auth.auth_type = PIPE_AUTH_TYPE_SCHANNEL;
+
 	p->pipe_bound = True;
 
 	return True;
@@ -1095,9 +1121,6 @@
 		return False;
 	}
 
-	p->auth.auth_data_free_func = NULL;
-
-	p->auth.auth_type = PIPE_AUTH_TYPE_NTLMSSP;
 	p->auth.a_u.ntlmssp_auth->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS;
 	p->auth.a_u.ntlmssp_auth->ntlmssp_auth_requested = True;
 
@@ -1136,6 +1159,9 @@
 	DEBUG(10,("pipe_ntlmssp_auth_bind: NTLMSSP auth: domain [%s] myname [%s]\n",
 		ntlmssp_neg.domain, ntlmssp_neg.myname));
 
+	p->auth.auth_data_free_func = NULL;
+	p->auth.auth_type = PIPE_AUTH_TYPE_NTLMSSP;
+
 	/* We can't set pipe_bound True yet - we need a response packet... */
 	return True;
 }

Modified: trunk/source/smbd/sesssetup.c
===================================================================
--- trunk/source/smbd/sesssetup.c	2005-08-04 02:59:19 UTC (rev 9038)
+++ trunk/source/smbd/sesssetup.c	2005-08-04 03:04:58 UTC (rev 9039)
@@ -348,6 +348,8 @@
  Send a session setup reply, wrapped in SPNEGO.
  Get vuid and check first.
  End the NTLMSSP exchange context if we are OK/complete fail
+ This should be split into two functions, one to handle each
+ leg of the NTLM auth steps.
 ***************************************************************************/
 
 static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *outbuf,
@@ -422,6 +424,7 @@
 	   and the other end, that we are not finished yet. */
 
 	if (!ret || !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+		/* NB. This is *NOT* an error case. JRA */
 		auth_ntlmssp_end(auth_ntlmssp_state);
 		/* Kill the intermediate vuid */
 		invalidate_vuid(vuid);



More information about the samba-cvs mailing list