From e53ca4845e123eeff5e29869995e4a1a455f5f5d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 4 Jun 2009 11:14:20 -0700 Subject: Add NTLMSSP SPNEGO to smb2 auth. Tested with Win7. Jeremy. --- source3/smbd/smb2_negprot.c | 6 +++- source3/smbd/smb2_server.c | 3 +- source3/smbd/smb2_sesssetup.c | 75 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 75 insertions(+), 9 deletions(-) diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c index e9464900f2..b312a7fa47 100644 --- a/source3/smbd/smb2_negprot.c +++ b/source3/smbd/smb2_negprot.c @@ -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) { diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index f7aad0efbf..20754fbf9c 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -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, diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index 0f0a90003e..faf7bd3db3 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -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 */ -- cgit