Add NTLMSSP SPNEGO to smb2 auth. Tested with Win7.
authorJeremy Allison <jra@samba.org>
Thu, 4 Jun 2009 18:14:20 +0000 (11:14 -0700)
committerJeremy Allison <jra@samba.org>
Thu, 4 Jun 2009 18:14:20 +0000 (11:14 -0700)
Jeremy.

source3/smbd/smb2_negprot.c
source3/smbd/smb2_server.c
source3/smbd/smb2_sesssetup.c

index e9464900f2809e49690633d5c0a6f75bbeb66e09..b312a7fa47b3d67518f5beb3541cf21de0e667ea 100644 (file)
@@ -142,11 +142,15 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
        }
 
        security_offset = SMB2_HDR_BODY + 0x40;
+
+#if 1
+       /* Try SPNEGO auth... */
        security_buffer = data_blob_const(negprot_spnego_blob.data + 16,
                                          negprot_spnego_blob.length - 16);
-
+#else
        /* for now we want raw NTLMSSP */
        security_buffer = data_blob_const(NULL, 0);
+#endif
 
        outbody = data_blob_talloc(req->out.vector, NULL, 0x40);
        if (outbody.data == NULL) {
index f7aad0efbf4c271b3472b8d8ea4c0eeeaf936c90..20754fbf9c8974bfb575ef82e4e4a172e71610ce 100644 (file)
@@ -245,7 +245,8 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
                      NT_STATUS_V(NT_STATUS_INTERNAL_ERROR));
                SSVAL(outhdr, SMB2_HDR_OPCODE,
                      SVAL(inhdr, SMB2_HDR_OPCODE));
-               SSVAL(outhdr, SMB2_HDR_CREDIT,          0);
+               /* Make up a number for now... JRA. FIXME ! FIXME !*/
+               SSVAL(outhdr, SMB2_HDR_CREDIT,          20);
                SIVAL(outhdr, SMB2_HDR_FLAGS,           SMB2_HDR_FLAG_REDIRECT);
                SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND,    next_command_ofs);
                SBVAL(outhdr, SMB2_HDR_MESSAGE_ID,
index 0f0a90003e0b5827609710eacbb8ab8e6bf9f556..faf7bd3db311b7dd886863424f5b7e8f89182330 100644 (file)
@@ -150,6 +150,7 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
        NTSTATUS status;
 
        *out_session_flags = 0;
+       *out_session_id = 0;
 
        if (in_session_id == 0) {
                int id;
@@ -202,15 +203,75 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
                }
        }
 
-       status = auth_ntlmssp_update(session->auth_ntlmssp_state,
-                                    in_security_buffer,
-                                    out_security_buffer);
-       if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+       if (in_security_buffer.data[0] == ASN1_APPLICATION(0)) {
+               DATA_BLOB secblob_in;
+               DATA_BLOB chal_out;
+               char *kerb_mech = NULL;
+
+               status = parse_spnego_mechanisms(in_security_buffer,
+                               &secblob_in, &kerb_mech);
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(session);
+                       return nt_status_squash(status);
+               }
+
+               /* For now, just SPNEGO NTLMSSP - krb5 goes here later.. */
+               status = auth_ntlmssp_update(session->auth_ntlmssp_state,
+                                            secblob_in,
+                                            &chal_out);
+
+               if (!NT_STATUS_IS_OK(status) &&
+                               !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+                       auth_ntlmssp_end(&session->auth_ntlmssp_state);
+                       TALLOC_FREE(session);
+                       return nt_status_squash(status);
+               }
+
+               *out_security_buffer = spnego_gen_auth_response(&chal_out,
+                                status, OID_NTLMSSP);
+
                *out_session_id = session->vuid;
                return status;
-       } else if (!NT_STATUS_IS_OK(status)) {
-               TALLOC_FREE(session);
-               return status;
+       } else if (in_security_buffer.data[0] == ASN1_CONTEXT(1)) {
+               DATA_BLOB auth = data_blob_null;
+               DATA_BLOB auth_out = data_blob_null;
+
+               /* its an auth packet */
+               if (!spnego_parse_auth(in_security_buffer, &auth)) {
+                       TALLOC_FREE(session);
+                       return NT_STATUS_LOGON_FAILURE;
+               }
+               /* For now, just SPNEGO NTLMSSP - krb5 goes here later.. */
+               status = auth_ntlmssp_update(session->auth_ntlmssp_state,
+                                            auth,
+                                            &auth_out);
+               if (!NT_STATUS_IS_OK(status)) {
+                       auth_ntlmssp_end(&session->auth_ntlmssp_state);
+                       TALLOC_FREE(session);
+                       return nt_status_squash(status);
+               }
+
+               *out_security_buffer = spnego_gen_auth_response(&auth_out,
+                                status, NULL);
+
+               *out_session_id = session->vuid;
+       } else if (strncmp((char *)(in_security_buffer.data), "NTLMSSP", 7) == 0) {
+
+               /* RAW NTLMSSP */
+               status = auth_ntlmssp_update(session->auth_ntlmssp_state,
+                                            in_security_buffer,
+                                            out_security_buffer);
+
+               if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+                       *out_session_id = session->vuid;
+                       return status;
+               }
+               if (!NT_STATUS_IS_OK(status)) {
+                       auth_ntlmssp_end(&session->auth_ntlmssp_state);
+                       TALLOC_FREE(session);
+                       return nt_status_squash(status);
+               }
+               *out_session_id = session->vuid;
        }
 
        /* TODO: setup session key for signing */