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);

Reply via email to