From a392a62801397d64a2c278fdfe313310eb6c536c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Mon, 16 Nov 2015 16:31:27 +0100 Subject: [PATCH 001/323] ntlmssp: add some missing defines from MS-NLMP to our IDL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit feb4ee62c5271b45877c1d3bc1d8b327439e5fd4) --- librpc/idl/ntlmssp.idl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/librpc/idl/ntlmssp.idl b/librpc/idl/ntlmssp.idl index 4a9e7c2..83d42a5 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -59,7 +59,8 @@ interface ntlmssp typedef [enum8bit] enum { NTLMSSP_WINDOWS_MAJOR_VERSION_5 = 0x05, - NTLMSSP_WINDOWS_MAJOR_VERSION_6 = 0x06 + NTLMSSP_WINDOWS_MAJOR_VERSION_6 = 0x06, + NTLMSSP_WINDOWS_MAJOR_VERSION_10 = 0x0A } ntlmssp_WindowsMajorVersion; /* @@ -141,7 +142,8 @@ interface ntlmssp typedef [bitmap32bit] bitmap { NTLMSSP_AVFLAG_CONSTRAINTED_ACCOUNT = 0x00000001, - NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE = 0x00000002 + NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE = 0x00000002, + NTLMSSP_AVFLAG_TARGET_SPN_FROM_UNTRUSTED_SOURCE = 0x00000004 } ntlmssp_AvFlags; typedef [gensize,nodiscriminant,flag(NDR_NOALIGN)] union { -- 1.9.1 From 2127f431b15861c38cac9fa78f85cd34cf53999b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 16:42:08 +0100 Subject: [PATCH 002/323] ntlmssp: fix copy/paste typo in CHALLENGE_MESSAGE in IDL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit 4be7451d9a7ed122c61a08bcf977bebeef4749dd) --- librpc/idl/ntlmssp.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/ntlmssp.idl b/librpc/idl/ntlmssp.idl index 83d42a5..ceccf79 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -186,7 +186,7 @@ interface ntlmssp uint8 ServerChallenge[8]; uint8 Reserved[8]; [value(ndr_size_AV_PAIR_LIST(TargetInfo, ndr->flags))] uint16 TargetInfoLen; - [value(TargetInfoLen)] uint16 TargetNameInfoMaxLen; + [value(TargetInfoLen)] uint16 TargetInfoMaxLen; [relative] [subcontext(0),subcontext_size(TargetInfoLen)] AV_PAIR_LIST *TargetInfo; [switch_is(NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)] ntlmssp_Version Version; } CHALLENGE_MESSAGE; -- 1.9.1 From a21d02be6b48b595805a5b15b81474fd336038ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 15:34:47 +0100 Subject: [PATCH 003/323] ntlmssp: properly document version defines in IDL (from MS-NLMP). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit ded0f3c8b7b4132d250907022ba59e88b45a6ed0) --- librpc/idl/ntlmssp.idl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/librpc/idl/ntlmssp.idl b/librpc/idl/ntlmssp.idl index ceccf79..df6773c 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -54,7 +54,8 @@ interface ntlmssp /* NTLMSSP_WINDOWS_MAJOR_VERSION_5: Windows XP SP2 and Server 2003 - NTLMSSP_WINDOWS_MAJOR_VERSION_6: Windows Vista, Server 2008, 7 and Server 2008 R2 + NTLMSSP_WINDOWS_MAJOR_VERSION_6: Windows Vista, Server 2008, 7, Server 2008 R2, 8, Server 2012, 8.1, Server 2012 R2 + NTLMSSP_WINDOWS_MAJOR_VERSION_10: Windows 10, Windows Server 2016 Technical Preview */ typedef [enum8bit] enum { @@ -64,9 +65,10 @@ interface ntlmssp } ntlmssp_WindowsMajorVersion; /* - NTLMSSP_WINDOWS_MINOR_VERSION_0: Windows Vista, Server 2008, 7, Server 2008 R2 - NTLMSSP_WINDOWS_MINOR_VERSION_1: Windows XP SP2 - NTLMSSP_WINDOWS_MINOR_VERSION_2: Windows Server 2003 + NTLMSSP_WINDOWS_MINOR_VERSION_0: Windows Vista, 10, Server 2016 Technical Preview + NTLMSSP_WINDOWS_MINOR_VERSION_1: Windows XP SP2, 7, Server 2008 R2 + NTLMSSP_WINDOWS_MINOR_VERSION_2: Windows Server 2003, 8, Server 2012 + NTLMSSP_WINDOWS_MINOR_VERSION_3: Windows 8.1, Server 2012 R2 */ typedef [enum8bit] enum { -- 1.9.1 From 466e567db74433f23a24d3c53d1bb15cc84cbfb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 15:35:29 +0100 Subject: [PATCH 004/323] ntlmssp: when pulling messages it is important to clear memory first. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit 30386c23ae0a6afd2060e626c73df9a3691a71fb) --- auth/ntlmssp/ntlmssp_ndr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/auth/ntlmssp/ntlmssp_ndr.c b/auth/ntlmssp/ntlmssp_ndr.c index af24be9..c8b16cc 100644 --- a/auth/ntlmssp/ntlmssp_ndr.c +++ b/auth/ntlmssp/ntlmssp_ndr.c @@ -25,6 +25,7 @@ #define NTLMSSP_PULL_MESSAGE(type, blob, mem_ctx, r) \ do { \ enum ndr_err_code __ndr_err; \ + ZERO_STRUCTP(r); /* in order to deal with unset neg flags */\ __ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r, \ (ndr_pull_flags_fn_t)ndr_pull_ ##type); \ if (!NDR_ERR_CODE_IS_SUCCESS(__ndr_err)) { \ -- 1.9.1 From b896c7d836de9891f0d9d59f33f130575ddb75a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 18:27:29 +0100 Subject: [PATCH 005/323] s4-torture: fill in ntlmssp_NEGOTIATE_MESSAGE_check(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit 68d043faa0aa9e5e0d289806e1aa2acba3f07af5) --- source4/torture/ndr/ntlmssp.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index 36127ce..5339558 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. test suite for ntlmssp ndr operations - Copyright (C) Guenther Deschner 2010 + Copyright (C) Guenther Deschner 2010,2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -33,6 +33,24 @@ static const uint8_t ntlmssp_NEGOTIATE_MESSAGE_data[] = { static bool ntlmssp_NEGOTIATE_MESSAGE_check(struct torture_context *tctx, struct NEGOTIATE_MESSAGE *r) { + torture_assert_str_equal(tctx, r->Signature, "NTLMSSP", "Signature"); + torture_assert_int_equal(tctx, r->MessageType, NtLmNegotiate, "MessageType"); + torture_assert_int_equal(tctx, r->NegotiateFlags, 0xe2088297, "NegotiateFlags"); + torture_assert_int_equal(tctx, r->DomainNameLen, 0, "DomainNameLen"); + torture_assert_int_equal(tctx, r->DomainNameMaxLen, 0, "DomainNameMaxLen"); + torture_assert(tctx, r->DomainName == NULL, "DomainName"); + torture_assert_int_equal(tctx, r->WorkstationLen, 0, "WorkstationLen"); + torture_assert_int_equal(tctx, r->WorkstationMaxLen, 0, "WorkstationMaxLen"); + torture_assert(tctx, r->Workstation == NULL, "Workstation"); + torture_assert_int_equal(tctx, r->Version.version.ProductMajorVersion, NTLMSSP_WINDOWS_MAJOR_VERSION_6, "ProductMajorVersion"); + torture_assert_int_equal(tctx, r->Version.version.ProductMinorVersion, NTLMSSP_WINDOWS_MINOR_VERSION_1, "ProductMinorVersion"); + torture_assert_int_equal(tctx, r->Version.version.ProductBuild, 0x1db0, "ProductBuild"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[0], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[1], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[2], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[3], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.NTLMRevisionCurrent, NTLMSSP_REVISION_W2K3, "NTLMRevisionCurrent"); + return true; } -- 1.9.1 From 736693b0edbb9859e6578f35cfc7c6cd20324b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 18:29:16 +0100 Subject: [PATCH 006/323] s4-torture: activate testing of CHALLENGE and AUTHENTICATE ntlmssp messages. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit 4ac7a6572149ec5b43a91a303c2008e73e467a56) --- source4/torture/ndr/ntlmssp.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index 5339558..0a593ba 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -54,7 +54,6 @@ static bool ntlmssp_NEGOTIATE_MESSAGE_check(struct torture_context *tctx, return true; } -#if 0 static const uint8_t ntlmssp_CHALLENGE_MESSAGE_data[] = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x38, 0x00, 0x00, 0x00, 0x95, 0x82, 0x89, 0xe2, @@ -126,16 +125,14 @@ static bool ntlmssp_AUTHENTICATE_MESSAGE_check(struct torture_context *tctx, { return true; } -#endif struct torture_suite *ndr_ntlmssp_suite(TALLOC_CTX *ctx) { struct torture_suite *suite = torture_suite_create(ctx, "ntlmssp"); torture_suite_add_ndr_pull_test(suite, NEGOTIATE_MESSAGE, ntlmssp_NEGOTIATE_MESSAGE_data, ntlmssp_NEGOTIATE_MESSAGE_check); -#if 0 torture_suite_add_ndr_pull_test(suite, CHALLENGE_MESSAGE, ntlmssp_CHALLENGE_MESSAGE_data, ntlmssp_CHALLENGE_MESSAGE_check); torture_suite_add_ndr_pull_test(suite, AUTHENTICATE_MESSAGE, ntlmssp_AUTHENTICATE_MESSAGE_data, ntlmssp_AUTHENTICATE_MESSAGE_check); -#endif + return suite; } -- 1.9.1 From c08b846eb6ba81b357b79a9a074bbc02750725da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 18:30:16 +0100 Subject: [PATCH 007/323] s4-torture: flesh out ntlmssp_CHALLENGE_MESSAGE_check(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit fe1be37c71a816458173082fa9213a3f279a0b79) --- source4/torture/ndr/ntlmssp.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index 0a593ba..cd4a67f 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -76,6 +76,49 @@ static const uint8_t ntlmssp_CHALLENGE_MESSAGE_data[] = { static bool ntlmssp_CHALLENGE_MESSAGE_check(struct torture_context *tctx, struct CHALLENGE_MESSAGE *r) { + uint8_t chal[8] = { 0xed, 0xc8, 0x2b, 0x7d, 0x2e, 0xd7, 0xd0, 0xd9 }; + uint8_t data[8] = { 0 }; + + torture_assert_str_equal(tctx, r->Signature, "NTLMSSP", "Signature"); + torture_assert_int_equal(tctx, r->MessageType, NtLmChallenge, "MessageType"); + torture_assert_int_equal(tctx, r->TargetNameLen, 10, "TargetNameLen"); + torture_assert_int_equal(tctx, r->TargetNameMaxLen, 10, "TargetNameMaxLen"); + torture_assert_str_equal(tctx, r->TargetName, "SAMBA", "TargetName"); + torture_assert_int_equal(tctx, r->NegotiateFlags, 0xe2898295, "NegotiateFlags"); + torture_assert_mem_equal(tctx, r->ServerChallenge, chal, 8, "ServerChallenge"); + torture_assert_mem_equal(tctx, r->Reserved, data, 8, "Reserved"); + torture_assert_int_equal(tctx, r->TargetInfoLen, 120, "TargetInfoLen"); + torture_assert_int_equal(tctx, r->TargetInfoMaxLen, 120, "TargetInfoMaxLen"); + torture_assert_int_equal(tctx, r->TargetInfo->count, 5, "TargetInfo->count"); + + torture_assert_int_equal(tctx, r->TargetInfo->pair[0].AvId, MsvAvNbDomainName, "AvId"); + torture_assert_int_equal(tctx, r->TargetInfo->pair[0].AvLen, 10, "AvLen"); + torture_assert_str_equal(tctx, r->TargetInfo->pair[0].Value.AvNbDomainName, "SAMBA", "AvNbDomainName"); + + torture_assert_int_equal(tctx, r->TargetInfo->pair[1].AvId, MsvAvNbComputerName, "AvId"); + torture_assert_int_equal(tctx, r->TargetInfo->pair[1].AvLen, 16, "AvLen"); + torture_assert_str_equal(tctx, r->TargetInfo->pair[1].Value.AvNbComputerName, "MTHELENA", "AvNbComputerName"); + + torture_assert_int_equal(tctx, r->TargetInfo->pair[2].AvId, MsvAvDnsDomainName, "AvId"); + torture_assert_int_equal(tctx, r->TargetInfo->pair[2].AvLen, 28, "AvLen"); + torture_assert_str_equal(tctx, r->TargetInfo->pair[2].Value.AvDnsDomainName, "ber.redhat.com", "AvDnsDomainName"); + + torture_assert_int_equal(tctx, r->TargetInfo->pair[3].AvId, MsvAvDnsComputerName, "AvId"); + torture_assert_int_equal(tctx, r->TargetInfo->pair[3].AvLen, 46, "AvLen"); + torture_assert_str_equal(tctx, r->TargetInfo->pair[3].Value.AvDnsComputerName, "mthelena.ber.redhat.com", "AvDnsComputerName"); + + torture_assert_int_equal(tctx, r->TargetInfo->pair[4].AvId, MsvAvEOL, "AvId"); + torture_assert_int_equal(tctx, r->TargetInfo->pair[4].AvLen, 0, "AvLen"); + + torture_assert_int_equal(tctx, r->Version.version.ProductMajorVersion, NTLMSSP_WINDOWS_MAJOR_VERSION_6, "ProductMajorVersion"); + torture_assert_int_equal(tctx, r->Version.version.ProductMinorVersion, NTLMSSP_WINDOWS_MINOR_VERSION_1, "ProductMinorVersion"); + torture_assert_int_equal(tctx, r->Version.version.ProductBuild, 0, "ProductBuild"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[0], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[1], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[2], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[3], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.NTLMRevisionCurrent, NTLMSSP_REVISION_W2K3, "NTLMRevisionCurrent"); + return true; } -- 1.9.1 From 2d25b6e4bdf8faac3a5584cf93ea74ad1887bc7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 18:32:28 +0100 Subject: [PATCH 008/323] s4-torture: add ndr pullpush validation for NTLMSSP CHALLENGE and AUTHENTICATE messages. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit 68b9b18e6cd346e2aa32418642b0746cee593be3) --- source4/torture/ndr/ntlmssp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index cd4a67f..f00c26e 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -177,5 +177,15 @@ struct torture_suite *ndr_ntlmssp_suite(TALLOC_CTX *ctx) torture_suite_add_ndr_pull_test(suite, CHALLENGE_MESSAGE, ntlmssp_CHALLENGE_MESSAGE_data, ntlmssp_CHALLENGE_MESSAGE_check); torture_suite_add_ndr_pull_test(suite, AUTHENTICATE_MESSAGE, ntlmssp_AUTHENTICATE_MESSAGE_data, ntlmssp_AUTHENTICATE_MESSAGE_check); + torture_suite_add_ndr_pullpush_test(suite, + NEGOTIATE_MESSAGE, + data_blob_const(ntlmssp_NEGOTIATE_MESSAGE_data, sizeof(ntlmssp_NEGOTIATE_MESSAGE_data)), + ntlmssp_NEGOTIATE_MESSAGE_check); + + torture_suite_add_ndr_pullpush_test(suite, + CHALLENGE_MESSAGE, + data_blob_const(ntlmssp_CHALLENGE_MESSAGE_data, sizeof(ntlmssp_CHALLENGE_MESSAGE_data)), + ntlmssp_CHALLENGE_MESSAGE_check); + return suite; } -- 1.9.1 From e8a897f2e8fad6d209fffdbdeed9cdcaa4a510a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 17 Nov 2015 18:35:29 +0100 Subject: [PATCH 009/323] s4-torture: flesh out ntlmssp_AUTHENTICATE_MESSAGE_check(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Andreas Schneider (cherry picked from commit e073f3c0b622f49ffad7082b9b4fbc429c48d530) --- source4/torture/ndr/ntlmssp.c | 107 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index f00c26e..5b879c6 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -166,6 +166,113 @@ static const uint8_t ntlmssp_AUTHENTICATE_MESSAGE_data[] = { static bool ntlmssp_AUTHENTICATE_MESSAGE_check(struct torture_context *tctx, struct AUTHENTICATE_MESSAGE *r) { + uint8_t lm_challenge_response[24] = { 0 }; + struct NTLMv2_RESPONSE v2; + struct AV_PAIR_LIST AvPairs; + uint8_t Response[16] = { + 0x38, 0xcf, 0xfb, 0x39, 0x5a, 0xb3, 0x4c, 0x58, + 0x86, 0x35, 0xa3, 0xe7, 0x1e, 0x00, 0x98, 0x43 + }; + uint8_t ChallengeFromClient[8] = { + 0x3c, 0x21, 0x0a, 0xe9, 0xde, 0x61, 0xc0, 0x7e + }; + uint8_t MachineId[32] = { + 0x0a, 0xfd, 0x3b, 0x2c, 0xad, 0x43, 0x46, 0x8b, + 0x49, 0x01, 0x6c, 0xa5, 0xf3, 0xbc, 0xd2, 0x13, + 0xbb, 0x70, 0xe2, 0x65, 0x96, 0xba, 0x0d, 0x8d, + 0x5d, 0x31, 0xe6, 0x47, 0x94, 0x61, 0xed, 0x28 + }; + uint8_t EncryptedRandomSessionKey[16] = { + 0xA4, 0x23, 0xD4, 0x5C, 0x16, 0x52, 0x8D, 0x56, + 0x34, 0x2D, 0x1C, 0xFF, 0x86, 0x17, 0xC9, 0x4F + }; + + torture_assert_str_equal(tctx, r->Signature, "NTLMSSP", "Signature"); + torture_assert_int_equal(tctx, r->MessageType, NtLmAuthenticate, "MessageType"); + torture_assert_int_equal(tctx, r->LmChallengeResponseLen, 24, "LmChallengeResponseLen"); + torture_assert_int_equal(tctx, r->LmChallengeResponseMaxLen, 24, "LmChallengeResponseMaxLen"); + torture_assert_mem_equal(tctx, r->LmChallengeResponse->v1.Response, lm_challenge_response, 24, "LmChallengeResponse"); + + torture_assert_int_equal(tctx, r->NtChallengeResponseLen, 270, "NtChallengeResponseLen"); + torture_assert_int_equal(tctx, r->NtChallengeResponseMaxLen, 270, "NtChallengeResponseMaxLen"); + + v2 = r->NtChallengeResponse->v2; + + torture_assert_mem_equal(tctx, v2.Response, Response, 16, "v2.Response"); + torture_assert_int_equal(tctx, v2.Challenge.RespType, 1, "RespType"); + torture_assert_int_equal(tctx, v2.Challenge.HiRespType, 1, "HiRespType"); + torture_assert_int_equal(tctx, v2.Challenge.Reserved1, 0, "Reserved1"); + torture_assert_int_equal(tctx, v2.Challenge.Reserved2, 0, "Reserved2"); + /* TimeStamp : Tue Sep 14 17:06:53 2010 CEST */ + torture_assert_mem_equal(tctx, v2.Challenge.ChallengeFromClient, ChallengeFromClient, 8, "v2.Challenge.ChallengeFromClient"); + torture_assert_int_equal(tctx, v2.Challenge.Reserved3, 0, "Reserved3"); + + AvPairs = v2.Challenge.AvPairs; + + torture_assert_int_equal(tctx, AvPairs.count, 8, "AvPairs.count"); + + torture_assert_int_equal(tctx, AvPairs.pair[0].AvId, MsvAvNbDomainName, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[0].AvLen, 10, "AvLen"); + torture_assert_str_equal(tctx, AvPairs.pair[0].Value.AvNbDomainName, "SAMBA", "Value.AvNbDomainName"); + + torture_assert_int_equal(tctx, AvPairs.pair[1].AvId, MsvAvNbComputerName, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[1].AvLen, 16, "AvLen"); + torture_assert_str_equal(tctx, AvPairs.pair[1].Value.AvNbComputerName, "MTHELENA", "Value.AvNbComputerName"); + + torture_assert_int_equal(tctx, AvPairs.pair[2].AvId, MsvAvDnsDomainName, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[2].AvLen, 28, "AvLen"); + torture_assert_str_equal(tctx, AvPairs.pair[2].Value.AvDnsDomainName, "ber.redhat.com", "Value.AvDnsDomainName"); + + torture_assert_int_equal(tctx, AvPairs.pair[3].AvId, MsvAvDnsComputerName, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[3].AvLen, 46, "AvLen"); + torture_assert_str_equal(tctx, AvPairs.pair[3].Value.AvDnsComputerName, "mthelena.ber.redhat.com", "Value.AvDnsComputerName"); + + torture_assert_int_equal(tctx, AvPairs.pair[4].AvId, MsAvRestrictions, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[4].AvLen, 48, "AvLen"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.Size, 48, "Value.AvRestrictions.Size"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.Z4, 0, "Value.AvRestrictions.Z4"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.IntegrityLevel, 0, "Value.AvRestrictions.IntegrityLevel"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.SubjectIntegrityLevel, 0x00003000, "Value.AvRestrictions.SubjectIntegrityLevel"); + torture_assert_mem_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.MachineId, MachineId, 32, "Value.AvRestrictions.MachineId"); + + torture_assert_int_equal(tctx, AvPairs.pair[5].AvId, MsvChannelBindings, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[5].AvLen, 16, "AvLen"); + torture_assert_mem_equal(tctx, AvPairs.pair[5].Value.ChannelBindings, lm_challenge_response, 16, "Value.ChannelBindings"); + + torture_assert_int_equal(tctx, AvPairs.pair[6].AvId, MsvAvTargetName, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[6].AvLen, 26, "AvLen"); + torture_assert_str_equal(tctx, AvPairs.pair[6].Value.AvTargetName, "cifs/mthelena", "Value.AvTargetName"); + + torture_assert_int_equal(tctx, AvPairs.pair[7].AvId, MsvAvEOL, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[7].AvLen, 0, "AvLen"); + + torture_assert_int_equal(tctx, r->DomainNameLen, 14, "DomainNameLen"); + torture_assert_int_equal(tctx, r->DomainNameMaxLen, 14, "DomainNameMaxLen"); + torture_assert_str_equal(tctx, r->DomainName, "W2K8DOM", "DomainName"); + + torture_assert_int_equal(tctx, r->UserNameLen, 26, "UserNameLen"); + torture_assert_int_equal(tctx, r->UserNameMaxLen, 26, "UserNameMaxLen"); + torture_assert_str_equal(tctx, r->UserName, "Administrator", "UserName"); + + torture_assert_int_equal(tctx, r->WorkstationLen, 12, "WorkstationLen"); + torture_assert_int_equal(tctx, r->WorkstationMaxLen, 12, "WorkstationMaxLen"); + torture_assert_str_equal(tctx, r->Workstation, "W2K8R2", "Workstation"); + + torture_assert_int_equal(tctx, r->EncryptedRandomSessionKeyLen, 16, "EncryptedRandomSessionKeyLen"); + torture_assert_int_equal(tctx, r->EncryptedRandomSessionKeyMaxLen, 16, "EncryptedRandomSessionKeyMaxLen"); + torture_assert_mem_equal(tctx, r->EncryptedRandomSessionKey->data, EncryptedRandomSessionKey, 16, "EncryptedRandomSessionKeyMaxLen"); + + torture_assert_int_equal(tctx, r->NegotiateFlags, 0xe2888215, "NegotiateFlags"); + + torture_assert_int_equal(tctx, r->Version.version.ProductMajorVersion, NTLMSSP_WINDOWS_MAJOR_VERSION_6, "ProductMajorVersion"); + torture_assert_int_equal(tctx, r->Version.version.ProductMinorVersion, NTLMSSP_WINDOWS_MINOR_VERSION_1, "ProductMinorVersion"); + torture_assert_int_equal(tctx, r->Version.version.ProductBuild, 0x1db0, "ProductBuild"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[0], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[1], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[2], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.Reserved[3], 0x00, "Reserved"); + torture_assert_int_equal(tctx, r->Version.version.NTLMRevisionCurrent, NTLMSSP_REVISION_W2K3, "NTLMRevisionCurrent"); + return true; } -- 1.9.1 From dc5216ad14967e9a459f68680edda5ad7e026e43 Mon Sep 17 00:00:00 2001 From: Christian Ambach Date: Mon, 8 Feb 2016 23:20:19 +0100 Subject: [PATCH 010/323] s4:torture/ntlmssp fix a compiler warning about invalid array subscript BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Christian Ambach Reviewed-by: Andreas Schneider (cherry picked from commit 8ca0f14b5c4ac85e40c9c96f8f5ebb569335f031) --- source4/torture/ndr/ntlmssp.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index 5b879c6..ae56192 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -48,7 +48,6 @@ static bool ntlmssp_NEGOTIATE_MESSAGE_check(struct torture_context *tctx, torture_assert_int_equal(tctx, r->Version.version.Reserved[0], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.Reserved[1], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.Reserved[2], 0x00, "Reserved"); - torture_assert_int_equal(tctx, r->Version.version.Reserved[3], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.NTLMRevisionCurrent, NTLMSSP_REVISION_W2K3, "NTLMRevisionCurrent"); return true; @@ -116,7 +115,6 @@ static bool ntlmssp_CHALLENGE_MESSAGE_check(struct torture_context *tctx, torture_assert_int_equal(tctx, r->Version.version.Reserved[0], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.Reserved[1], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.Reserved[2], 0x00, "Reserved"); - torture_assert_int_equal(tctx, r->Version.version.Reserved[3], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.NTLMRevisionCurrent, NTLMSSP_REVISION_W2K3, "NTLMRevisionCurrent"); return true; @@ -270,7 +268,6 @@ static bool ntlmssp_AUTHENTICATE_MESSAGE_check(struct torture_context *tctx, torture_assert_int_equal(tctx, r->Version.version.Reserved[0], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.Reserved[1], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.Reserved[2], 0x00, "Reserved"); - torture_assert_int_equal(tctx, r->Version.version.Reserved[3], 0x00, "Reserved"); torture_assert_int_equal(tctx, r->Version.version.NTLMRevisionCurrent, NTLMSSP_REVISION_W2K3, "NTLMRevisionCurrent"); return true; -- 1.9.1 From 96367c1bea41314f2f6cb3e211ff6369f8252484 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 11 Jan 2016 21:49:21 +0100 Subject: [PATCH 011/323] spnego: Correctly check asn1_tag_remaining retval BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Guenther Deschner (cherry picked from commit 024c619fa82960ae4f8af029b6872102202ffd07) --- source3/libsmb/clispnego.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 82f13b7..9aab8fd 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -349,7 +349,7 @@ bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob, if (!asn1_end_tag(data)) goto err; /* the second challenge is optional (XP doesn't send it) */ - if (asn1_tag_remaining(data)) { + if (asn1_tag_remaining(data) > 0) { if (!asn1_start_tag(data,ASN1_CONTEXT(3))) goto err; if (!asn1_read_OctetString(data, ctx, chal2)) goto err; if (!asn1_end_tag(data)) goto err; @@ -438,12 +438,12 @@ bool spnego_parse_auth_response(TALLOC_CTX *ctx, if (!asn1_check_enumerated(data, negResult)) goto err; if (!asn1_end_tag(data)) goto err; - if (asn1_tag_remaining(data)) { + if (asn1_tag_remaining(data) > 0) { if (!asn1_start_tag(data,ASN1_CONTEXT(1))) goto err; if (!asn1_check_OID(data, mechOID)) goto err; if (!asn1_end_tag(data)) goto err; - if (asn1_tag_remaining(data)) { + if (asn1_tag_remaining(data) > 0) { if (!asn1_start_tag(data,ASN1_CONTEXT(2))) goto err; if (!asn1_read_OctetString(data, ctx, auth)) goto err; if (!asn1_end_tag(data)) goto err; @@ -457,7 +457,7 @@ bool spnego_parse_auth_response(TALLOC_CTX *ctx, * the optional mechListMIC field. This is a bug in Win2K. We ignore * this field if it exists. Win2K8 may return a proper mechListMIC at * which point we need to implement the integrity checking. */ - if (asn1_tag_remaining(data)) { + if (asn1_tag_remaining(data) > 0) { DATA_BLOB mechList = data_blob_null; if (!asn1_start_tag(data, ASN1_CONTEXT(3))) goto err; if (!asn1_read_OctetString(data, ctx, &mechList)) goto err; -- 1.9.1 From 69d9a75bc716e082833b006f5b8ca43d8224306c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Mar 2016 02:18:38 +0100 Subject: [PATCH 012/323] lib/util_net: move ipv6 linklocal handling into interpret_string_addr_internal() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 771042a2387b596fff2ab59a1a68d75c6c27b2cc) --- lib/util/util_net.c | 95 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 39 deletions(-) diff --git a/lib/util/util_net.c b/lib/util/util_net.c index d58855d..f5fe323 100644 --- a/lib/util/util_net.c +++ b/lib/util/util_net.c @@ -49,6 +49,10 @@ bool interpret_string_addr_internal(struct addrinfo **ppres, { int ret; struct addrinfo hints; +#if defined(HAVE_IPV6) + char addr[INET6_ADDRSTRLEN] = { 0, }; + unsigned int scope_id = 0; +#endif ZERO_STRUCT(hints); @@ -58,8 +62,60 @@ bool interpret_string_addr_internal(struct addrinfo **ppres, /* always try as a numeric host first. This prevents unnecessary name * lookups, and also ensures we accept IPv6 addresses */ hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + +#if defined(HAVE_IPV6) + if (strchr_m(str, ':')) { + char *p = strchr_m(str, '%'); + + /* + * Cope with link-local. + * This is IP:v6:addr%ifname. + */ + + if (p && (p > str) && ((scope_id = if_nametoindex(p+1)) != 0)) { + /* Length of string we want to copy. + This is IP:v6:addr (removing the %ifname). + */ + size_t len = PTR_DIFF(p,str); + + if (len+1 > sizeof(addr)) { + /* string+nul too long for array. */ + return false; + } + memcpy(addr, str, len); + addr[len] = '\0'; + + str = addr; + } + } +#endif + ret = getaddrinfo(str, NULL, &hints, ppres); if (ret == 0) { +#if defined(HAVE_IPV6) + struct sockaddr_in6 *ps6 = NULL; + + if (scope_id == 0) { + return true; + } + if (ppres == NULL) { + return true; + } + if ((*ppres) == NULL) { + return true; + } + if ((*ppres)->ai_addr->sa_family != AF_INET6) { + return true; + } + + ps6 = (struct sockaddr_in6 *)(*ppres)->ai_addr; + + if (IN6_IS_ADDR_LINKLOCAL(&ps6->sin6_addr) && + ps6->sin6_scope_id == 0) { + ps6->sin6_scope_id = scope_id; + } +#endif + return true; } @@ -94,35 +150,6 @@ static bool interpret_string_addr_pref(struct sockaddr_storage *pss, { struct addrinfo *res = NULL; int int_flags; -#if defined(HAVE_IPV6) - char addr[INET6_ADDRSTRLEN]; - unsigned int scope_id = 0; - - if (strchr_m(str, ':')) { - char *p = strchr_m(str, '%'); - - /* - * Cope with link-local. - * This is IP:v6:addr%ifname. - */ - - if (p && (p > str) && ((scope_id = if_nametoindex(p+1)) != 0)) { - /* Length of string we want to copy. - This is IP:v6:addr (removing the %ifname). - */ - size_t len = PTR_DIFF(p,str); - - if (len+1 > sizeof(addr)) { - /* string+nul too long for array. */ - return false; - } - memcpy(addr, str, len); - addr[len] = '\0'; - - str = addr; - } - } -#endif zero_sockaddr(pss); @@ -157,16 +184,6 @@ static bool interpret_string_addr_pref(struct sockaddr_storage *pss, memcpy(pss, res->ai_addr, res->ai_addrlen); } -#if defined(HAVE_IPV6) - if (pss->ss_family == AF_INET6 && scope_id) { - struct sockaddr_in6 *ps6 = (struct sockaddr_in6 *)pss; - if (IN6_IS_ADDR_LINKLOCAL(&ps6->sin6_addr) && - ps6->sin6_scope_id == 0) { - ps6->sin6_scope_id = scope_id; - } - } -#endif - freeaddrinfo(res); return true; } -- 1.9.1 From 03e2d77cee4ce14fea33ef1ae33987e35702c596 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Mar 2016 02:18:38 +0100 Subject: [PATCH 013/323] lib/util_net: add support for .ipv6-literal.net MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 6400bbb5eee958babbdd578c2f80b0c65d6f6e7a) --- lib/util/util_net.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++-- lib/util/util_net.h | 1 + 2 files changed, 154 insertions(+), 5 deletions(-) diff --git a/lib/util/util_net.c b/lib/util/util_net.c index f5fe323..e5b33aa 100644 --- a/lib/util/util_net.c +++ b/lib/util/util_net.c @@ -41,6 +41,115 @@ void zero_sockaddr(struct sockaddr_storage *pss) pss->ss_family = AF_INET; } +static char *normalize_ipv6_literal(const char *str, char *buf, size_t *_len) +{ +#define IPv6_LITERAL_NET ".ipv6-literal.net" + static const size_t llen = sizeof(IPv6_LITERAL_NET) - 1; + size_t len = *_len; + int cmp; + size_t i; + size_t idx_chars = 0; + size_t cnt_delimiter = 0; + size_t cnt_chars = 0; + + if (len <= llen) { + return false; + } + + /* ignore a trailing '.' */ + if (str[len - 1] == '.') { + len -= 1; + } + + len -= llen; + if (len >= INET6_ADDRSTRLEN) { + return NULL; + } + if (len < 2) { + return NULL; + } + + cmp = strncasecmp(&str[len], IPv6_LITERAL_NET, llen); + if (cmp != 0) { + return NULL; + } + + for (i = 0; i < len; i++) { + if (idx_chars != 0) { + break; + } + + switch (str[i]) { + case '-': + buf[i] = ':'; + cnt_chars = 0; + cnt_delimiter += 1; + break; + case 's': + buf[i] = '%'; + idx_chars += 1; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'A': + case 'b': + case 'B': + case 'c': + case 'C': + case 'd': + case 'D': + case 'e': + case 'E': + case 'f': + case 'F': + buf[i] = str[i]; + cnt_chars += 1; + break; + default: + return NULL; + } + if (cnt_chars > 4) { + return NULL; + } + if (cnt_delimiter > 7) { + return NULL; + } + } + + if (cnt_delimiter < 2) { + return NULL; + } + + for (; idx_chars != 0 && i < len; i++) { + switch (str[i]) { + case '%': + case ':': + return NULL; + default: + buf[i] = str[i]; + idx_chars += 1; + break; + } + } + + if (idx_chars == 1) { + return NULL; + } + + buf[i] = '\0'; + *_len = len; + return buf; +} + /** * Wrap getaddrinfo... */ @@ -50,8 +159,9 @@ bool interpret_string_addr_internal(struct addrinfo **ppres, int ret; struct addrinfo hints; #if defined(HAVE_IPV6) - char addr[INET6_ADDRSTRLEN] = { 0, }; + char addr[INET6_ADDRSTRLEN*2] = { 0, }; unsigned int scope_id = 0; + size_t len = strlen(str); #endif ZERO_STRUCT(hints); @@ -64,6 +174,16 @@ bool interpret_string_addr_internal(struct addrinfo **ppres, hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; #if defined(HAVE_IPV6) + if (len < sizeof(addr)) { + char *p = NULL; + + p = normalize_ipv6_literal(str, addr, &len); + if (p != NULL) { + hints.ai_family = AF_INET6; + str = p; + } + } + if (strchr_m(str, ':')) { char *p = strchr_m(str, '%'); @@ -76,13 +196,15 @@ bool interpret_string_addr_internal(struct addrinfo **ppres, /* Length of string we want to copy. This is IP:v6:addr (removing the %ifname). */ - size_t len = PTR_DIFF(p,str); + len = PTR_DIFF(p,str); if (len+1 > sizeof(addr)) { /* string+nul too long for array. */ return false; } - memcpy(addr, str, len); + if (str != addr) { + memcpy(addr, str, len); + } addr[len] = '\0'; str = addr; @@ -337,6 +459,28 @@ bool is_ipaddress_v4(const char *str) return false; } +bool is_ipv6_literal(const char *str) +{ +#if defined(HAVE_IPV6) + char buf[INET6_ADDRSTRLEN*2] = { 0, }; + size_t len = strlen(str); + char *p = NULL; + + if (len >= sizeof(buf)) { + return false; + } + + p = normalize_ipv6_literal(str, buf, &len); + if (p == NULL) { + return false; + } + + return true; +#else + return false; +#endif +} + /** * Return true if a string could be a IPv6 address. */ @@ -345,16 +489,20 @@ bool is_ipaddress_v6(const char *str) { #if defined(HAVE_IPV6) int ret = -1; + char *p = NULL; - if (strchr_m(str, ':')) { + p = strchr_m(str, ':'); + if (p == NULL) { + return is_ipv6_literal(str); + } else { char buf[INET6_ADDRSTRLEN] = { 0, }; size_t len; const char *addr = str; const char *idxs = NULL; unsigned int idx = 0; struct in6_addr ip6; - char *p = strchr_m(str, '%'); + p = strchr_m(str, '%'); if (p && (p > str)) { len = PTR_DIFF(p, str); idxs = p + 1; diff --git a/lib/util/util_net.h b/lib/util/util_net.h index 2f1beff..29468b4 100644 --- a/lib/util/util_net.h +++ b/lib/util/util_net.h @@ -86,6 +86,7 @@ _PUBLIC_ uint32_t interpret_addr(const char *str); _PUBLIC_ struct in_addr interpret_addr2(const char *str); _PUBLIC_ bool is_ipaddress_v4(const char *str); +_PUBLIC_ bool is_ipv6_literal(const char *str); _PUBLIC_ bool is_ipaddress_v6(const char *str); bool is_address_any(const struct sockaddr *psa); -- 1.9.1 From 87882822aa7beedfb2ab9ac1fa7d0128dc76cb81 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 8 Mar 2016 15:47:59 +0100 Subject: [PATCH 014/323] s3:test_smbclient_auth.sh: test using the ip address in the unc path (incl. ipv6-literal.net) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit e906739553ee6112426af0cf29e33ef1920a316c) --- source3/script/tests/test_smbclient_auth.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source3/script/tests/test_smbclient_auth.sh b/source3/script/tests/test_smbclient_auth.sh index 057414c..cc075b9 100755 --- a/source3/script/tests/test_smbclient_auth.sh +++ b/source3/script/tests/test_smbclient_auth.sh @@ -21,6 +21,17 @@ ADDARGS="$*" incdir=`dirname $0`/../../../testprogs/blackbox . $incdir/subunit.sh +echo "${SERVER_IP}" | grep -q ':.*:' && { + # If we have an ipv6 address e.g. + # fd00:0000:0000:0000:0000:0000:5357:5f03 + # we also try + # fd00-0000-0000-0000-0000-0000-5357-5f03.ipv6-literal.net + IPV6LITERAL=$(echo "${SERVER_IP}.ipv6-literal.net" | sed -e 's!:!-!g' -e 's!%!s!') + testit "smbclient //${IPV6LITERAL}/tmpguest" $SMBCLIENT //${IPV6LITERAL}/tmpguest $CONFIGURATION -U$USERNAME%$PASSWORD -c quit $ADDARGS + testit "smbclient //${IPV6LITERAL}./tmpguest" $SMBCLIENT //${IPV6LITERAL}./tmpguest $CONFIGURATION -U$USERNAME%$PASSWORD -c quit $ADDARGS +} +testit "smbclient //${SERVER_IP}/tmpguest" $SMBCLIENT //${SERVER_IP}/tmpguest $CONFIGURATION -U$USERNAME%$PASSWORD -p 139 -c quit $ADDARGS + testit "smbclient //$SERVER/guestonly" $SMBCLIENT //$SERVER/guestonly $CONFIGURATION -U$USERNAME%$PASSWORD -I $SERVER_IP -p 139 -c quit $ADDARGS testit "smbclient //$SERVER/guestonly as anon" $SMBCLIENT //$SERVER/guestonly $CONFIGURATION -U% -I $SERVER_IP -p 139 -c quit $ADDARGS testit "smbclient //$SERVER/tmpguest" $SMBCLIENT //$SERVER/tmpguest $CONFIGURATION -U$USERNAME%$PASSWORD -I $SERVER_IP -p 139 -c quit $ADDARGS -- 1.9.1 From 54eeb5e3b9fa2cec7756f9cff84dd28b8559851a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 8 Mar 2016 15:53:21 +0100 Subject: [PATCH 015/323] s3:selftest: run samba3.blackbox.smbclient_auth.plain also with $SERVER_IPV6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 2c9f9557e4d7e02b4f588aa0a6551a6881ac57af) --- source3/selftest/tests.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 71b4e21..e2d9c38 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -136,6 +136,9 @@ for env in ["nt4_dc", "nt4_member", "ad_member"]: plantestsuite("samba3.blackbox.smbclient_auth.plain (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_smbclient_auth.sh"), '$SERVER', '$SERVER_IP', '$DC_USERNAME', '$DC_PASSWORD', smbclient3, configuration]) plantestsuite("samba3.blackbox.smbclient_auth.plain (%s) member creds" % env, env, [os.path.join(samba3srcdir, "script/tests/test_smbclient_auth.sh"), '$SERVER', '$SERVER_IP', '$SERVER/$USERNAME', '$PASSWORD', smbclient3, configuration]) +env="nt4_dc" +plantestsuite("samba3.blackbox.smbclient_auth.plain (%s) ipv6" % env, env, [os.path.join(samba3srcdir, "script/tests/test_smbclient_auth.sh"), '$SERVER', '$SERVER_IPV6', '$SERVER/$USERNAME', '$PASSWORD', smbclient3, configuration]) + for env in ["nt4_member", "ad_member"]: plantestsuite("samba3.blackbox.net_cred_change.(%s:local)" % env, "%s:local" % env, [os.path.join(samba3srcdir, "script/tests/test_net_cred_change.sh"), configuration]) -- 1.9.1 From 28c7d20668401472552b0f94ecd04be88abb0186 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2015 17:15:24 +0200 Subject: [PATCH 016/323] epmapper.idl: make epm_twr_t available in python bindings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 2e71f5d9351b9660a5ef94309674e09fdeb7ab48) --- librpc/idl/epmapper.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/epmapper.idl b/librpc/idl/epmapper.idl index 5f3d653..fd8eeb4 100644 --- a/librpc/idl/epmapper.idl +++ b/librpc/idl/epmapper.idl @@ -214,7 +214,7 @@ interface epmapper epm_floor floors[num_floors]; } epm_tower; - typedef struct { + typedef [public] struct { [value(ndr_size_epm_tower(&tower, ndr->flags))] uint32 tower_length; [subcontext(4)] epm_tower tower; } epm_twr_t; -- 1.9.1 From e042518f5fe0793f45c689848c7a9319fd2fb936 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Jul 2015 03:35:19 +0200 Subject: [PATCH 017/323] dcerpc.idl: make WERROR RPC faults available in ndr_print output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 5afc2d85b3d17b32ca9bd2856958114af146f80e) --- librpc/idl/dcerpc.idl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl index 1036693..f7bf595 100644 --- a/librpc/idl/dcerpc.idl +++ b/librpc/idl/dcerpc.idl @@ -197,18 +197,21 @@ interface dcerpc DCERPC_NCA_S_FAULT_TX_OPEN_FAILED = 0x1C000022, DCERPC_NCA_S_FAULT_CODESET_CONV_ERROR = 0x1C000023, DCERPC_NCA_S_FAULT_OBJECT_NOT_FOUND = 0x1C000024, - DCERPC_NCA_S_FAULT_NO_CLIENT_STUB = 0x1C000025 + DCERPC_NCA_S_FAULT_NO_CLIENT_STUB = 0x1C000025, + DCERPC_FAULT_ACCESS_DENIED = 0x00000005, + DCERPC_FAULT_NO_CALL_ACTIVE = 0x000006bd, + DCERPC_FAULT_CANT_PERFORM = 0x000006d8, + DCERPC_FAULT_OUT_OF_RESOURCES = 0x000006d9, + DCERPC_FAULT_BAD_STUB_DATA = 0x000006f7, + DCERPC_FAULT_SEC_PKG_ERROR = 0x00000721 } dcerpc_nca_status; const int DCERPC_FAULT_OP_RNG_ERROR = DCERPC_NCA_S_OP_RNG_ERROR; const int DCERPC_FAULT_UNK_IF = DCERPC_NCA_S_UNKNOWN_IF; - const int DCERPC_FAULT_NDR = 0x000006f7; + const int DCERPC_FAULT_NDR = DCERPC_FAULT_BAD_STUB_DATA; const int DCERPC_FAULT_INVALID_TAG = DCERPC_NCA_S_FAULT_INVALID_TAG; const int DCERPC_FAULT_CONTEXT_MISMATCH = DCERPC_NCA_S_FAULT_CONTEXT_MISMATCH; const int DCERPC_FAULT_OTHER = 0x00000001; - const int DCERPC_FAULT_ACCESS_DENIED = 0x00000005; - const int DCERPC_FAULT_CANT_PERFORM = 0x000006d8; - const int DCERPC_FAULT_SEC_PKG_ERROR = 0x00000721; /* we return this fault when we haven't yet run the test to see what fault w2k3 returns in this case */ -- 1.9.1 From 7fe7bd122a5fa46f0bb9b7bd3e954a4ef45d743b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Jul 2015 03:36:36 +0200 Subject: [PATCH 018/323] librpc/rpc: add error mappings for NO_CALL_ACTIVE, OUT_OF_RESOURCES and BAD_STUB_DATA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit e9e9ba7eaecf2b6d95e79fbe424e1479e9468d63) --- librpc/rpc/dcerpc_error.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/librpc/rpc/dcerpc_error.c b/librpc/rpc/dcerpc_error.c index 2b90334..f386025 100644 --- a/librpc/rpc/dcerpc_error.c +++ b/librpc/rpc/dcerpc_error.c @@ -88,9 +88,11 @@ static const struct dcerpc_fault_table dcerpc_faults[] = _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_OBJECT_NOT_FOUND), _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_NO_CLIENT_STUB), _FAULT_STR(DCERPC_FAULT_OTHER, NT_STATUS_RPC_CALL_FAILED), - _FAULT_STR(DCERPC_FAULT_CANT_PERFORM, NT_STATUS_EPT_CANT_PERFORM_OP), - _FAULT_STR(DCERPC_FAULT_NDR, NT_STATUS_RPC_BAD_STUB_DATA), _FAULT_STR(DCERPC_FAULT_ACCESS_DENIED, NT_STATUS_ACCESS_DENIED), + _FAULT_STR(DCERPC_FAULT_NO_CALL_ACTIVE, NT_STATUS_RPC_NO_CALL_ACTIVE), + _FAULT_STR(DCERPC_FAULT_CANT_PERFORM, NT_STATUS_EPT_CANT_PERFORM_OP), + _FAULT_STR(DCERPC_FAULT_OUT_OF_RESOURCES, NT_STATUS_RPC_OUT_OF_RESOURCES), + _FAULT_STR(DCERPC_FAULT_BAD_STUB_DATA, NT_STATUS_RPC_BAD_STUB_DATA), _FAULT_STR(DCERPC_FAULT_SEC_PKG_ERROR, NT_STATUS_RPC_SEC_PKG_ERROR), { NULL, 0 } #undef _FAULT_STR -- 1.9.1 From 07e762a08963996531d12a4018a39c3d17056dd2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 11:06:47 +0100 Subject: [PATCH 019/323] s4:librpc/rpc: map alter context SEC_PKG_ERROR to NT_STATUS_LOGON_FAILURE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 960b0adfb398eeabd48213393bc560654baeed5b) --- source4/librpc/rpc/dcerpc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 33c37069..88a041c 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -2232,6 +2232,9 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, if (pkt->u.fault.status == DCERPC_FAULT_ACCESS_DENIED) { state->p->last_fault_code = pkt->u.fault.status; tevent_req_nterror(req, NT_STATUS_LOGON_FAILURE); + } else if (pkt->u.fault.status == DCERPC_FAULT_SEC_PKG_ERROR) { + state->p->last_fault_code = pkt->u.fault.status; + tevent_req_nterror(req, NT_STATUS_LOGON_FAILURE); } else { state->p->last_fault_code = pkt->u.fault.status; status = dcerpc_fault_to_nt_status(pkt->u.fault.status); -- 1.9.1 From 21513b632f1731bdabdf9de654d512fef7aea5c7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 14:36:14 +0100 Subject: [PATCH 020/323] s3:libads: remove unused ads_connect_gc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit cd8af25d4bf87a9156cb2afb3dd206c68b1bedd7) --- source3/libads/ads_proto.h | 1 - source3/libads/ldap.c | 134 --------------------------------------------- 2 files changed, 135 deletions(-) diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h index eb0dea9..425c352 100644 --- a/source3/libads/ads_proto.h +++ b/source3/libads/ads_proto.h @@ -66,7 +66,6 @@ bool ads_sitename_match(ADS_STRUCT *ads); bool ads_closest_dc(ADS_STRUCT *ads); ADS_STATUS ads_connect(ADS_STRUCT *ads); ADS_STATUS ads_connect_user_creds(ADS_STRUCT *ads); -ADS_STATUS ads_connect_gc(ADS_STRUCT *ads); void ads_disconnect(ADS_STRUCT *ads); ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6735072..f1e7d21 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -553,140 +553,6 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) c_realm, c_domain, nt_errstr(status))); return status; } - -/********************************************************************* - *********************************************************************/ - -static NTSTATUS ads_lookup_site(void) -{ - ADS_STRUCT *ads = NULL; - ADS_STATUS ads_status; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - - ads = ads_init(lp_realm(), NULL, NULL); - if (!ads) { - return NT_STATUS_NO_MEMORY; - } - - /* The NO_BIND here will find a DC and set the client site - but not establish the TCP connection */ - - ads->auth.flags = ADS_AUTH_NO_BIND; - ads_status = ads_connect(ads); - if (!ADS_ERR_OK(ads_status)) { - DEBUG(4, ("ads_lookup_site: ads_connect to our realm failed! (%s)\n", - ads_errstr(ads_status))); - } - nt_status = ads_ntstatus(ads_status); - - if (ads) { - ads_destroy(&ads); - } - - return nt_status; -} - -/********************************************************************* - *********************************************************************/ - -static const char* host_dns_domain(const char *fqdn) -{ - const char *p = fqdn; - - /* go to next char following '.' */ - - if ((p = strchr_m(fqdn, '.')) != NULL) { - p++; - } - - return p; -} - - -/** - * Connect to the Global Catalog server - * @param ads Pointer to an existing ADS_STRUCT - * @return status of connection - * - * Simple wrapper around ads_connect() that fills in the - * GC ldap server information - **/ - -ADS_STATUS ads_connect_gc(ADS_STRUCT *ads) -{ - TALLOC_CTX *frame = talloc_stackframe(); - struct dns_rr_srv *gcs_list; - int num_gcs; - const char *realm = ads->server.realm; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); - int i; - bool done = false; - char *sitename = NULL; - - if (!realm) - realm = lp_realm(); - - if ((sitename = sitename_fetch(frame, realm)) == NULL) { - ads_lookup_site(); - sitename = sitename_fetch(frame, realm); - } - - do { - /* We try once with a sitename and once without - (unless we don't have a sitename and then we're - done */ - - if (sitename == NULL) - done = true; - - nt_status = ads_dns_query_gcs(frame, - realm, - sitename, - &gcs_list, - &num_gcs); - - if (!NT_STATUS_IS_OK(nt_status)) { - ads_status = ADS_ERROR_NT(nt_status); - goto done; - } - - /* Loop until we get a successful connection or have gone - through them all. When connecting a GC server, make sure that - the realm is the server's DNS name and not the forest root */ - - for (i=0; iserver.gc = true; - ads->server.ldap_server = SMB_STRDUP(gcs_list[i].hostname); - ads->server.realm = SMB_STRDUP(host_dns_domain(ads->server.ldap_server)); - ads_status = ads_connect(ads); - if (ADS_ERR_OK(ads_status)) { - /* Reset the bind_dn to "". A Global Catalog server - may host multiple domain trees in a forest. - Windows 2003 GC server will accept "" as the search - path to imply search all domain trees in the forest */ - - SAFE_FREE(ads->config.bind_path); - ads->config.bind_path = SMB_STRDUP(""); - - - goto done; - } - SAFE_FREE(ads->server.ldap_server); - SAFE_FREE(ads->server.realm); - } - - TALLOC_FREE(gcs_list); - num_gcs = 0; - } while (!done); - -done: - talloc_destroy(frame); - - return ads_status; -} - - /** * Connect to the LDAP server * @param ads Pointer to an existing ADS_STRUCT -- 1.9.1 From ef7d1c02b4807328a6587ca94f82478c11c3424e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 15:18:22 +0200 Subject: [PATCH 021/323] wscript_configure_system_mitkrb5: add configure checks for GSS_KRB5_CRED_NO_CI_FLAGS_X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Newer MIT versions (maybe krb5-1.14) will also support this. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 1fd5bdafbddfd0ad2926ef50a0cb7d07956ddd44) --- wscript_configure_system_mitkrb5 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wscript_configure_system_mitkrb5 b/wscript_configure_system_mitkrb5 index 4b3a69f..34f81b6 100644 --- a/wscript_configure_system_mitkrb5 +++ b/wscript_configure_system_mitkrb5 @@ -59,7 +59,8 @@ conf.CHECK_FUNCS_IN('_et_list', 'com_err') conf.CHECK_HEADERS('com_err.h', lib='com_err') conf.CHECK_HEADERS('krb5.h krb5/locate_plugin.h', lib='krb5') -conf.CHECK_HEADERS('gssapi.h gssapi/gssapi_generic.h gssapi/gssapi.h gssapi/gssapi_ext.h gssapi/gssapi_krb5.h', lib='gssapi') +possible_gssapi_headers="gssapi.h gssapi/gssapi_generic.h gssapi/gssapi.h gssapi/gssapi_ext.h gssapi/gssapi_krb5.h gssapi/gssapi_oid.h" +conf.CHECK_HEADERS(possible_gssapi_headers, lib='gssapi') conf.CHECK_FUNCS_IN('krb5_encrypt_data', 'k5crypto') conf.CHECK_FUNCS_IN('des_set_key','crypto') @@ -87,6 +88,7 @@ conf.CHECK_FUNCS_IN(''' gss_krb5_export_lucid_sec_context gss_import_cred gss_export_cred ''', 'gssapi gssapi_krb5') +conf.CHECK_VARIABLE('GSS_KRB5_CRED_NO_CI_FLAGS_X', headers=possible_gssapi_headers) conf.CHECK_FUNCS_IN('krb5_mk_req_extended krb5_kt_compare', 'krb5') conf.CHECK_FUNCS(''' krb5_set_default_in_tkt_etypes krb5_set_default_tgs_enctypes -- 1.9.1 From 8595e7f64a08fddc314e0523ba1c3db2ecfcb6af Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 15:21:05 +0200 Subject: [PATCH 022/323] s3:librpc/gse: make use of GSS_C_EMPTY_BUFFER in gse_init_client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 46b92525181fa32c5797c914e8de92f3c226e3c7) --- source3/librpc/crypto/gse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 9c4cce2..7490987 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -201,7 +201,7 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, { struct gse_context *gse_ctx; OM_uint32 gss_maj, gss_min; - gss_buffer_desc name_buffer = {0, NULL}; + gss_buffer_desc name_buffer = GSS_C_EMPTY_BUFFER; gss_OID_set_desc mech_set; NTSTATUS status; -- 1.9.1 From 7406d683f6f0a16c80d40e652695033bed0318da Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 15:21:53 +0200 Subject: [PATCH 023/323] s3:librpc/gse: fix debug message in gse_init_client() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 84c66f1a388c8b5105f3740a3cd5d4d5a27f6ee8) --- source3/librpc/crypto/gse.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 7490987..6ba4d4a 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -255,8 +255,7 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, &gse_ctx->creds, NULL, NULL); if (gss_maj) { - DEBUG(0, ("gss_acquire_creds failed for %s, with [%s]\n", - (char *)name_buffer.value, + DEBUG(0, ("gss_acquire_creds failed for GSS_C_NO_NAME with [%s]\n", gse_errstr(gse_ctx, gss_maj, gss_min))); status = NT_STATUS_INTERNAL_ERROR; goto err_out; -- 1.9.1 From 8054bc499521f060ae19243f430f0fef01cff50e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Jun 2015 15:22:44 +0200 Subject: [PATCH 024/323] s3:librpc/gse: set GSS_KRB5_CRED_NO_CI_FLAGS_X in gse_init_client() if available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit a8fa078f1acbd9fb1a1681033922731dce855aad) --- source3/librpc/crypto/gse.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 6ba4d4a..543fdb7 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -203,6 +203,9 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, OM_uint32 gss_maj, gss_min; gss_buffer_desc name_buffer = GSS_C_EMPTY_BUFFER; gss_OID_set_desc mech_set; +#ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X + gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; +#endif NTSTATUS status; if (!server || !service) { @@ -261,6 +264,28 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, goto err_out; } +#ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X + /* + * Don't force GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG. + * + * This allows us to disable SIGN and SEAL for + * AUTH_LEVEL_CONNECT and AUTH_LEVEL_INTEGRITY. + * + * https://groups.yahoo.com/neo/groups/cat-ietf/conversations/topics/575 + * http://krbdev.mit.edu/rt/Ticket/Display.html?id=6938 + */ + gss_maj = gss_set_cred_option(&gss_min, &gse_ctx->creds, + GSS_KRB5_CRED_NO_CI_FLAGS_X, + &empty_buffer); + if (gss_maj) { + DEBUG(0, ("gss_set_cred_option(GSS_KRB5_CRED_NO_CI_FLAGS_X), " + "failed with [%s]\n", + gse_errstr(gse_ctx, gss_maj, gss_min))); + status = NT_STATUS_INTERNAL_ERROR; + goto err_out; + } +#endif + *_gse_ctx = gse_ctx; TALLOC_FREE(name_buffer.value); return NT_STATUS_OK; -- 1.9.1 From c60834a8d6b334d501353dbad70b366eaacc390d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 17:37:38 +0100 Subject: [PATCH 025/323] s3:librpc/gse: correctly support GENSEC_FEATURE_SESSION_KEY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit e4aebd7e28e7b00a13246b367eb2e7de5ae7b57b) --- source3/librpc/crypto/gse.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 543fdb7..e67c3d2 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -603,6 +603,9 @@ static NTSTATUS gensec_gse_client_start(struct gensec_security *gensec_security) return NT_STATUS_INVALID_PARAMETER; } + if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { + do_sign = true; + } if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { do_sign = true; } @@ -903,18 +906,15 @@ static bool gensec_gse_have_feature(struct gensec_security *gensec_security, talloc_get_type_abort(gensec_security->private_data, struct gse_context); + if (feature & GENSEC_FEATURE_SESSION_KEY) { + return gse_ctx->gss_got_flags & GSS_C_INTEG_FLAG; + } if (feature & GENSEC_FEATURE_SIGN) { return gse_ctx->gss_got_flags & GSS_C_INTEG_FLAG; } if (feature & GENSEC_FEATURE_SEAL) { return gse_ctx->gss_got_flags & GSS_C_CONF_FLAG; } - if (feature & GENSEC_FEATURE_SESSION_KEY) { - /* Only for GSE/Krb5 */ - if (smb_gss_oid_equal(gse_ctx->ret_mech, gss_mech_krb5)) { - return true; - } - } if (feature & GENSEC_FEATURE_DCE_STYLE) { return gse_ctx->gss_got_flags & GSS_C_DCE_STYLE; } -- 1.9.1 From 020198ea5af389462b39b16617098ee05cad2729 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 07:42:41 +0100 Subject: [PATCH 026/323] s3:librpc/gse: don't log gss_acquire_creds failed at level 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some callers just retry after a kinit. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 79bf88353488b5912435e0c7f8e77f2d075ce134) --- source3/librpc/crypto/gse.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index e67c3d2..a2f25ea 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -258,7 +258,8 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, &gse_ctx->creds, NULL, NULL); if (gss_maj) { - DEBUG(0, ("gss_acquire_creds failed for GSS_C_NO_NAME with [%s]\n", + DEBUG(5, ("gss_acquire_creds failed for GSS_C_NO_NAME with [%s] -" + "the caller may retry after a kinit.\n", gse_errstr(gse_ctx, gss_maj, gss_min))); status = NT_STATUS_INTERNAL_ERROR; goto err_out; -- 1.9.1 From c4e0c4a4a678472d769a642da66d4e2950caa44b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Mar 2016 02:52:29 +0100 Subject: [PATCH 027/323] s3:librpc/gse: implement gensec_gse_max_{input,wrapped}_size() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is important in order to support gensec_[un]wrap() with GENSEC_SEAL. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit dec9d085f3eea8d49fa129c05c030bdd779cba54) --- source3/librpc/crypto/gse.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index a2f25ea..ffdfde1 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -45,6 +45,7 @@ struct gse_context { gss_name_t server_name; gss_name_t client_name; OM_uint32 gss_want_flags, gss_got_flags; + size_t max_wrap_buf_size; size_t sig_size; gss_cred_id_t delegated_cred_handle; @@ -136,6 +137,7 @@ static NTSTATUS gse_context_init(TALLOC_CTX *mem_ctx, talloc_set_destructor((TALLOC_CTX *)gse_ctx, gse_context_destructor); gse_ctx->expire_time = GENSEC_EXPIRE_TIME_INFINITY; + gse_ctx->max_wrap_buf_size = UINT16_MAX; memcpy(&gse_ctx->gss_mech, gss_mech_krb5, sizeof(gss_OID_desc)); @@ -1071,6 +1073,40 @@ static NTSTATUS gensec_gse_session_info(struct gensec_security *gensec_security, return NT_STATUS_OK; } +static size_t gensec_gse_max_input_size(struct gensec_security *gensec_security) +{ + struct gse_context *gse_ctx = + talloc_get_type_abort(gensec_security->private_data, + struct gse_context); + OM_uint32 maj_stat, min_stat; + OM_uint32 max_input_size; + + maj_stat = gss_wrap_size_limit(&min_stat, + gse_ctx->gssapi_context, + gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), + GSS_C_QOP_DEFAULT, + gse_ctx->max_wrap_buf_size, + &max_input_size); + if (GSS_ERROR(maj_stat)) { + TALLOC_CTX *mem_ctx = talloc_new(NULL); + DEBUG(1, ("gensec_gssapi_max_input_size: determining signature size with gss_wrap_size_limit failed: %s\n", + gse_errstr(mem_ctx, maj_stat, min_stat))); + talloc_free(mem_ctx); + return 0; + } + + return max_input_size; +} + +/* Find out the maximum output size negotiated on this connection */ +static size_t gensec_gse_max_wrapped_size(struct gensec_security *gensec_security) +{ + struct gse_context *gse_ctx = + talloc_get_type_abort(gensec_security->private_data, + struct gse_context); + return gse_ctx->max_wrap_buf_size; +} + static size_t gensec_gse_sig_size(struct gensec_security *gensec_security, size_t data_size) { @@ -1110,6 +1146,8 @@ const struct gensec_security_ops gensec_gse_krb5_security_ops = { .check_packet = gensec_gse_check_packet, .seal_packet = gensec_gse_seal_packet, .unseal_packet = gensec_gse_unseal_packet, + .max_input_size = gensec_gse_max_input_size, + .max_wrapped_size = gensec_gse_max_wrapped_size, .wrap = gensec_gse_wrap, .unwrap = gensec_gse_unwrap, .have_feature = gensec_gse_have_feature, -- 1.9.1 From 81f33003f95e1b1b8d454f28450ff57be40e18e0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 19 Aug 2015 10:53:34 +0200 Subject: [PATCH 028/323] s4:pygensec: make sig_size() and sign/check_packet() available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 0f6713826dfe73b7f338b8110c53ce52d42efbda) --- source4/auth/gensec/pygensec.c | 83 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/source4/auth/gensec/pygensec.c b/source4/auth/gensec/pygensec.c index 3399869..eba84f0 100644 --- a/source4/auth/gensec/pygensec.c +++ b/source4/auth/gensec/pygensec.c @@ -530,6 +530,83 @@ static PyObject *py_gensec_unwrap(PyObject *self, PyObject *args) return ret; } +static PyObject *py_gensec_sig_size(PyObject *self, PyObject *args) +{ + struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); + Py_ssize_t data_size = 0; + size_t sig_size = 0; + + if (!PyArg_ParseTuple(args, "n", &data_size)) { + return NULL; + } + + sig_size = gensec_sig_size(security, data_size); + + return PyLong_FromSize_t(sig_size); +} + +static PyObject *py_gensec_sign_packet(PyObject *self, PyObject *args) +{ + NTSTATUS status; + TALLOC_CTX *mem_ctx = NULL; + Py_ssize_t data_length = 0; + Py_ssize_t pdu_length = 0; + DATA_BLOB data, pdu, sig; + PyObject *py_sig; + struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); + + if (!PyArg_ParseTuple(args, "z#z#", &data.data, &data_length, &pdu.data, &pdu_length)) { + return NULL; + } + data.length = data_length; + pdu.length = pdu_length; + + mem_ctx = talloc_new(NULL); + + status = gensec_sign_packet(security, mem_ctx, + data.data, data.length, + pdu.data, pdu.length, &sig); + if (!NT_STATUS_IS_OK(status)) { + PyErr_SetNTSTATUS(status); + talloc_free(mem_ctx); + return NULL; + } + + py_sig = PyBytes_FromStringAndSize((const char *)sig.data, sig.length); + talloc_free(mem_ctx); + return py_sig; +} + +static PyObject *py_gensec_check_packet(PyObject *self, PyObject *args) +{ + NTSTATUS status; + Py_ssize_t data_length = 0; + Py_ssize_t pdu_length = 0; + Py_ssize_t sig_length = 0; + DATA_BLOB data, pdu, sig; + struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); + + if (!PyArg_ParseTuple(args, "z#z#z#", + &data.data, &data_length, + &pdu.data, &pdu_length, + &sig.data, &sig_length)) { + return NULL; + } + data.length = data_length; + pdu.length = pdu_length; + sig.length = sig_length; + + status = gensec_check_packet(security, + data.data, data.length, + pdu.data, pdu.length, &sig); + if (!NT_STATUS_IS_OK(status)) { + PyErr_SetNTSTATUS(status); + return NULL; + } + + Py_RETURN_NONE; +} + static PyMethodDef py_gensec_security_methods[] = { { "start_client", (PyCFunction)py_gensec_start_client, METH_VARARGS|METH_KEYWORDS|METH_CLASS, "S.start_client(settings) -> gensec" }, @@ -567,6 +644,12 @@ static PyMethodDef py_gensec_security_methods[] = { "S.wrap(blob_in) -> blob_out\nPackage one clear packet into a wrapped GENSEC packet." }, { "unwrap", (PyCFunction)py_gensec_unwrap, METH_VARARGS, "S.unwrap(blob_in) -> blob_out\nPerform one wrapped GENSEC packet into a clear packet." }, + { "sig_size", (PyCFunction)py_gensec_sig_size, METH_VARARGS, + "S.sig_size(data_size) -> sig_size\nSize of the DCERPC packet signature" }, + { "sign_packet", (PyCFunction)py_gensec_sign_packet, METH_VARARGS, + "S.sign_packet(data, whole_pdu) -> sig\nSign a DCERPC packet." }, + { "check_packet", (PyCFunction)py_gensec_check_packet, METH_VARARGS, + "S.check_packet(data, whole_pdu, sig)\nCheck a DCERPC packet." }, { NULL } }; -- 1.9.1 From 191e9b5522d2fcf319d297ef90f6bc46489e8b73 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 12:06:50 +0100 Subject: [PATCH 029/323] auth/gensec: keep a pointer to a possible child/sub gensec_security context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a hack in order to temporary implement something like: gensec_ntlmssp_server_domain(), which may be used within spnego. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 5e913af833721733c4f79f2636fc3ae19d5f42f0) --- auth/gensec/gensec_internal.h | 2 ++ auth/gensec/spnego.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/auth/gensec/gensec_internal.h b/auth/gensec/gensec_internal.h index 45a66f8..2751196 100644 --- a/auth/gensec/gensec_internal.h +++ b/auth/gensec/gensec_internal.h @@ -110,6 +110,8 @@ struct gensec_security { * NTLM authentication backend, and user lookup (such as if no * PAC is found) */ struct auth4_context *auth_context; + + struct gensec_security *child_security; }; /* this structure is used by backends to determine the size of some critical types */ diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index 079a2bc..0079bb8 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -1265,6 +1265,9 @@ static NTSTATUS gensec_spnego_update_wrapper(struct gensec_security *gensec_secu &spnego_state->out_frag); data_blob_free(&spnego_state->in_frag); spnego_state->in_needed = 0; + if (NT_STATUS_IS_OK(status)) { + gensec_security->child_security = spnego_state->sub_sec_security; + } if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { return status; -- 1.9.1 From 1f2df9ca889f01fd2b1259f80ed7543bf7340f88 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 19:29:40 +0100 Subject: [PATCH 030/323] auth/gensec: handle gensec_security_by_sasl_name(NULL, ...) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We do that for all other gensec_security_by_*() functions already. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 64364e365c56c93e86305a536c5c68450d154d2a) --- auth/gensec/gensec_start.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c index be31697..8d4bfa7 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -211,8 +211,10 @@ _PUBLIC_ const struct gensec_security_ops *gensec_security_by_sasl_name( } backends = gensec_security_mechs(gensec_security, mem_ctx); for (i=0; backends && backends[i]; i++) { - if (!gensec_security_ops_enabled(backends[i], gensec_security)) - continue; + if (gensec_security != NULL && + !gensec_security_ops_enabled(backends[i], gensec_security)) { + continue; + } if (backends[i]->sasl_name && (strcmp(backends[i]->sasl_name, sasl_name) == 0)) { backend = backends[i]; -- 1.9.1 From e5bfed01416eaa631037fe9195be8f35b3d5e2a2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 11:43:02 +0100 Subject: [PATCH 031/323] auth/gensec: make gensec_security_by_name() public MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 8efcb4943585f015c9956118d8f42be89d5c7677) --- auth/gensec/gensec.h | 2 ++ auth/gensec/gensec_start.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h index d09813e..fae44df 100644 --- a/auth/gensec/gensec.h +++ b/auth/gensec/gensec.h @@ -163,6 +163,8 @@ const struct gensec_security_ops *gensec_security_by_sasl_name(struct gensec_sec const struct gensec_security_ops *gensec_security_by_auth_type( struct gensec_security *gensec_security, uint32_t auth_type); +const struct gensec_security_ops *gensec_security_by_name(struct gensec_security *gensec_security, + const char *name); const struct gensec_security_ops **gensec_security_mechs(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx); const struct gensec_security_ops_wrapper *gensec_security_by_oid_list( diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c index 8d4bfa7..bb9cd18 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -255,8 +255,8 @@ _PUBLIC_ const struct gensec_security_ops *gensec_security_by_auth_type( return NULL; } -static const struct gensec_security_ops *gensec_security_by_name(struct gensec_security *gensec_security, - const char *name) +const struct gensec_security_ops *gensec_security_by_name(struct gensec_security *gensec_security, + const char *name) { int i; const struct gensec_security_ops **backends; -- 1.9.1 From 57f122c8b2cd2d3eda883d021060c8d45d94fbb7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 11:44:02 +0100 Subject: [PATCH 032/323] s3:auth_generic: add auth_generic_client_start_by_name() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit ccfd2647c7e65c3e2ad92dbc27c21570da0706d4) --- source3/include/auth_generic.h | 3 ++- source3/libsmb/auth_generic.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/source3/include/auth_generic.h b/source3/include/auth_generic.h index 07df62a..2672dc2 100644 --- a/source3/include/auth_generic.h +++ b/source3/include/auth_generic.h @@ -42,7 +42,8 @@ NTSTATUS auth_generic_set_creds(struct auth_generic_state *ans, NTSTATUS auth_generic_client_prepare(TALLOC_CTX *mem_ctx, struct auth_generic_state **_ans); NTSTATUS auth_generic_client_start(struct auth_generic_state *ans, const char *oid); - +NTSTATUS auth_generic_client_start_by_name(struct auth_generic_state *ans, + const char *name); NTSTATUS auth_generic_client_start_by_authtype(struct auth_generic_state *ans, uint8_t auth_type, uint8_t auth_level); diff --git a/source3/libsmb/auth_generic.c b/source3/libsmb/auth_generic.c index 68d1451..c07445e 100644 --- a/source3/libsmb/auth_generic.c +++ b/source3/libsmb/auth_generic.c @@ -151,6 +151,29 @@ NTSTATUS auth_generic_client_start(struct auth_generic_state *ans, const char *o return NT_STATUS_OK; } +NTSTATUS auth_generic_client_start_by_name(struct auth_generic_state *ans, + const char *name) +{ + NTSTATUS status; + + /* Transfer the credentials to gensec */ + status = gensec_set_credentials(ans->gensec_security, ans->credentials); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to set GENSEC credentials: %s\n", + nt_errstr(status))); + return status; + } + talloc_unlink(ans, ans->credentials); + ans->credentials = NULL; + + status = gensec_start_mech_by_name(ans->gensec_security, name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return NT_STATUS_OK; +} + NTSTATUS auth_generic_client_start_by_authtype(struct auth_generic_state *ans, uint8_t auth_type, uint8_t auth_level) -- 1.9.1 From c2132ac784b75bcd573cd9ee235929a9b2bb786b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 19:39:04 +0100 Subject: [PATCH 033/323] s3:auth_generic: add auth_generic_client_start_by_sasl() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 79a6fc0532936558421eb4321f795655b5280763) --- source3/include/auth_generic.h | 2 ++ source3/libsmb/auth_generic.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/source3/include/auth_generic.h b/source3/include/auth_generic.h index 2672dc2..02d2b4b 100644 --- a/source3/include/auth_generic.h +++ b/source3/include/auth_generic.h @@ -47,6 +47,8 @@ NTSTATUS auth_generic_client_start_by_name(struct auth_generic_state *ans, NTSTATUS auth_generic_client_start_by_authtype(struct auth_generic_state *ans, uint8_t auth_type, uint8_t auth_level); +NTSTATUS auth_generic_client_start_by_sasl(struct auth_generic_state *ans, + const char **sasl_list); extern const struct gensec_security_ops gensec_ntlmssp3_client_ops; diff --git a/source3/libsmb/auth_generic.c b/source3/libsmb/auth_generic.c index c07445e..27f4801 100644 --- a/source3/libsmb/auth_generic.c +++ b/source3/libsmb/auth_generic.c @@ -198,3 +198,26 @@ NTSTATUS auth_generic_client_start_by_authtype(struct auth_generic_state *ans, return NT_STATUS_OK; } + +NTSTATUS auth_generic_client_start_by_sasl(struct auth_generic_state *ans, + const char **sasl_list) +{ + NTSTATUS status; + + /* Transfer the credentials to gensec */ + status = gensec_set_credentials(ans->gensec_security, ans->credentials); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to set GENSEC credentials: %s\n", + nt_errstr(status))); + return status; + } + talloc_unlink(ans, ans->credentials); + ans->credentials = NULL; + + status = gensec_start_mech_by_sasl_list(ans->gensec_security, sasl_list); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return NT_STATUS_OK; +} -- 1.9.1 From 6fc9d620940cd3d17fdea98492421efda2f76510 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 22:15:50 +0100 Subject: [PATCH 034/323] auth/ntlmssp: keep ntlmssp_state->server.netbios_domain on the correct talloc context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 0a9e37a0db86815d2baf7ab791721b6a7e04a717) --- auth/ntlmssp/ntlmssp_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index b22619b..1ac0996 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -244,7 +244,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, } /* TODO: parse struct_blob and fill in the rest */ ntlmssp_state->server.netbios_name = ""; - ntlmssp_state->server.netbios_domain = server_domain; + ntlmssp_state->server.netbios_domain = talloc_move(ntlmssp_state, &server_domain); ntlmssp_state->server.dns_name = ""; ntlmssp_state->server.dns_domain = ""; -- 1.9.1 From ccc8ff20f7b9d3d9d8bdec84bb5f8381088b86e2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 12:06:50 +0100 Subject: [PATCH 035/323] auth/ntlmssp: add gensec_ntlmssp_server_domain() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a hack in order to temporary export the server domain from NTLMSSP through the gensec stack. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit a85a02b631609cd9c16e1048c62dbe9661128279) --- auth/ntlmssp/ntlmssp.c | 37 ++++++++++++++++++++++++++++++++++++- auth/ntlmssp/ntlmssp.h | 1 + 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/auth/ntlmssp/ntlmssp.c b/auth/ntlmssp/ntlmssp.c index 916b376..0b7667c 100644 --- a/auth/ntlmssp/ntlmssp.c +++ b/auth/ntlmssp/ntlmssp.c @@ -209,13 +209,48 @@ _PUBLIC_ NTSTATUS gensec_ntlmssp_init(void) return ret; } +static struct gensec_security *gensec_find_child_by_ops(struct gensec_security *gensec_security, + const struct gensec_security_ops *ops) +{ + struct gensec_security *current = gensec_security; + + while (current != NULL) { + if (current->ops == ops) { + return current; + } + + current = current->child_security; + } + + return NULL; +} + uint32_t gensec_ntlmssp_neg_flags(struct gensec_security *gensec_security) { struct gensec_ntlmssp_context *gensec_ntlmssp; - if (gensec_security->ops != &gensec_ntlmssp_security_ops) { + + gensec_security = gensec_find_child_by_ops(gensec_security, + &gensec_ntlmssp_security_ops); + if (gensec_security == NULL) { return 0; } + gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data, struct gensec_ntlmssp_context); return gensec_ntlmssp->ntlmssp_state->neg_flags; } + +const char *gensec_ntlmssp_server_domain(struct gensec_security *gensec_security) +{ + struct gensec_ntlmssp_context *gensec_ntlmssp; + + gensec_security = gensec_find_child_by_ops(gensec_security, + &gensec_ntlmssp_security_ops); + if (gensec_security == NULL) { + return NULL; + } + + gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data, + struct gensec_ntlmssp_context); + return gensec_ntlmssp->ntlmssp_state->server.netbios_domain; +} diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index 6061cd0..b357e42 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -132,3 +132,4 @@ bool ntlmssp_blob_matches_magic(const DATA_BLOB *blob); NTSTATUS gensec_ntlmssp_init(void); uint32_t gensec_ntlmssp_neg_flags(struct gensec_security *gensec_security); +const char *gensec_ntlmssp_server_domain(struct gensec_security *gensec_security); -- 1.9.1 From 90c068bac5a928253fbf1a7e83c23d85b413f515 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 21:23:33 +0100 Subject: [PATCH 036/323] s3:ntlm_auth: fix --use-cached-creds with ntlmssp-client-1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11776 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 69a7ec794213e8adec5dcbd9ca45172df13292c1) --- source3/utils/ntlm_auth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index b90f927..3cd48b7 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -1212,7 +1212,7 @@ static NTSTATUS do_ccache_ntlm_auth(DATA_BLOB initial_msg, DATA_BLOB challenge_m } winbindd_free_response(&wb_response); - return NT_STATUS_MORE_PROCESSING_REQUIRED; + return NT_STATUS_OK; } static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, @@ -1271,7 +1271,7 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo DATA_BLOB empty_blob = data_blob_null; nt_status = do_ccache_ntlm_auth(empty_blob, empty_blob, NULL); - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (!NT_STATUS_IS_OK(nt_status)) { /* failed to use cached creds */ use_cached_creds = False; } -- 1.9.1 From a2c5af717bc3f478d1be835c5016e797f6e54e15 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Dec 2015 12:11:05 +0100 Subject: [PATCH 037/323] s3:torture/test_ntlm_auth.py: replace tabs with whitespaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit cf2ea04135774853d1cebca82c60bed890135163) --- source3/torture/test_ntlm_auth.py | 548 +++++++++++++++++++------------------- 1 file changed, 274 insertions(+), 274 deletions(-) diff --git a/source3/torture/test_ntlm_auth.py b/source3/torture/test_ntlm_auth.py index d17af9b..ae868f1 100755 --- a/source3/torture/test_ntlm_auth.py +++ b/source3/torture/test_ntlm_auth.py @@ -27,300 +27,300 @@ import sys from optparse import OptionParser class ReadChildError(Exception): - pass + pass class WriteChildError(Exception): - pass + pass def readLine(pipe): - """readLine(pipe) -> str - Read a line from the child's pipe, returns the string read. - Throws ReadChildError if the read fails. - """ - buf = os.read(pipe, 2047) - newline = buf.find('\n') - if newline == -1: - raise ReadChildError() - return buf[:newline] + """readLine(pipe) -> str + Read a line from the child's pipe, returns the string read. + Throws ReadChildError if the read fails. + """ + buf = os.read(pipe, 2047) + newline = buf.find('\n') + if newline == -1: + raise ReadChildError() + return buf[:newline] def writeLine(pipe, buf): - """writeLine(pipe, buf) -> nul - Write a line to the child's pipe. - Raises WriteChildError if the write fails. - """ - written = os.write(pipe, buf) - if written != len(buf): - raise WriteChildError() - os.write(pipe, "\n") + """writeLine(pipe, buf) -> nul + Write a line to the child's pipe. + Raises WriteChildError if the write fails. + """ + written = os.write(pipe, buf) + if written != len(buf): + raise WriteChildError() + os.write(pipe, "\n") def parseCommandLine(): - """parseCommandLine() -> (opts, ntlm_auth_path) - Parse the command line. - Return a tuple consisting of the options and the path to ntlm_auth. - """ - usage = "usage: %prog [options] path/to/ntlm_auth" - parser = OptionParser(usage) - - parser.set_defaults(client_username="foo") - parser.set_defaults(client_password="secret") - parser.set_defaults(client_domain="FOO") - parser.set_defaults(client_helper="ntlmssp-client-1") - - parser.set_defaults(server_username="foo") - parser.set_defaults(server_password="secret") - parser.set_defaults(server_domain="FOO") - parser.set_defaults(server_helper="squid-2.5-ntlmssp") - parser.set_defaults(config_file="/etc/samba/smb.conf") - - parser.add_option("--client-username", dest="client_username",\ - help="User name for the client. [default: foo]") - parser.add_option("--client-password", dest="client_password",\ - help="Password the client will send. [default: secret]") - parser.add_option("--client-domain", dest="client_domain",\ - help="Domain the client authenticates for. [default: FOO]") - parser.add_option("--client-helper", dest="client_helper",\ - help="Helper mode for the ntlm_auth client. [default: ntlmssp-client-1]") - - parser.add_option("--target-hostname", dest="target_hostname",\ - help="Target hostname for kerberos") - parser.add_option("--target-service", dest="target_service",\ - help="Target service for kerberos") - - - parser.add_option("--server-username", dest="server_username",\ - help="User name server uses for local auth. [default: foo]") - parser.add_option("--server-password", dest="server_password",\ - help="Password server uses for local auth. [default: secret]") - parser.add_option("--server-domain", dest="server_domain",\ - help="Domain server uses for local auth. [default: FOO]") - parser.add_option("--server-helper", dest="server_helper",\ - help="Helper mode for the ntlm_auth server. [default: squid-2.5-server]") - parser.add_option("--server-use-winbindd", dest="server_use_winbindd",\ - help="Use winbindd to check the password (rather than default username/pw)", action="store_true") - parser.add_option("--require-membership-of", dest="sid",\ - help="Require that the user is a member of this group to authenticate.") - - - parser.add_option("-s", "--configfile", dest="config_file",\ - help="Path to smb.conf file. [default:/etc/samba/smb.conf") - - (opts, args) = parser.parse_args() - if len(args) != 1: - parser.error("Invalid number of arguments.") - - if not os.access(args[0], os.X_OK): - parser.error("%s is not executable." % args[0]) - - return (opts, args[0]) + """parseCommandLine() -> (opts, ntlm_auth_path) + Parse the command line. + Return a tuple consisting of the options and the path to ntlm_auth. + """ + usage = "usage: %prog [options] path/to/ntlm_auth" + parser = OptionParser(usage) + + parser.set_defaults(client_username="foo") + parser.set_defaults(client_password="secret") + parser.set_defaults(client_domain="FOO") + parser.set_defaults(client_helper="ntlmssp-client-1") + + parser.set_defaults(server_username="foo") + parser.set_defaults(server_password="secret") + parser.set_defaults(server_domain="FOO") + parser.set_defaults(server_helper="squid-2.5-ntlmssp") + parser.set_defaults(config_file="/etc/samba/smb.conf") + + parser.add_option("--client-username", dest="client_username",\ + help="User name for the client. [default: foo]") + parser.add_option("--client-password", dest="client_password",\ + help="Password the client will send. [default: secret]") + parser.add_option("--client-domain", dest="client_domain",\ + help="Domain the client authenticates for. [default: FOO]") + parser.add_option("--client-helper", dest="client_helper",\ + help="Helper mode for the ntlm_auth client. [default: ntlmssp-client-1]") + + parser.add_option("--target-hostname", dest="target_hostname",\ + help="Target hostname for kerberos") + parser.add_option("--target-service", dest="target_service",\ + help="Target service for kerberos") + + + parser.add_option("--server-username", dest="server_username",\ + help="User name server uses for local auth. [default: foo]") + parser.add_option("--server-password", dest="server_password",\ + help="Password server uses for local auth. [default: secret]") + parser.add_option("--server-domain", dest="server_domain",\ + help="Domain server uses for local auth. [default: FOO]") + parser.add_option("--server-helper", dest="server_helper",\ + help="Helper mode for the ntlm_auth server. [default: squid-2.5-server]") + parser.add_option("--server-use-winbindd", dest="server_use_winbindd",\ + help="Use winbindd to check the password (rather than default username/pw)", action="store_true") + parser.add_option("--require-membership-of", dest="sid",\ + help="Require that the user is a member of this group to authenticate.") + + + parser.add_option("-s", "--configfile", dest="config_file",\ + help="Path to smb.conf file. [default:/etc/samba/smb.conf") + + (opts, args) = parser.parse_args() + if len(args) != 1: + parser.error("Invalid number of arguments.") + + if not os.access(args[0], os.X_OK): + parser.error("%s is not executable." % args[0]) + + return (opts, args[0]) def main(): - """main() -> int - Run the test. - Returns 0 if test succeeded, <>0 otherwise. - """ - (opts, ntlm_auth_path) = parseCommandLine() + """main() -> int + Run the test. + Returns 0 if test succeeded, <>0 otherwise. + """ + (opts, ntlm_auth_path) = parseCommandLine() - (client_in_r, client_in_w) = os.pipe() - (client_out_r, client_out_w) = os.pipe() - - client_pid = os.fork() - - if not client_pid: - # We're in the client child - os.close(0) - os.close(1) - - os.dup2(client_out_r, 0) - os.close(client_out_r) - os.close(client_out_w) - - os.dup2(client_in_w, 1) - os.close(client_in_r) - os.close(client_in_w) - - client_args = [] - client_args.append("--helper-protocol=%s" % opts.client_helper) - client_args.append("--username=%s" % opts.client_username) - client_args.append("--password=%s" % opts.client_password) - client_args.append("--domain=%s" % opts.client_domain) - client_args.append("--configfile=%s" % opts.config_file) - if opts.target_service: - client_args.append("--target-service=%s" % opts.target_service) - if opts.target_hostname: - client_args.append("--target-hostname=%s" % opts.target_hostname) - - os.execv(ntlm_auth_path, client_args) - - client_in = client_in_r - os.close(client_in_w) - - client_out = client_out_w - os.close(client_out_r) - - (server_in_r, server_in_w) = os.pipe() - (server_out_r, server_out_w) = os.pipe() - - server_pid = os.fork() - - if not server_pid: - # We're in the server child - os.close(0) - os.close(1) - - os.dup2(server_out_r, 0) - os.close(server_out_r) - os.close(server_out_w) - - os.dup2(server_in_w, 1) - os.close(server_in_r) - os.close(server_in_w) - - server_args = [] - server_args.append("--helper-protocol=%s" % opts.server_helper) - if not opts.server_use_winbindd: - server_args.append("--username=%s" % opts.server_username) - server_args.append("--password=%s" % opts.server_password) - server_args.append("--domain=%s" % opts.server_domain) - if opts.sid: - raise Exception("Server must be using winbindd for require-membership-of.") - else: - if opts.sid: - server_args.append("--require-membership-of=%s" % opts.sid) - - server_args.append("--configfile=%s" % opts.config_file) - - os.execv(ntlm_auth_path, server_args) - - server_in = server_in_r - os.close(server_in_w) - - server_out = server_out_w - os.close(server_out_r) - - if opts.client_helper == "ntlmssp-client-1" and opts.server_helper == "squid-2.5-ntlmssp": - - # We're in the parent - writeLine(client_out, "YR") - buf = readLine(client_in) - - if buf.count("YR ", 0, 3) != 1: - sys.exit(1) - - writeLine(server_out, buf) - buf = readLine(server_in) - - if buf.count("TT ", 0, 3) != 1: - sys.exit(2) - - writeLine(client_out, buf) - buf = readLine(client_in) - - if buf.count("AF ", 0, 3) != 1: - sys.exit(3) - - # Client sends 'AF ' but server expects 'KK ' - buf = buf.replace("AF", "KK", 1) - - writeLine(server_out, buf) - buf = readLine(server_in) - - if buf.count("AF ", 0, 3) != 1: - sys.exit(4) - - - elif opts.client_helper == "ntlmssp-client-1" and opts.server_helper == "gss-spnego": - # We're in the parent - writeLine(client_out, "YR") - buf = readLine(client_in) - - if buf.count("YR ", 0, 3) != 1: - sys.exit(1) - - writeLine(server_out, buf) - buf = readLine(server_in) - - if buf.count("TT ", 0, 3) != 1: - sys.exit(2) - - writeLine(client_out, buf) - buf = readLine(client_in) + (client_in_r, client_in_w) = os.pipe() + (client_out_r, client_out_w) = os.pipe() - if buf.count("AF ", 0, 3) != 1: - sys.exit(3) + client_pid = os.fork() - # Client sends 'AF ' but server expects 'KK ' - buf = buf.replace("AF", "KK", 1) - - writeLine(server_out, buf) - buf = readLine(server_in) - - if buf.count("AF * ", 0, 5) != 1: - sys.exit(4) + if not client_pid: + # We're in the client child + os.close(0) + os.close(1) + os.dup2(client_out_r, 0) + os.close(client_out_r) + os.close(client_out_w) - elif opts.client_helper == "gss-spnego-client" and opts.server_helper == "gss-spnego": - # We're in the parent - writeLine(server_out, "YR") - buf = readLine(server_in) - - while True: - if buf.count("AF ", 0, 3) != 1 and buf.count("TT ", 0, 3) != 1: - sys.exit(1) - - writeLine(client_out, buf) - buf = readLine(client_in) - - if buf.count("AF", 0, 2) == 1: - break - - if buf.count("AF ", 0, 5) != 1 and buf.count("KK ", 0, 3) != 1 and buf.count("TT ", 0, 3) != 1: - sys.exit(2) - - writeLine(server_out, buf) - buf = readLine(server_in) - - if buf.count("AF * ", 0, 5) == 1: - break - - else: - sys.exit(5) + os.dup2(client_in_w, 1) + os.close(client_in_r) + os.close(client_in_w) - if opts.client_helper == "ntlmssp-client-1": - writeLine(client_out, "GK") - buf = readLine(client_in) + client_args = [] + client_args.append("--helper-protocol=%s" % opts.client_helper) + client_args.append("--username=%s" % opts.client_username) + client_args.append("--password=%s" % opts.client_password) + client_args.append("--domain=%s" % opts.client_domain) + client_args.append("--configfile=%s" % opts.config_file) + if opts.target_service: + client_args.append("--target-service=%s" % opts.target_service) + if opts.target_hostname: + client_args.append("--target-hostname=%s" % opts.target_hostname) - if buf.count("GK ", 0, 3) != 1: - sys.exit(4) - - writeLine(client_out, "GF") - buf = readLine(client_in) - - if buf.count("GF ", 0, 3) != 1: - sys.exit(4) - - if opts.server_helper == "squid-2.5-ntlmssp": - writeLine(server_out, "GK") - buf = readLine(server_in) - - if buf.count("GK ", 0, 3) != 1: - sys.exit(4) + os.execv(ntlm_auth_path, client_args) - writeLine(server_out, "GF") - buf = readLine(server_in) - - if buf.count("GF ", 0, 3) != 1: - sys.exit(4) - - os.close(server_in) - os.close(server_out) - os.close(client_in) - os.close(client_out) - os.waitpid(server_pid, 0) - os.waitpid(client_pid, 0) - sys.exit(0) + client_in = client_in_r + os.close(client_in_w) + + client_out = client_out_w + os.close(client_out_r) + + (server_in_r, server_in_w) = os.pipe() + (server_out_r, server_out_w) = os.pipe() + + server_pid = os.fork() + + if not server_pid: + # We're in the server child + os.close(0) + os.close(1) + + os.dup2(server_out_r, 0) + os.close(server_out_r) + os.close(server_out_w) + + os.dup2(server_in_w, 1) + os.close(server_in_r) + os.close(server_in_w) + + server_args = [] + server_args.append("--helper-protocol=%s" % opts.server_helper) + if not opts.server_use_winbindd: + server_args.append("--username=%s" % opts.server_username) + server_args.append("--password=%s" % opts.server_password) + server_args.append("--domain=%s" % opts.server_domain) + if opts.sid: + raise Exception("Server must be using winbindd for require-membership-of.") + else: + if opts.sid: + server_args.append("--require-membership-of=%s" % opts.sid) + + server_args.append("--configfile=%s" % opts.config_file) + + os.execv(ntlm_auth_path, server_args) + + server_in = server_in_r + os.close(server_in_w) + + server_out = server_out_w + os.close(server_out_r) + + if opts.client_helper == "ntlmssp-client-1" and opts.server_helper == "squid-2.5-ntlmssp": + + # We're in the parent + writeLine(client_out, "YR") + buf = readLine(client_in) + + if buf.count("YR ", 0, 3) != 1: + sys.exit(1) + + writeLine(server_out, buf) + buf = readLine(server_in) + + if buf.count("TT ", 0, 3) != 1: + sys.exit(2) + + writeLine(client_out, buf) + buf = readLine(client_in) + + if buf.count("AF ", 0, 3) != 1: + sys.exit(3) + + # Client sends 'AF ' but server expects 'KK ' + buf = buf.replace("AF", "KK", 1) + + writeLine(server_out, buf) + buf = readLine(server_in) + + if buf.count("AF ", 0, 3) != 1: + sys.exit(4) + + + elif opts.client_helper == "ntlmssp-client-1" and opts.server_helper == "gss-spnego": + # We're in the parent + writeLine(client_out, "YR") + buf = readLine(client_in) + + if buf.count("YR ", 0, 3) != 1: + sys.exit(1) + + writeLine(server_out, buf) + buf = readLine(server_in) + + if buf.count("TT ", 0, 3) != 1: + sys.exit(2) + + writeLine(client_out, buf) + buf = readLine(client_in) + + if buf.count("AF ", 0, 3) != 1: + sys.exit(3) + + # Client sends 'AF ' but server expects 'KK ' + buf = buf.replace("AF", "KK", 1) + + writeLine(server_out, buf) + buf = readLine(server_in) + + if buf.count("AF * ", 0, 5) != 1: + sys.exit(4) + + + elif opts.client_helper == "gss-spnego-client" and opts.server_helper == "gss-spnego": + # We're in the parent + writeLine(server_out, "YR") + buf = readLine(server_in) + + while True: + if buf.count("AF ", 0, 3) != 1 and buf.count("TT ", 0, 3) != 1: + sys.exit(1) + + writeLine(client_out, buf) + buf = readLine(client_in) + + if buf.count("AF", 0, 2) == 1: + break + + if buf.count("AF ", 0, 5) != 1 and buf.count("KK ", 0, 3) != 1 and buf.count("TT ", 0, 3) != 1: + sys.exit(2) + + writeLine(server_out, buf) + buf = readLine(server_in) + + if buf.count("AF * ", 0, 5) == 1: + break + + else: + sys.exit(5) + + if opts.client_helper == "ntlmssp-client-1": + writeLine(client_out, "GK") + buf = readLine(client_in) + + if buf.count("GK ", 0, 3) != 1: + sys.exit(4) + + writeLine(client_out, "GF") + buf = readLine(client_in) + + if buf.count("GF ", 0, 3) != 1: + sys.exit(4) + + if opts.server_helper == "squid-2.5-ntlmssp": + writeLine(server_out, "GK") + buf = readLine(server_in) + + if buf.count("GK ", 0, 3) != 1: + sys.exit(4) + + writeLine(server_out, "GF") + buf = readLine(server_in) + + if buf.count("GF ", 0, 3) != 1: + sys.exit(4) + + os.close(server_in) + os.close(server_out) + os.close(client_in) + os.close(client_out) + os.waitpid(server_pid, 0) + os.waitpid(client_pid, 0) + sys.exit(0) if __name__ == "__main__": - main() + main() -- 1.9.1 From 2808c0aff95435d6f7fea7769a8b6555e799d4bd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 16:15:13 +0100 Subject: [PATCH 038/323] s3:torture/test_ntlm_auth.py: add --client-use-cached-creds option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11776 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 1289130ad2aeded63990bf1bde6f169505c62280) --- source3/torture/test_ntlm_auth.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source3/torture/test_ntlm_auth.py b/source3/torture/test_ntlm_auth.py index ae868f1..fffeb26 100755 --- a/source3/torture/test_ntlm_auth.py +++ b/source3/torture/test_ntlm_auth.py @@ -80,6 +80,8 @@ def parseCommandLine(): help="Domain the client authenticates for. [default: FOO]") parser.add_option("--client-helper", dest="client_helper",\ help="Helper mode for the ntlm_auth client. [default: ntlmssp-client-1]") + parser.add_option("--client-use-cached-creds", dest="client_use_cached_creds",\ + help="Use winbindd credentials cache (rather than default username/pw)", action="store_true") parser.add_option("--target-hostname", dest="target_hostname",\ help="Target hostname for kerberos") @@ -142,7 +144,10 @@ def main(): client_args = [] client_args.append("--helper-protocol=%s" % opts.client_helper) client_args.append("--username=%s" % opts.client_username) - client_args.append("--password=%s" % opts.client_password) + if opts.client_use_cached_creds: + client_args.append("--use-cached-creds") + else: + client_args.append("--password=%s" % opts.client_password) client_args.append("--domain=%s" % opts.client_domain) client_args.append("--configfile=%s" % opts.config_file) if opts.target_service: -- 1.9.1 From 819159005901b6afc05196867b2daa366d4e2eb0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 16:15:13 +0100 Subject: [PATCH 039/323] s3:tests/test_ntlm_auth_s3: test ntlmssp-client-1 with cached credentials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11776 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 9bd1ecffffd070333a22ef2449a179cee3effe5d) --- source3/script/tests/test_ntlm_auth_s3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/script/tests/test_ntlm_auth_s3.sh b/source3/script/tests/test_ntlm_auth_s3.sh index a6f20ed..2b5e435 100755 --- a/source3/script/tests/test_ntlm_auth_s3.sh +++ b/source3/script/tests/test_ntlm_auth_s3.sh @@ -276,6 +276,8 @@ testit "ntlm_auth with NTLMSSP client and gss-spnego server" $PYTHON $SRC3DIR/to testit "ntlm_auth with NTLMSSP gss-spnego-client and gss-spnego server" $PYTHON $SRC3DIR/torture/test_ntlm_auth.py $NTLM_AUTH $ADDARGS --client-domain=fOo --server-domain=fOo --client-helper=gss-spnego-client --server-helper=gss-spnego || failed=`expr $failed + 1` testit "ntlm_auth with NTLMSSP gss-spnego-client and gss-spnego server against winbind" $PYTHON $SRC3DIR/torture/test_ntlm_auth.py $NTLM_AUTH --client-username=$USERNAME --client-domain=$DOMAIN --client-password=$PASSWORD --server-use-winbindd --client-helper=gss-spnego-client --server-helper=gss-spnego $ADDARGS || failed=`expr $failed + 1` +testit "wbinfo store cached credentials" $BINDIR/wbinfo --ccache-save=$DOMAIN/$USERNAME%$PASSWORD || failed=`expr $failed + 1` +testit "ntlm_auth ccached credentials with NTLMSSP client and gss-spnego server" $PYTHON $SRC3DIR/torture/test_ntlm_auth.py $NTLM_AUTH $ADDARGS --client-username=$USERNAME --client-domain=$DOMAIN --client-use-cached-creds --client-helper=ntlmssp-client-1 --server-helper=gss-spnego --server-use-winbindd || failed=`expr $failed + 1` testit "ntlm_auth against winbindd with require-membership-of" $PYTHON $SRC3DIR/torture/test_ntlm_auth.py $NTLM_AUTH --client-username=$USERNAME --client-domain=$DOMAIN --client-password=$PASSWORD --server-use-winbindd $ADDARGS --require-membership-of=$SID || failed=`expr $failed + 1` testit "ntlm_auth with NTLMSSP gss-spnego-client and gss-spnego server against winbind with require-membership-of" $PYTHON $SRC3DIR/torture/test_ntlm_auth.py $NTLM_AUTH --client-username=$USERNAME --client-domain=$DOMAIN --client-password=$PASSWORD --server-use-winbindd --client-helper=gss-spnego-client --server-helper=gss-spnego $ADDARGS --require-membership-of=$SID || failed=`expr $failed + 1` -- 1.9.1 From efd608e52f081091c3bc53985ce3f2305da6282d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 09:07:33 +0100 Subject: [PATCH 040/323] winbindd: pass an memory context to do_ntlm_auth_with_stored_pw() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should avoid using NULL. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 871e8a9fd029bbcbccb79bd17f9c6a2617b8be55) --- source3/winbindd/winbindd_ccache_access.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source3/winbindd/winbindd_ccache_access.c b/source3/winbindd/winbindd_ccache_access.c index 939da9b..ed0543c 100644 --- a/source3/winbindd/winbindd_ccache_access.c +++ b/source3/winbindd/winbindd_ccache_access.c @@ -48,6 +48,7 @@ static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, const char *password, const DATA_BLOB initial_msg, const DATA_BLOB challenge_msg, + TALLOC_CTX *mem_ctx, DATA_BLOB *auth_msg, uint8_t session_key[16]) { @@ -55,7 +56,7 @@ static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, struct auth_generic_state *auth_generic_state = NULL; DATA_BLOB dummy_msg, reply, session_key_blob; - status = auth_generic_client_prepare(NULL, &auth_generic_state); + status = auth_generic_client_prepare(mem_ctx, &auth_generic_state); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not start NTLMSSP client: %s\n", @@ -120,7 +121,7 @@ static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, /* Now we are ready to handle the server's actual response. */ status = gensec_update(auth_generic_state->gensec_security, - NULL, challenge_msg, &reply); + mem_ctx, challenge_msg, &reply); if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) { DEBUG(1, ("We didn't get a response to the challenge! [%s]\n", nt_errstr(status))); @@ -273,7 +274,7 @@ void winbindd_ccache_ntlm_auth(struct winbindd_cli_state *state) result = do_ntlm_auth_with_stored_pw( name_user, name_domain, entry->pass, - initial, challenge, &auth, + initial, challenge, talloc_tos(), &auth, state->response->data.ccache_ntlm_auth.session_key); if (!NT_STATUS_IS_OK(result)) { -- 1.9.1 From e5d120fbaa135628b8bc0ecac74af4e341e43002 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 11:45:33 +0100 Subject: [PATCH 041/323] s3:auth_generic: make use of the top level NTLMSSP client code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no reason to use gensec_ntlmssp3_client_ops, the WINBINDD_CCACHE_NTLMAUTH isn't available via gensec anyway. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 0d66e2d34f656028eb3adb35acb653a45c041890) --- source3/libsmb/auth_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/libsmb/auth_generic.c b/source3/libsmb/auth_generic.c index 27f4801..67d27c6 100644 --- a/source3/libsmb/auth_generic.c +++ b/source3/libsmb/auth_generic.c @@ -100,7 +100,7 @@ NTSTATUS auth_generic_client_prepare(TALLOC_CTX *mem_ctx, struct auth_generic_st backends[idx++] = &gensec_gse_krb5_security_ops; #endif - backends[idx++] = &gensec_ntlmssp3_client_ops; + backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP); backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_SPNEGO); backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_SCHANNEL); -- 1.9.1 From 506c989025ed311415dd2e45b924c074b7852f88 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Dec 2015 12:47:40 +0100 Subject: [PATCH 042/323] s3:ntlmssp: remove unused libsmb/ntlmssp_wrap.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 52c03c07151a12e84fb4d34443864e59583c0db9) --- source3/include/auth_generic.h | 2 - source3/libsmb/ntlmssp_wrap.c | 135 ----------------------------------------- source3/wscript_build | 3 +- 3 files changed, 1 insertion(+), 139 deletions(-) delete mode 100644 source3/libsmb/ntlmssp_wrap.c diff --git a/source3/include/auth_generic.h b/source3/include/auth_generic.h index 02d2b4b..0911182 100644 --- a/source3/include/auth_generic.h +++ b/source3/include/auth_generic.h @@ -50,6 +50,4 @@ NTSTATUS auth_generic_client_start_by_authtype(struct auth_generic_state *ans, NTSTATUS auth_generic_client_start_by_sasl(struct auth_generic_state *ans, const char **sasl_list); -extern const struct gensec_security_ops gensec_ntlmssp3_client_ops; - #endif /* _AUTH_GENERIC_ */ diff --git a/source3/libsmb/ntlmssp_wrap.c b/source3/libsmb/ntlmssp_wrap.c deleted file mode 100644 index 46f68ae..0000000 --- a/source3/libsmb/ntlmssp_wrap.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - NLTMSSP wrappers - - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Andrew Bartlett 2001-2003,2011 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "auth/ntlmssp/ntlmssp.h" -#include "auth/ntlmssp/ntlmssp_private.h" -#include "auth_generic.h" -#include "auth/gensec/gensec.h" -#include "auth/gensec/gensec_internal.h" -#include "auth/credentials/credentials.h" -#include "librpc/rpc/dcerpc.h" -#include "lib/param/param.h" - -static NTSTATUS gensec_ntlmssp3_client_update(struct gensec_security *gensec_security, - TALLOC_CTX *out_mem_ctx, - struct tevent_context *ev, - const DATA_BLOB request, - DATA_BLOB *reply) -{ - NTSTATUS status; - struct gensec_ntlmssp_context *gensec_ntlmssp = - talloc_get_type_abort(gensec_security->private_data, - struct gensec_ntlmssp_context); - - status = ntlmssp_update(gensec_ntlmssp->ntlmssp_state, request, reply); - if (NT_STATUS_IS_OK(status) || - NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - talloc_steal(out_mem_ctx, reply->data); - } - - return status; -} - -static NTSTATUS gensec_ntlmssp3_client_start(struct gensec_security *gensec_security) -{ - NTSTATUS nt_status; - struct gensec_ntlmssp_context *gensec_ntlmssp; - const char *user, *domain; - const char *password; - - nt_status = gensec_ntlmssp_start(gensec_security); - NT_STATUS_NOT_OK_RETURN(nt_status); - - gensec_ntlmssp = - talloc_get_type_abort(gensec_security->private_data, - struct gensec_ntlmssp_context); - - nt_status = ntlmssp_client_start(gensec_ntlmssp, - lp_netbios_name(), lp_workgroup(), - lp_client_ntlmv2_auth(), &gensec_ntlmssp->ntlmssp_state); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - cli_credentials_get_ntlm_username_domain(gensec_security->credentials, gensec_ntlmssp, &user, &domain); - if (!user || !domain) { - return NT_STATUS_NO_MEMORY; - } - - nt_status = ntlmssp_set_username(gensec_ntlmssp->ntlmssp_state, user); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - nt_status = ntlmssp_set_domain(gensec_ntlmssp->ntlmssp_state, domain); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - password = cli_credentials_get_password(gensec_security->credentials); - if (!password) { - return NT_STATUS_NO_MEMORY; - } - - nt_status = ntlmssp_set_password(gensec_ntlmssp->ntlmssp_state, password); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { - gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { - gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { - gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; - } - - return NT_STATUS_OK; -} - -static const char *gensec_ntlmssp3_client_oids[] = { - GENSEC_OID_NTLMSSP, - NULL -}; - -const struct gensec_security_ops gensec_ntlmssp3_client_ops = { - .name = "ntlmssp3_client", - .sasl_name = GENSEC_SASL_NAME_NTLMSSP, /* "NTLM" */ - .auth_type = DCERPC_AUTH_TYPE_NTLMSSP, - .oid = gensec_ntlmssp3_client_oids, - .client_start = gensec_ntlmssp3_client_start, - .magic = gensec_ntlmssp_magic, - .update = gensec_ntlmssp3_client_update, - .sig_size = gensec_ntlmssp_sig_size, - .sign_packet = gensec_ntlmssp_sign_packet, - .check_packet = gensec_ntlmssp_check_packet, - .seal_packet = gensec_ntlmssp_seal_packet, - .unseal_packet = gensec_ntlmssp_unseal_packet, - .wrap = gensec_ntlmssp_wrap, - .unwrap = gensec_ntlmssp_unwrap, - .session_key = gensec_ntlmssp_session_key, - .have_feature = gensec_ntlmssp_have_feature, - .enabled = true, - .priority = GENSEC_NTLMSSP -}; diff --git a/source3/wscript_build b/source3/wscript_build index 7c9723a..5c3b667 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -370,8 +370,7 @@ bld.SAMBA3_LIBRARY('smbd_shim', private_library=True) bld.SAMBA3_SUBSYSTEM('LIBNTLMSSP', - source='''libsmb/ntlmssp.c - libsmb/ntlmssp_wrap.c''', + source='''libsmb/ntlmssp.c''', deps='NDR_NTLMSSP NTLMSSP_COMMON wbclient') bld.SAMBA3_SUBSYSTEM('auth_generic', -- 1.9.1 From e4b6fe26afa0c84eddc1e23b1185dc21b27f9fb3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Nov 2015 21:41:23 +0100 Subject: [PATCH 043/323] auth/ntlmssp: provide a "ntlmssp_resume_ccache" backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These can be used to implement the winbindd side of the WINBINDD_CCACHE_NTLMAUTH call. It can properly get the initial NEGOTIATE messages injected if available. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit b3d4523ff7810279dc4d3201a09a868545d4d253) --- auth/ntlmssp/ntlmssp.c | 29 +++++++++++ auth/ntlmssp/ntlmssp.h | 1 + auth/ntlmssp/ntlmssp_client.c | 111 +++++++++++++++++++++++++++++++++++++++++ auth/ntlmssp/ntlmssp_private.h | 5 ++ 4 files changed, 146 insertions(+) diff --git a/auth/ntlmssp/ntlmssp.c b/auth/ntlmssp/ntlmssp.c index 0b7667c..091fdab 100644 --- a/auth/ntlmssp/ntlmssp.c +++ b/auth/ntlmssp/ntlmssp.c @@ -48,6 +48,10 @@ static const struct ntlmssp_callbacks { .command = NTLMSSP_INITIAL, .sync_fn = ntlmssp_client_initial, },{ + .role = NTLMSSP_CLIENT, + .command = NTLMSSP_NEGOTIATE, + .sync_fn = gensec_ntlmssp_resume_ccache, + },{ .role = NTLMSSP_SERVER, .command = NTLMSSP_NEGOTIATE, .sync_fn = gensec_ntlmssp_server_negotiate, @@ -82,6 +86,15 @@ static NTSTATUS gensec_ntlmssp_update_find(struct gensec_security *gensec_securi if (!input.length) { switch (gensec_ntlmssp->ntlmssp_state->role) { case NTLMSSP_CLIENT: + if (gensec_ntlmssp->ntlmssp_state->resume_ccache) { + /* + * make sure gensec_ntlmssp_resume_ccache() + * will be called + */ + ntlmssp_command = NTLMSSP_NEGOTIATE; + break; + } + ntlmssp_command = NTLMSSP_INITIAL; break; case NTLMSSP_SERVER: @@ -194,6 +207,15 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = { .priority = GENSEC_NTLMSSP }; +static const struct gensec_security_ops gensec_ntlmssp_resume_ccache_ops = { + .name = "ntlmssp_resume_ccache", + .client_start = gensec_ntlmssp_resume_ccache_start, + .update = gensec_ntlmssp_update, + .session_key = gensec_ntlmssp_session_key, + .have_feature = gensec_ntlmssp_have_feature, + .enabled = true, + .priority = GENSEC_NTLMSSP +}; _PUBLIC_ NTSTATUS gensec_ntlmssp_init(void) { @@ -206,6 +228,13 @@ _PUBLIC_ NTSTATUS gensec_ntlmssp_init(void) return ret; } + ret = gensec_register(&gensec_ntlmssp_resume_ccache_ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' gensec backend!\n", + gensec_ntlmssp_resume_ccache_ops.name)); + return ret; + } + return ret; } diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index b357e42..4d2ddf9 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -62,6 +62,7 @@ struct ntlmssp_state bool unicode; bool use_ntlmv2; bool use_ccache; + bool resume_ccache; bool use_nt_response; /* Set to 'False' to debug what happens when the NT response is omited */ bool allow_lm_key; /* The LM_KEY code is not very secure... */ diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 1ac0996..df29aa2 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -114,6 +114,98 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security, return NT_STATUS_MORE_PROCESSING_REQUIRED; } +NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security, + TALLOC_CTX *out_mem_ctx, + DATA_BLOB in, DATA_BLOB *out) +{ + struct gensec_ntlmssp_context *gensec_ntlmssp = + talloc_get_type_abort(gensec_security->private_data, + struct gensec_ntlmssp_context); + struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; + uint32_t neg_flags = 0; + uint32_t ntlmssp_command; + NTSTATUS status; + bool ok; + + *out = data_blob_null; + + if (in.length == 0) { + /* + * This is compat code for older callers + * which were missing the "initial_blob" + */ + ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; + return NT_STATUS_MORE_PROCESSING_REQUIRED; + } + + /* parse the NTLMSSP packet */ + + if (in.length > UINT16_MAX) { + DEBUG(1, ("%s: reject large request of length %u\n", + __func__, (unsigned int)in.length)); + return NT_STATUS_INVALID_PARAMETER; + } + + ok = msrpc_parse(ntlmssp_state, &in, "Cdd", + "NTLMSSP", + &ntlmssp_command, + &neg_flags); + if (!ok) { + DEBUG(1, ("%s: failed to parse NTLMSSP Negotiate of length %u\n", + __func__, (unsigned int)in.length)); + dump_data(2, in.data, in.length); + return NT_STATUS_INVALID_PARAMETER; + } + + if (ntlmssp_command != NTLMSSP_NEGOTIATE) { + DEBUG(1, ("%s: no NTLMSSP Negotiate message (length %u)\n", + __func__, (unsigned int)in.length)); + dump_data(2, in.data, in.length); + return NT_STATUS_INVALID_PARAMETER; + } + + ntlmssp_state->neg_flags = neg_flags; + DEBUG(3, ("Imported Negotiate flags:\n")); + debug_ntlmssp_flags(neg_flags); + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { + ntlmssp_state->unicode = true; + } else { + ntlmssp_state->unicode = false; + } + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { + gensec_security->want_features |= GENSEC_FEATURE_SIGN; + + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { + gensec_security->want_features |= GENSEC_FEATURE_SEAL; + + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + } + + if (DEBUGLEVEL >= 10) { + struct NEGOTIATE_MESSAGE *negotiate = talloc( + ntlmssp_state, struct NEGOTIATE_MESSAGE); + if (negotiate != NULL) { + status = ntlmssp_pull_NEGOTIATE_MESSAGE( + &in, negotiate, negotiate); + if (NT_STATUS_IS_OK(status)) { + NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE, + negotiate); + } + TALLOC_FREE(negotiate); + } + } + + ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; + + return NT_STATUS_MORE_PROCESSING_REQUIRED; +} + /** * Next state function for the Challenge Packet. Generate an auth packet. * @@ -476,3 +568,22 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) return NT_STATUS_OK; } + +NTSTATUS gensec_ntlmssp_resume_ccache_start(struct gensec_security *gensec_security) +{ + struct gensec_ntlmssp_context *gensec_ntlmssp = NULL; + NTSTATUS status; + + status = gensec_ntlmssp_client_start(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data, + struct gensec_ntlmssp_context); + gensec_ntlmssp->ntlmssp_state->use_ccache = false; + gensec_ntlmssp->ntlmssp_state->resume_ccache = true; + gensec_ntlmssp->ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE; + + return NT_STATUS_OK; +} diff --git a/auth/ntlmssp/ntlmssp_private.h b/auth/ntlmssp/ntlmssp_private.h index 778d638..ea5703f 100644 --- a/auth/ntlmssp/ntlmssp_private.h +++ b/auth/ntlmssp/ntlmssp_private.h @@ -88,6 +88,10 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, DATA_BLOB in, DATA_BLOB *out) ; +NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security, + TALLOC_CTX *out_mem_ctx, + DATA_BLOB in, DATA_BLOB *out); + /** * Next state function for the Challenge Packet. Generate an auth packet. * @@ -101,6 +105,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) ; NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security); +NTSTATUS gensec_ntlmssp_resume_ccache_start(struct gensec_security *gensec_security); /* The following definitions come from auth/ntlmssp/gensec_ntlmssp_server.c */ -- 1.9.1 From 66bca18d62904162d0c36b226142a123629fcb3d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 27 Nov 2015 13:42:30 +0100 Subject: [PATCH 044/323] auth/gensec: add GENSEC_FEATURE_NTLM_CCACHE define MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 0a93cad337578a7ba61f12726c9a15ecf869db7b) --- auth/gensec/gensec.h | 1 + 1 file changed, 1 insertion(+) diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h index fae44df..f09e501 100644 --- a/auth/gensec/gensec.h +++ b/auth/gensec/gensec.h @@ -61,6 +61,7 @@ struct gensec_target { #define GENSEC_FEATURE_SIGN_PKT_HEADER 0x00000040 #define GENSEC_FEATURE_NEW_SPNEGO 0x00000080 #define GENSEC_FEATURE_UNIX_TOKEN 0x00000100 +#define GENSEC_FEATURE_NTLM_CCACHE 0x00000200 #define GENSEC_EXPIRE_TIME_INFINITY (NTTIME)0x8000000000000000LL -- 1.9.1 From fed30697ed57fbca4101797ab70e116e4464f8a6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 27 Nov 2015 15:35:40 +0100 Subject: [PATCH 045/323] auth/ntlmssp: implement GENSEC_FEATURE_NTLM_CCACHE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This can used in order to use the WINBINDD_CCACHE_NTLMAUTH code of winbindd to do NTLMSSP authentication with a cached password. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit b133f66e0da5ed05bbe81098e52c744bac4b48ac) --- auth/ntlmssp/ntlmssp_client.c | 94 +++++++++++++++++++++++++++++++++++++++++-- auth/ntlmssp/wscript_build | 2 +- 2 files changed, 92 insertions(+), 4 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index df29aa2..0823ebe 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -34,6 +34,7 @@ struct auth_session_info; #include "auth/ntlmssp/ntlmssp_private.h" #include "../librpc/gen_ndr/ndr_ntlmssp.h" #include "../auth/ntlmssp/ntlmssp_ndr.h" +#include "../nsswitch/libwbclient/wbclient.h" /********************************************************************* Client side NTLMSSP @@ -240,6 +241,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, NTSTATUS nt_status; int flags = 0; const char *user = NULL, *domain = NULL, *workstation = NULL; + bool is_anonymous = false; TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx); if (!mem_ctx) { @@ -345,6 +347,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } + is_anonymous = cli_credentials_is_anonymous(gensec_security->credentials); cli_credentials_get_ntlm_username_domain(gensec_security->credentials, mem_ctx, &user, &domain); @@ -365,6 +368,87 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, return NT_STATUS_INVALID_PARAMETER; } + if (is_anonymous) { + /* + * don't use the ccache for anonymous auth + */ + ntlmssp_state->use_ccache = false; + } + if (ntlmssp_state->use_ccache) { + struct samr_Password *nt_hash = NULL; + + /* + * If we have a password given we don't + * use the ccache + */ + nt_hash = cli_credentials_get_nt_hash(gensec_security->credentials, + mem_ctx); + if (nt_hash != NULL) { + ZERO_STRUCTP(nt_hash); + TALLOC_FREE(nt_hash); + ntlmssp_state->use_ccache = false; + } + } + + if (ntlmssp_state->use_ccache) { + struct wbcCredentialCacheParams params; + struct wbcCredentialCacheInfo *info = NULL; + struct wbcAuthErrorInfo *error = NULL; + struct wbcNamedBlob auth_blobs[1]; + const struct wbcBlob *wbc_auth_blob = NULL; + const struct wbcBlob *wbc_session_key = NULL; + wbcErr wbc_status; + int i; + + params.account_name = user; + params.domain_name = domain; + params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP; + + auth_blobs[0].name = "challenge_blob"; + auth_blobs[0].flags = 0; + auth_blobs[0].blob.data = in.data; + auth_blobs[0].blob.length = in.length; + params.num_blobs = ARRAY_SIZE(auth_blobs); + params.blobs = auth_blobs; + + wbc_status = wbcCredentialCache(¶ms, &info, &error); + wbcFreeMemory(error); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return NT_STATUS_WRONG_CREDENTIAL_HANDLE; + } + + for (i=0; inum_blobs; i++) { + if (strequal(info->blobs[i].name, "auth_blob")) { + wbc_auth_blob = &info->blobs[i].blob; + } + if (strequal(info->blobs[i].name, "session_key")) { + wbc_session_key = &info->blobs[i].blob; + } + } + if ((wbc_auth_blob == NULL) || (wbc_session_key == NULL)) { + wbcFreeMemory(info); + return NT_STATUS_WRONG_CREDENTIAL_HANDLE; + } + + session_key = data_blob_talloc(mem_ctx, + wbc_session_key->data, + wbc_session_key->length); + if (session_key.length != wbc_session_key->length) { + wbcFreeMemory(info); + return NT_STATUS_NO_MEMORY; + } + *out = data_blob_talloc(mem_ctx, + wbc_auth_blob->data, + wbc_auth_blob->length); + if (out->length != wbc_auth_blob->length) { + wbcFreeMemory(info); + return NT_STATUS_NO_MEMORY; + } + + wbcFreeMemory(info); + goto done; + } + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { flags |= CLI_CRED_NTLM2; } @@ -434,9 +518,6 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, session_key = data_blob_talloc(mem_ctx, client_session_key, sizeof(client_session_key)); } - DEBUG(3, ("NTLMSSP: Set final flags:\n")); - debug_ntlmssp_flags(ntlmssp_state->neg_flags); - /* this generates the actual auth packet */ nt_status = msrpc_gen(mem_ctx, out, auth_gen_string, @@ -454,9 +535,13 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, return nt_status; } +done: ntlmssp_state->session_key = session_key; talloc_steal(ntlmssp_state, session_key.data); + DEBUG(3, ("NTLMSSP: Set final flags:\n")); + debug_ntlmssp_flags(ntlmssp_state->neg_flags); + talloc_steal(out_mem_ctx, out->data); ntlmssp_state->expected_state = NTLMSSP_DONE; @@ -565,6 +650,9 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } + if (gensec_security->want_features & GENSEC_FEATURE_NTLM_CCACHE) { + ntlmssp_state->use_ccache = true; + } return NT_STATUS_OK; } diff --git a/auth/ntlmssp/wscript_build b/auth/ntlmssp/wscript_build index 8725a80..e28d4eb 100644 --- a/auth/ntlmssp/wscript_build +++ b/auth/ntlmssp/wscript_build @@ -7,7 +7,7 @@ bld.SAMBA_SUBSYSTEM('NTLMSSP_COMMON', ntlmssp_server.c ntlmssp_sign.c gensec_ntlmssp_server.c''', - deps='samba-util NDR_NTLMSSP MSRPC_PARSE NTLM_CHECK samba-credentials') + deps='samba-util NDR_NTLMSSP MSRPC_PARSE NTLM_CHECK samba-credentials wbclient') bld.SAMBA_MODULE('gensec_ntlmssp', source='''''', -- 1.9.1 From 71dc8239ed3934a464fc597b65e2a1fce32fdab2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Dec 2015 15:42:51 +0100 Subject: [PATCH 046/323] s3:auth_generic: add "ntlmssp_resume_ccache" backend in auth_generic_client_prepare() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will be used by winbindd in order to correctly implement WINBINDD_CCACHE_NTLMAUTH. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 8bcde9ec625547df42915e9138d696deeabdb62d) --- source3/libsmb/auth_generic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/libsmb/auth_generic.c b/source3/libsmb/auth_generic.c index 67d27c6..59560d6 100644 --- a/source3/libsmb/auth_generic.c +++ b/source3/libsmb/auth_generic.c @@ -86,7 +86,7 @@ NTSTATUS auth_generic_client_prepare(TALLOC_CTX *mem_ctx, struct auth_generic_st } backends = talloc_zero_array(gensec_settings, - const struct gensec_security_ops *, 6); + const struct gensec_security_ops *, 7); if (backends == NULL) { TALLOC_FREE(ans); return NT_STATUS_NO_MEMORY; @@ -101,6 +101,7 @@ NTSTATUS auth_generic_client_prepare(TALLOC_CTX *mem_ctx, struct auth_generic_st #endif backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP); + backends[idx++] = gensec_security_by_name(NULL, "ntlmssp_resume_ccache"); backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_SPNEGO); backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_SCHANNEL); -- 1.9.1 From aea542609027ba6b2008fee0527987eb89e9cf52 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 11:46:52 +0100 Subject: [PATCH 047/323] winbindd: make use of ntlmssp_resume_ccache backend for WINBINDD_CCACHE_NTLMAUTH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 716e78f3b294210130f3cf253f496391534819b0) --- source3/winbindd/winbindd_ccache_access.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/source3/winbindd/winbindd_ccache_access.c b/source3/winbindd/winbindd_ccache_access.c index ed0543c..ddedf6a 100644 --- a/source3/winbindd/winbindd_ccache_access.c +++ b/source3/winbindd/winbindd_ccache_access.c @@ -54,7 +54,7 @@ static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, { NTSTATUS status; struct auth_generic_state *auth_generic_state = NULL; - DATA_BLOB dummy_msg, reply, session_key_blob; + DATA_BLOB reply, session_key_blob; status = auth_generic_client_prepare(mem_ctx, &auth_generic_state); @@ -88,29 +88,26 @@ static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, goto done; } - gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SESSION_KEY); + if (initial_msg.length == 0) { + gensec_want_feature(auth_generic_state->gensec_security, + GENSEC_FEATURE_SESSION_KEY); + } - status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP); + status = auth_generic_client_start_by_name(auth_generic_state, + "ntlmssp_resume_ccache"); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not start NTLMSSP mech: %s\n", + DEBUG(1, ("Could not start NTLMSSP resume mech: %s\n", nt_errstr(status))); goto done; } - /* We need to get our protocol handler into the right state. So first - we ask it to generate the initial message. Actually the client has already - sent its own initial message, so we're going to drop this one on the floor. - The client might have sent a different message, for example with different - negotiation options, but as far as I can tell this won't hurt us. (Unless - the client sent a different username or domain, in which case that's their - problem for telling us the wrong username or domain.) - Since we have a copy of the initial message that the client sent, we could - resolve any discrepancies if we had to. - */ - dummy_msg = data_blob_null; + /* + * We inject the inital NEGOTIATE message our caller used + * in order to get the state machine into the correct possition. + */ reply = data_blob_null; status = gensec_update(auth_generic_state->gensec_security, - talloc_tos(), dummy_msg, &reply); + talloc_tos(), initial_msg, &reply); data_blob_free(&reply); if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { -- 1.9.1 From d7f2a2caea8ba6cdd336f90ee4cec05823d5c643 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 10:54:56 +0100 Subject: [PATCH 048/323] s3:ntlm_auth: also use gensec for "ntlmssp-client-1" and "gss-spnego-client" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This implicitly fixes bug #10708. BUG: https://bugzilla.samba.org/show_bug.cgi?id=10708 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 279d58c1e68c9466a76e4a67d2cfea22e8719d31) --- source3/utils/ntlm_auth.c | 789 +++++++--------------------------------------- 1 file changed, 110 insertions(+), 679 deletions(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 3cd48b7..f37cfa3 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -29,7 +29,6 @@ #include "popt_common.h" #include "utils/ntlm_auth.h" #include "../libcli/auth/libcli_auth.h" -#include "../libcli/auth/spnego.h" #include "auth/ntlmssp/ntlmssp.h" #include "auth/gensec/gensec.h" #include "auth/gensec/gensec_internal.h" @@ -38,7 +37,6 @@ #include "smb_krb5.h" #include "lib/util/tiniparser.h" #include "../lib/crypto/arcfour.h" -#include "libads/kerberos_proto.h" #include "nsswitch/winbind_client.h" #include "librpc/gen_ndr/krb5pac.h" #include "../lib/util/asn1.h" @@ -100,6 +98,10 @@ typedef void (*stdio_helper_function)(enum stdio_helper_mode stdio_helper_mode, struct ntlm_auth_state *state, char *buf, int length, void **private2); +static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, + struct loadparm_context *lp_ctx, + char *buf, int length, void **private1); + static void manage_squid_request(enum stdio_helper_mode stdio_helper_mode, struct loadparm_context *lp_ctx, struct ntlm_auth_state *state, @@ -255,6 +257,10 @@ static void gensec_want_feature_list(struct gensec_security *state, char* featur DEBUG(10, ("want GENSEC_FEATURE_SEAL\n")); gensec_want_feature(state, GENSEC_FEATURE_SEAL); } + if (in_list("NTLMSSP_FEATURE_CCACHE", feature_list, true)) { + DEBUG(10, ("want GENSEC_FEATURE_NTLM_CCACHE\n")); + gensec_want_feature(state, GENSEC_FEATURE_NTLM_CCACHE); + } } static char winbind_separator(void) @@ -958,57 +964,75 @@ static NTSTATUS local_pw_check(struct auth4_context *auth4_context, return nt_status; } -static NTSTATUS ntlm_auth_start_ntlmssp_client(struct ntlmssp_state **client_ntlmssp_state) +static NTSTATUS ntlm_auth_prepare_gensec_client(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct gensec_security **gensec_security_out) { - NTSTATUS status; - if ( (opt_username == NULL) || (opt_domain == NULL) ) { - status = NT_STATUS_UNSUCCESSFUL; - DEBUG(1, ("Need username and domain for NTLMSSP\n")); - return NT_STATUS_INVALID_PARAMETER; - } + struct gensec_security *gensec_security = NULL; + NTSTATUS nt_status; + TALLOC_CTX *tmp_ctx; + const struct gensec_security_ops **backends = NULL; + struct gensec_settings *gensec_settings = NULL; + size_t idx = 0; - status = ntlmssp_client_start(NULL, - lp_netbios_name(), - lp_workgroup(), - lp_client_ntlmv2_auth(), - client_ntlmssp_state); + tmp_ctx = talloc_new(mem_ctx); + NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not start NTLMSSP client: %s\n", - nt_errstr(status))); - TALLOC_FREE(*client_ntlmssp_state); - return status; + gensec_settings = lpcfg_gensec_settings(tmp_ctx, lp_ctx); + if (gensec_settings == NULL) { + DEBUG(10, ("lpcfg_gensec_settings failed\n")); + TALLOC_FREE(tmp_ctx); + return NT_STATUS_NO_MEMORY; } - status = ntlmssp_set_username(*client_ntlmssp_state, opt_username); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not set username: %s\n", - nt_errstr(status))); - TALLOC_FREE(*client_ntlmssp_state); - return status; + backends = talloc_zero_array(gensec_settings, + const struct gensec_security_ops *, 4); + if (backends == NULL) { + TALLOC_FREE(tmp_ctx); + return NT_STATUS_NO_MEMORY; } + gensec_settings->backends = backends; + + gensec_init(); + + /* These need to be in priority order, krb5 before NTLMSSP */ +#if defined(HAVE_KRB5) + backends[idx++] = &gensec_gse_krb5_security_ops; +#endif - status = ntlmssp_set_domain(*client_ntlmssp_state, opt_domain); + backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP); + + backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_SPNEGO); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not set domain: %s\n", - nt_errstr(status))); - TALLOC_FREE(*client_ntlmssp_state); - return status; + nt_status = gensec_client_start(NULL, &gensec_security, + gensec_settings); + if (!NT_STATUS_IS_OK(nt_status)) { + TALLOC_FREE(tmp_ctx); + return nt_status; } - if (opt_password) { - status = ntlmssp_set_password(*client_ntlmssp_state, opt_password); + talloc_unlink(tmp_ctx, gensec_settings); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not set password: %s\n", - nt_errstr(status))); - TALLOC_FREE(*client_ntlmssp_state); - return status; + if (opt_target_service != NULL) { + nt_status = gensec_set_target_service(gensec_security, + opt_target_service); + if (!NT_STATUS_IS_OK(nt_status)) { + TALLOC_FREE(tmp_ctx); + return nt_status; + } + } + + if (opt_target_hostname != NULL) { + nt_status = gensec_set_target_hostname(gensec_security, + opt_target_hostname); + if (!NT_STATUS_IS_OK(nt_status)) { + TALLOC_FREE(tmp_ctx); + return nt_status; } } + *gensec_security_out = talloc_steal(mem_ctx, gensec_security); + TALLOC_FREE(tmp_ctx); return NT_STATUS_OK; } @@ -1145,249 +1169,13 @@ static NTSTATUS ntlm_auth_prepare_gensec_server(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -/******************************************************************* - Used by firefox to drive NTLM auth to IIS servers. -*******************************************************************/ - -static NTSTATUS do_ccache_ntlm_auth(DATA_BLOB initial_msg, DATA_BLOB challenge_msg, - DATA_BLOB *reply) -{ - struct winbindd_request wb_request; - struct winbindd_response wb_response; - int ctrl = 0; - NSS_STATUS result; - - /* get winbindd to do the ntlmssp step on our behalf */ - ZERO_STRUCT(wb_request); - ZERO_STRUCT(wb_response); - - /* - * This is tricky here. If we set krb5_auth in pam_winbind.conf - * creds for users in trusted domain will be stored the winbindd - * child of the trusted domain. If we ask the primary domain for - * ntlm_ccache_auth, it will fail. So, we have to ask the trusted - * domain's child for ccache_ntlm_auth. that is to say, we have to - * set WBFLAG_PAM_CONTACT_TRUSTDOM in request.flags. - */ - ctrl = get_pam_winbind_config(); - - if (ctrl & WINBIND_KRB5_AUTH) { - wb_request.flags |= WBFLAG_PAM_CONTACT_TRUSTDOM; - } - - fstr_sprintf(wb_request.data.ccache_ntlm_auth.user, - "%s%c%s", opt_domain, winbind_separator(), opt_username); - wb_request.data.ccache_ntlm_auth.uid = geteuid(); - wb_request.data.ccache_ntlm_auth.initial_blob_len = initial_msg.length; - wb_request.data.ccache_ntlm_auth.challenge_blob_len = challenge_msg.length; - wb_request.extra_len = initial_msg.length + challenge_msg.length; - - if (wb_request.extra_len > 0) { - wb_request.extra_data.data = SMB_MALLOC_ARRAY(char, wb_request.extra_len); - if (wb_request.extra_data.data == NULL) { - return NT_STATUS_NO_MEMORY; - } - - memcpy(wb_request.extra_data.data, initial_msg.data, initial_msg.length); - memcpy(wb_request.extra_data.data + initial_msg.length, - challenge_msg.data, challenge_msg.length); - } - - result = winbindd_request_response(NULL, WINBINDD_CCACHE_NTLMAUTH, &wb_request, &wb_response); - SAFE_FREE(wb_request.extra_data.data); - - if (result != NSS_STATUS_SUCCESS) { - winbindd_free_response(&wb_response); - return NT_STATUS_UNSUCCESSFUL; - } - - if (reply) { - *reply = data_blob(wb_response.extra_data.data, - wb_response.data.ccache_ntlm_auth.auth_blob_len); - if (wb_response.data.ccache_ntlm_auth.auth_blob_len > 0 && - reply->data == NULL) { - winbindd_free_response(&wb_response); - return NT_STATUS_NO_MEMORY; - } - } - - winbindd_free_response(&wb_response); - return NT_STATUS_OK; -} - static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, struct loadparm_context *lp_ctx, struct ntlm_auth_state *state, char *buf, int length, void **private2) { - DATA_BLOB request, reply; - NTSTATUS nt_status; - - if (!opt_username || !*opt_username) { - x_fprintf(x_stderr, "username must be specified!\n\n"); - exit(1); - } - - if (strlen(buf) < 2) { - DEBUG(1, ("NTLMSSP query [%s] invalid\n", buf)); - x_fprintf(x_stdout, "BH NTLMSSP query invalid\n"); - return; - } - - if (strlen(buf) > 3) { - if(strncmp(buf, "SF ", 3) == 0) { - DEBUG(10, ("Looking for flags to negotiate\n")); - talloc_free(state->want_feature_list); - state->want_feature_list = talloc_strdup(state->mem_ctx, - buf+3); - x_fprintf(x_stdout, "OK\n"); - return; - } - request = base64_decode_data_blob(buf + 3); - } else { - request = data_blob_null; - } - - if (strncmp(buf, "PW ", 3) == 0) { - /* We asked for a password and obviously got it :-) */ - - opt_password = SMB_STRNDUP((const char *)request.data, - request.length); - - if (opt_password == NULL) { - DEBUG(1, ("Out of memory\n")); - x_fprintf(x_stdout, "BH Out of memory\n"); - data_blob_free(&request); - return; - } - - x_fprintf(x_stdout, "OK\n"); - data_blob_free(&request); - return; - } - - if (!state->ntlmssp_state && use_cached_creds) { - /* check whether cached credentials are usable. */ - DATA_BLOB empty_blob = data_blob_null; - - nt_status = do_ccache_ntlm_auth(empty_blob, empty_blob, NULL); - if (!NT_STATUS_IS_OK(nt_status)) { - /* failed to use cached creds */ - use_cached_creds = False; - } - } - - if (opt_password == NULL && !use_cached_creds) { - /* Request a password from the calling process. After - sending it, the calling process should retry asking for the - negotiate. */ - - DEBUG(10, ("Requesting password\n")); - x_fprintf(x_stdout, "PW\n"); - return; - } - - if (strncmp(buf, "YR", 2) == 0) { - TALLOC_FREE(state->ntlmssp_state); - state->cli_state = CLIENT_INITIAL; - } else if (strncmp(buf, "TT", 2) == 0) { - /* No special preprocessing required */ - } else if (strncmp(buf, "GF", 2) == 0) { - DEBUG(10, ("Requested negotiated NTLMSSP flags\n")); - - if(state->cli_state == CLIENT_FINISHED) { - x_fprintf(x_stdout, "GF 0x%08x\n", state->neg_flags); - } - else { - x_fprintf(x_stdout, "BH\n"); - } - - data_blob_free(&request); - return; - } else if (strncmp(buf, "GK", 2) == 0 ) { - DEBUG(10, ("Requested session key\n")); - - if(state->cli_state == CLIENT_FINISHED) { - char *key64 = base64_encode_data_blob(state->mem_ctx, - state->session_key); - x_fprintf(x_stdout, "GK %s\n", key64?key64:""); - TALLOC_FREE(key64); - } - else { - x_fprintf(x_stdout, "BH\n"); - } - - data_blob_free(&request); - return; - } else { - DEBUG(1, ("NTLMSSP query [%s] invalid\n", buf)); - x_fprintf(x_stdout, "BH NTLMSSP query invalid\n"); - return; - } - - if (!state->ntlmssp_state) { - nt_status = ntlm_auth_start_ntlmssp_client( - &state->ntlmssp_state); - if (!NT_STATUS_IS_OK(nt_status)) { - x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); - return; - } - ntlmssp_want_feature_list(state->ntlmssp_state, - state->want_feature_list); - state->initial_message = data_blob_null; - } - - DEBUG(10, ("got NTLMSSP packet:\n")); - dump_data(10, request.data, request.length); - - if (use_cached_creds && !opt_password && - (state->cli_state == CLIENT_RESPONSE)) { - nt_status = do_ccache_ntlm_auth(state->initial_message, request, - &reply); - } else { - nt_status = ntlmssp_update(state->ntlmssp_state, request, - &reply); - } - - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - char *reply_base64 = base64_encode_data_blob(state->mem_ctx, - reply); - if (state->cli_state == CLIENT_INITIAL) { - x_fprintf(x_stdout, "YR %s\n", reply_base64); - state->initial_message = reply; - state->cli_state = CLIENT_RESPONSE; - } else { - x_fprintf(x_stdout, "KK %s\n", reply_base64); - data_blob_free(&reply); - } - TALLOC_FREE(reply_base64); - DEBUG(10, ("NTLMSSP challenge\n")); - } else if (NT_STATUS_IS_OK(nt_status)) { - char *reply_base64 = base64_encode_data_blob(talloc_tos(), - reply); - x_fprintf(x_stdout, "AF %s\n", reply_base64); - TALLOC_FREE(reply_base64); - - if(state->have_session_key) - data_blob_free(&state->session_key); - - state->session_key = data_blob( - state->ntlmssp_state->session_key.data, - state->ntlmssp_state->session_key.length); - state->neg_flags = state->ntlmssp_state->neg_flags; - state->have_session_key = true; - - DEBUG(10, ("NTLMSSP OK!\n")); - state->cli_state = CLIENT_FINISHED; - TALLOC_FREE(state->ntlmssp_state); - } else { - x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); - DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); - state->cli_state = CLIENT_ERROR; - TALLOC_FREE(state->ntlmssp_state); - } - - data_blob_free(&request); + manage_gensec_request(stdio_helper_mode, lp_ctx, buf, length, &state->gensec_private_1); + return; } static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode, @@ -1506,11 +1294,42 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, if (!(state->gensec_state)) { switch (stdio_helper_mode) { case GSS_SPNEGO_CLIENT: + /* + * cached credentials are only supported by + * NTLMSSP_CLIENT_1 for now. + */ + use_cached_creds = false; + /* fall through */ case NTLMSSP_CLIENT_1: /* setup the client side */ - nt_status = gensec_client_start(NULL, &state->gensec_state, - lpcfg_gensec_settings(NULL, lp_ctx)); + if (state->set_password != NULL) { + use_cached_creds = false; + } + + if (use_cached_creds) { + struct wbcCredentialCacheParams params; + struct wbcCredentialCacheInfo *info = NULL; + struct wbcAuthErrorInfo *error = NULL; + wbcErr wbc_status; + + params.account_name = opt_username; + params.domain_name = opt_domain; + params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP; + params.num_blobs = 0; + params.blobs = NULL; + + wbc_status = wbcCredentialCache(¶ms, &info, + &error); + wbcFreeMemory(error); + if (!WBC_ERROR_IS_OK(wbc_status)) { + use_cached_creds = false; + } + wbcFreeMemory(info); + } + + nt_status = ntlm_auth_prepare_gensec_client(state, lp_ctx, + &state->gensec_state); if (!NT_STATUS_IS_OK(nt_status)) { x_fprintf(x_stdout, "BH GENSEC mech failed to start: %s\n", nt_errstr(nt_status)); talloc_free(mem_ctx); @@ -1525,7 +1344,10 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, if (opt_domain) { cli_credentials_set_domain(creds, opt_domain, CRED_SPECIFIED); } - if (state->set_password) { + if (use_cached_creds) { + gensec_want_feature(state->gensec_state, + GENSEC_FEATURE_NTLM_CCACHE); + } else if (state->set_password) { cli_credentials_set_password(creds, state->set_password, CRED_SPECIFIED); } else { cli_credentials_set_password_callback(creds, get_password); @@ -1620,12 +1442,17 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, return; } - if (stdio_helper_mode == SQUID_2_5_NTLMSSP && strncmp(buf, "GF", 2) == 0) { + if (strncmp(buf, "GF", 2) == 0) { uint32_t neg_flags; + DEBUG(10, ("Requested negotiated NTLMSSP feature flags\n")); + neg_flags = gensec_ntlmssp_neg_flags(state->gensec_state); + if (neg_flags == 0) { + x_fprintf(x_stdout, "BH\n"); + return; + } - DEBUG(10, ("Requested negotiated feature flags\n")); x_fprintf(x_stdout, "GF 0x%08x\n", neg_flags); return; } @@ -1729,408 +1556,12 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod return; } -static struct ntlmssp_state *client_ntlmssp_state = NULL; - -static bool manage_client_ntlmssp_init(struct spnego_data spnego) -{ - NTSTATUS status; - DATA_BLOB null_blob = data_blob_null; - DATA_BLOB to_server; - char *to_server_base64; - const char *my_mechs[] = {OID_NTLMSSP, NULL}; - TALLOC_CTX *ctx = talloc_tos(); - - DEBUG(10, ("Got spnego negTokenInit with NTLMSSP\n")); - - if (client_ntlmssp_state != NULL) { - DEBUG(1, ("Request for initial SPNEGO request where " - "we already have a state\n")); - return False; - } - - if (!client_ntlmssp_state) { - if (!NT_STATUS_IS_OK(status = ntlm_auth_start_ntlmssp_client(&client_ntlmssp_state))) { - x_fprintf(x_stdout, "BH %s\n", nt_errstr(status)); - return False; - } - } - - - if (opt_password == NULL) { - - /* Request a password from the calling process. After - sending it, the calling process should retry with - the negTokenInit. */ - - DEBUG(10, ("Requesting password\n")); - x_fprintf(x_stdout, "PW\n"); - return True; - } - - spnego.type = SPNEGO_NEG_TOKEN_INIT; - spnego.negTokenInit.mechTypes = my_mechs; - spnego.negTokenInit.reqFlags = data_blob_null; - spnego.negTokenInit.reqFlagsPadding = 0; - spnego.negTokenInit.mechListMIC = null_blob; - - status = ntlmssp_update(client_ntlmssp_state, null_blob, - &spnego.negTokenInit.mechToken); - - if ( !(NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || - NT_STATUS_IS_OK(status)) ) { - DEBUG(1, ("Expected OK or MORE_PROCESSING_REQUIRED, got: %s\n", - nt_errstr(status))); - TALLOC_FREE(client_ntlmssp_state); - return False; - } - - spnego_write_data(ctx, &to_server, &spnego); - data_blob_free(&spnego.negTokenInit.mechToken); - - to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server); - data_blob_free(&to_server); - x_fprintf(x_stdout, "KK %s\n", to_server_base64); - TALLOC_FREE(to_server_base64); - return True; -} - -static void manage_client_ntlmssp_targ(struct spnego_data spnego) -{ - NTSTATUS status; - DATA_BLOB null_blob = data_blob_null; - DATA_BLOB request; - DATA_BLOB to_server; - char *to_server_base64; - TALLOC_CTX *ctx = talloc_tos(); - - DEBUG(10, ("Got spnego negTokenTarg with NTLMSSP\n")); - - if (client_ntlmssp_state == NULL) { - DEBUG(1, ("Got NTLMSSP tArg without a client state\n")); - x_fprintf(x_stdout, "BH Got NTLMSSP tArg without a client state\n"); - return; - } - - if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { - x_fprintf(x_stdout, "NA\n"); - TALLOC_FREE(client_ntlmssp_state); - return; - } - - if (spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) { - x_fprintf(x_stdout, "AF\n"); - TALLOC_FREE(client_ntlmssp_state); - return; - } - - status = ntlmssp_update(client_ntlmssp_state, - spnego.negTokenTarg.responseToken, - &request); - - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED or OK from " - "ntlmssp_client_update, got: %s\n", - nt_errstr(status))); - x_fprintf(x_stdout, "BH Expected MORE_PROCESSING_REQUIRED from " - "ntlmssp_client_update\n"); - data_blob_free(&request); - TALLOC_FREE(client_ntlmssp_state); - return; - } - - spnego.type = SPNEGO_NEG_TOKEN_TARG; - spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; - spnego.negTokenTarg.supportedMech = (const char *)OID_NTLMSSP; - spnego.negTokenTarg.responseToken = request; - spnego.negTokenTarg.mechListMIC = null_blob; - - spnego_write_data(ctx, &to_server, &spnego); - data_blob_free(&request); - - to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server); - data_blob_free(&to_server); - x_fprintf(x_stdout, "KK %s\n", to_server_base64); - TALLOC_FREE(to_server_base64); - return; -} - -#ifdef HAVE_KRB5 - -static bool manage_client_krb5_init(struct spnego_data spnego) -{ - char *principal; - DATA_BLOB tkt, tkt_wrapped, to_server; - DATA_BLOB session_key_krb5 = data_blob_null; - struct spnego_data reply; - char *reply_base64; - int retval; - - const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL}; - ssize_t len; - TALLOC_CTX *ctx = talloc_tos(); - - principal = spnego.negTokenInit.targetPrincipal; - - /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us - */ - if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) { - principal = NULL; - } - - if (principal == NULL && - opt_target_service && opt_target_hostname && !is_ipaddress(opt_target_hostname)) { - DEBUG(3,("manage_client_krb5_init: using target " - "hostname not SPNEGO principal\n")); - - principal = kerberos_get_principal_from_service_hostname(talloc_tos(), - opt_target_service, - opt_target_hostname, - lp_realm()); - - if (!principal) { - return false; - } - - DEBUG(3,("manage_client_krb5_init: guessed " - "server principal=%s\n", - principal ? principal : "")); - } - - if (principal == NULL) { - DEBUG(3,("manage_client_krb5_init: could not guess server principal\n")); - return false; - } - - retval = cli_krb5_get_ticket(ctx, principal, 0, - &tkt, &session_key_krb5, - 0, NULL, NULL, NULL); - if (retval) { - char *user = NULL; - - /* Let's try to first get the TGT, for that we need a - password. */ - - if (opt_password == NULL) { - DEBUG(10, ("Requesting password\n")); - x_fprintf(x_stdout, "PW\n"); - return True; - } - - user = talloc_asprintf(talloc_tos(), "%s@%s", opt_username, opt_domain); - if (!user) { - return false; - } - - if ((retval = kerberos_kinit_password(user, opt_password, 0, NULL))) { - DEBUG(10, ("Requesting TGT failed: %s\n", error_message(retval))); - return False; - } - - retval = cli_krb5_get_ticket(ctx, principal, 0, - &tkt, &session_key_krb5, - 0, NULL, NULL, NULL); - if (retval) { - DEBUG(10, ("Kinit suceeded, but getting a ticket failed: %s\n", error_message(retval))); - return False; - } - - } - - /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap(ctx, tkt, TOK_ID_KRB_AP_REQ); - - data_blob_free(&session_key_krb5); - - ZERO_STRUCT(reply); - - reply.type = SPNEGO_NEG_TOKEN_INIT; - reply.negTokenInit.mechTypes = my_mechs; - reply.negTokenInit.reqFlags = data_blob_null; - reply.negTokenInit.reqFlagsPadding = 0; - reply.negTokenInit.mechToken = tkt_wrapped; - reply.negTokenInit.mechListMIC = data_blob_null; - - len = spnego_write_data(ctx, &to_server, &reply); - data_blob_free(&tkt); - - if (len == -1) { - DEBUG(1, ("Could not write SPNEGO data blob\n")); - return False; - } - - reply_base64 = base64_encode_data_blob(talloc_tos(), to_server); - x_fprintf(x_stdout, "KK %s *\n", reply_base64); - - TALLOC_FREE(reply_base64); - data_blob_free(&to_server); - DEBUG(10, ("sent GSS-SPNEGO KERBEROS5 negTokenInit\n")); - return True; -} - -static void manage_client_krb5_targ(struct spnego_data spnego) -{ - switch (spnego.negTokenTarg.negResult) { - case SPNEGO_ACCEPT_INCOMPLETE: - DEBUG(1, ("Got a Kerberos negTokenTarg with ACCEPT_INCOMPLETE\n")); - x_fprintf(x_stdout, "BH Got a Kerberos negTokenTarg with " - "ACCEPT_INCOMPLETE\n"); - break; - case SPNEGO_ACCEPT_COMPLETED: - DEBUG(10, ("Accept completed\n")); - x_fprintf(x_stdout, "AF\n"); - break; - case SPNEGO_REJECT: - DEBUG(10, ("Rejected\n")); - x_fprintf(x_stdout, "NA\n"); - break; - default: - DEBUG(1, ("Got an invalid negTokenTarg\n")); - x_fprintf(x_stdout, "AF\n"); - } -} - -#endif - static void manage_gss_spnego_client_request(enum stdio_helper_mode stdio_helper_mode, struct loadparm_context *lp_ctx, struct ntlm_auth_state *state, char *buf, int length, void **private2) { - DATA_BLOB request; - struct spnego_data spnego; - ssize_t len; - TALLOC_CTX *ctx = talloc_tos(); - - if (!opt_username || !*opt_username) { - x_fprintf(x_stderr, "username must be specified!\n\n"); - exit(1); - } - - if (strlen(buf) <= 3) { - DEBUG(1, ("SPNEGO query [%s] too short\n", buf)); - x_fprintf(x_stdout, "BH SPNEGO query too short\n"); - return; - } - - request = base64_decode_data_blob(buf+3); - - if (strncmp(buf, "PW ", 3) == 0) { - - /* We asked for a password and obviously got it :-) */ - - opt_password = SMB_STRNDUP((const char *)request.data, request.length); - - if (opt_password == NULL) { - DEBUG(1, ("Out of memory\n")); - x_fprintf(x_stdout, "BH Out of memory\n"); - data_blob_free(&request); - return; - } - - x_fprintf(x_stdout, "OK\n"); - data_blob_free(&request); - return; - } - - if ( (strncmp(buf, "TT ", 3) != 0) && - (strncmp(buf, "AF ", 3) != 0) && - (strncmp(buf, "NA ", 3) != 0) ) { - DEBUG(1, ("SPNEGO request [%s] invalid\n", buf)); - x_fprintf(x_stdout, "BH SPNEGO request invalid\n"); - data_blob_free(&request); - return; - } - - /* So we got a server challenge to generate a SPNEGO - client-to-server request... */ - - len = spnego_read_data(ctx, request, &spnego); - data_blob_free(&request); - - if (len == -1) { - DEBUG(1, ("Could not read SPNEGO data for [%s]\n", buf)); - x_fprintf(x_stdout, "BH Could not read SPNEGO data\n"); - return; - } - - if (spnego.type == SPNEGO_NEG_TOKEN_INIT) { - - /* The server offers a list of mechanisms */ - - const char *const *mechType = spnego.negTokenInit.mechTypes; - - while (*mechType != NULL) { - -#ifdef HAVE_KRB5 - if ( (strcmp(*mechType, OID_KERBEROS5_OLD) == 0) || - (strcmp(*mechType, OID_KERBEROS5) == 0) ) { - if (manage_client_krb5_init(spnego)) - goto out; - } -#endif - - if (strcmp(*mechType, OID_NTLMSSP) == 0) { - if (manage_client_ntlmssp_init(spnego)) - goto out; - } - - mechType++; - } - - DEBUG(1, ("Server offered no compatible mechanism\n")); - x_fprintf(x_stdout, "BH Server offered no compatible mechanism\n"); - return; - } - - if (spnego.type == SPNEGO_NEG_TOKEN_TARG) { - - if (spnego.negTokenTarg.supportedMech == NULL) { - /* On accept/reject Windows does not send the - mechanism anymore. Handle that here and - shut down the mechanisms. */ - - switch (spnego.negTokenTarg.negResult) { - case SPNEGO_ACCEPT_COMPLETED: - x_fprintf(x_stdout, "AF\n"); - break; - case SPNEGO_REJECT: - x_fprintf(x_stdout, "NA\n"); - break; - default: - DEBUG(1, ("Got a negTokenTarg with no mech and an " - "unknown negResult: %d\n", - spnego.negTokenTarg.negResult)); - x_fprintf(x_stdout, "BH Got a negTokenTarg with" - " no mech and an unknown " - "negResult\n"); - } - - TALLOC_FREE(client_ntlmssp_state); - goto out; - } - - if (strcmp(spnego.negTokenTarg.supportedMech, - OID_NTLMSSP) == 0) { - manage_client_ntlmssp_targ(spnego); - goto out; - } - -#if HAVE_KRB5 - if (strcmp(spnego.negTokenTarg.supportedMech, - OID_KERBEROS5_OLD) == 0) { - manage_client_krb5_targ(spnego); - goto out; - } -#endif - - } - - DEBUG(1, ("Got an SPNEGO token I could not handle [%s]!\n", buf)); - x_fprintf(x_stdout, "BH Got an SPNEGO token I could not handle\n"); - return; - - out: - spnego_free_data(&spnego); + manage_gensec_request(stdio_helper_mode, lp_ctx, buf, length, &state->gensec_private_1); return; } -- 1.9.1 From 60c20b74bf2b323c4f951fa947facebc07a3a337 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 11:16:02 +0100 Subject: [PATCH 049/323] auth/ntlmssp: split out a debug_ntlmssp_flags_raw() that's more complete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit e63442a1c27c475e373048893d9cf04859dd1792) --- auth/ntlmssp/ntlmssp_util.c | 77 +++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_util.c b/auth/ntlmssp/ntlmssp_util.c index 96793ab..dee909a 100644 --- a/auth/ntlmssp/ntlmssp_util.c +++ b/auth/ntlmssp/ntlmssp_util.c @@ -25,6 +25,41 @@ #include "../auth/ntlmssp/ntlmssp.h" #include "../auth/ntlmssp/ntlmssp_private.h" +static void debug_ntlmssp_flags_raw(int level, uint32_t flags) +{ +#define _PRINT_FLAG_LINE(v) do { \ + if (flags & (v)) { \ + DEBUGADD(level, (" " #v "\n")); \ + } \ +} while (0) + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_UNICODE); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_OEM); + _PRINT_FLAG_LINE(NTLMSSP_REQUEST_TARGET); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_SIGN); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_SEAL); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_DATAGRAM); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_LM_KEY); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_NETWARE); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_NTLM); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_NT_ONLY); + _PRINT_FLAG_LINE(NTLMSSP_ANONYMOUS); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_ALWAYS_SIGN); + _PRINT_FLAG_LINE(NTLMSSP_TARGET_TYPE_DOMAIN); + _PRINT_FLAG_LINE(NTLMSSP_TARGET_TYPE_SERVER); + _PRINT_FLAG_LINE(NTLMSSP_TARGET_TYPE_SHARE); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_IDENTIFY); + _PRINT_FLAG_LINE(NTLMSSP_REQUEST_NON_NT_SESSION_KEY); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_TARGET_INFO); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_VERSION); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_128); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_KEY_EXCH); + _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_56); +} + /** * Print out the NTLMSSP flags for debugging * @param neg_flags The flags from the packet @@ -32,47 +67,7 @@ void debug_ntlmssp_flags(uint32_t neg_flags) { DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); - - if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_OEM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); - if (neg_flags & NTLMSSP_REQUEST_TARGET) - DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DATAGRAM\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); - if (neg_flags & NTLMSSP_REQUEST_NON_NT_SESSION_KEY) - DEBUGADD(4, (" NTLMSSP_REQUEST_NON_NT_SESSION_KEY\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_TARGET_INFO\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_VERSION) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_VERSION\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_128) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_56) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_56\n")); + debug_ntlmssp_flags_raw(4, neg_flags); } void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, -- 1.9.1 From ec326f884fe8927434ed72a3da10f400ce632284 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 10:52:29 +0100 Subject: [PATCH 050/323] auth/ntlmssp: NTLMSSP_NEGOTIATE_VERSION is not a negotiated option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NTLMSSP_NEGOTIATE_VERSION only indicates the existence of the version information in the packet. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 30d626024c7e8f275d64f835632717b0130be4b2) --- auth/ntlmssp/ntlmssp_util.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_util.c b/auth/ntlmssp/ntlmssp_util.c index dee909a..96a9991 100644 --- a/auth/ntlmssp/ntlmssp_util.c +++ b/auth/ntlmssp/ntlmssp_util.c @@ -119,10 +119,6 @@ void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_VERSION)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_VERSION; - } - if ((neg_flags & NTLMSSP_REQUEST_TARGET)) { ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET; } -- 1.9.1 From 949854ac13a861d581fdea1977d281add265257a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 11:01:24 +0100 Subject: [PATCH 051/323] auth/ntlmssp: define all client neg_flags in gensec_ntlmssp_client_start() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit afba38dbf5c954abbcfc485a81f510255b69a426) --- auth/ntlmssp/ntlmssp_client.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 0823ebe..114f8b0 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -71,16 +71,6 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security, workstation = ""; } - if (ntlmssp_state->unicode) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; - } else { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; - } - - if (ntlmssp_state->use_ntlmv2) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; - } - /* generate the ntlmssp negotiate packet */ status = msrpc_gen(out_mem_ctx, out, "CddAA", @@ -604,6 +594,12 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_REQUEST_TARGET; + if (ntlmssp_state->unicode) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; + } else { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; + } + if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "128bit", true)) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128; } @@ -631,6 +627,10 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) ntlmssp_state->use_ntlmv2 = false; } + if (ntlmssp_state->use_ntlmv2) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; + } + if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { /* * We need to set this to allow a later SetPassword -- 1.9.1 From 457a62c7fa476ce593705ca34151b34d67d2d823 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 8 Dec 2015 13:59:42 +0100 Subject: [PATCH 052/323] auth/ntlmssp: set NTLMSSP_ANONYMOUS for anonymous authentication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches a modern Windows client. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit efd4986794889f1315dbd011b94b8673d785053a) --- auth/ntlmssp/ntlmssp_client.c | 1 + 1 file changed, 1 insertion(+) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 114f8b0..afd5a00 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -359,6 +359,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, } if (is_anonymous) { + ntlmssp_state->neg_flags |= NTLMSSP_ANONYMOUS; /* * don't use the ccache for anonymous auth */ -- 1.9.1 From cfb4a0f535382c283f20440ccc8f411107620e2f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 10:52:29 +0100 Subject: [PATCH 053/323] auth/ntlmssp: don't send domain and workstation in the NEGOTIATE_MESSAGE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't set NTLMSSP_NEGOTIATE_OEM_{DOMAIN,WORKSTATION}_SUPPLIED anyway. This matches modern Windows clients. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 4fca8eaaae23955e704dc9c45d373fe78bf88201) --- auth/ntlmssp/ntlmssp_client.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index afd5a00..61ca886 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -58,28 +58,16 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security, talloc_get_type_abort(gensec_security->private_data, struct gensec_ntlmssp_context); struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; - const char *domain = ntlmssp_state->client.netbios_domain; - const char *workstation = ntlmssp_state->client.netbios_name; NTSTATUS status; - /* These don't really matter in the initial packet, so don't panic if they are not set */ - if (!domain) { - domain = ""; - } - - if (!workstation) { - workstation = ""; - } - /* generate the ntlmssp negotiate packet */ status = msrpc_gen(out_mem_ctx, out, "CddAA", "NTLMSSP", NTLMSSP_NEGOTIATE, ntlmssp_state->neg_flags, - domain, - workstation); - + "", /* domain */ + ""); /* workstation */ if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("ntlmssp_client_initial: failed to generate " "ntlmssp negotiate packet\n")); -- 1.9.1 From b98e0a119049198a1b1049bfba3936128f612f6f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 14:05:17 +0100 Subject: [PATCH 054/323] auth/ntlmssp: add ntlmssp_version_blob() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit a61ab398ccc1036edce677e00569fd7f58b70995) --- auth/ntlmssp/ntlmssp_private.h | 1 + auth/ntlmssp/ntlmssp_util.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/auth/ntlmssp/ntlmssp_private.h b/auth/ntlmssp/ntlmssp_private.h index ea5703f..29eca35 100644 --- a/auth/ntlmssp/ntlmssp_private.h +++ b/auth/ntlmssp/ntlmssp_private.h @@ -61,6 +61,7 @@ NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, void debug_ntlmssp_flags(uint32_t neg_flags); void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, uint32_t neg_flags, bool allow_lm); +const DATA_BLOB ntlmssp_version_blob(void); /* The following definitions come from auth/ntlmssp_server.c */ diff --git a/auth/ntlmssp/ntlmssp_util.c b/auth/ntlmssp/ntlmssp_util.c index 96a9991..bfe27f9 100644 --- a/auth/ntlmssp/ntlmssp_util.c +++ b/auth/ntlmssp/ntlmssp_util.c @@ -133,3 +133,38 @@ bool ntlmssp_blob_matches_magic(const DATA_BLOB *blob) return false; } } + +const DATA_BLOB ntlmssp_version_blob(void) +{ + /* + * This is a simplified version of + * + * enum ndr_err_code err; + * struct ntlmssp_VERSION vers; + * + * ZERO_STRUCT(vers); + * vers.ProductMajorVersion = NTLMSSP_WINDOWS_MAJOR_VERSION_6; + * vers.ProductMinorVersion = NTLMSSP_WINDOWS_MINOR_VERSION_1; + * vers.ProductBuild = 0; + * vers.NTLMRevisionCurrent = NTLMSSP_REVISION_W2K3; + * + * err = ndr_push_struct_blob(&version_blob, + * ntlmssp_state, + * &vers, + * (ndr_push_flags_fn_t)ndr_push_ntlmssp_VERSION); + * + * if (!NDR_ERR_CODE_IS_SUCCESS(err)) { + * data_blob_free(&struct_blob); + * return NT_STATUS_NO_MEMORY; + * } + */ + static const uint8_t version_buffer[8] = { + NTLMSSP_WINDOWS_MAJOR_VERSION_6, + NTLMSSP_WINDOWS_MINOR_VERSION_1, + 0x00, 0x00, /* product build */ + 0x00, 0x00, 0x00, /* reserved */ + NTLMSSP_REVISION_W2K3 + }; + + return data_blob_const(version_buffer, ARRAY_SIZE(version_buffer)); +} -- 1.9.1 From 33270cd3b554fa76973595b2bfe4f6d08d54bf93 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 10:52:29 +0100 Subject: [PATCH 055/323] auth/ntlmssp: let the client always include NTLMSSP_NEGOTIATE_VERSION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches a modern Windows client. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 4a1809cb14dcb03e9ba386af5b90650400377875) --- auth/ntlmssp/ntlmssp_client.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 61ca886..523a842 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -59,15 +59,17 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security, struct gensec_ntlmssp_context); struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; NTSTATUS status; + const DATA_BLOB version_blob = ntlmssp_version_blob(); /* generate the ntlmssp negotiate packet */ status = msrpc_gen(out_mem_ctx, - out, "CddAA", + out, "CddAAb", "NTLMSSP", NTLMSSP_NEGOTIATE, ntlmssp_state->neg_flags, - "", /* domain */ - ""); /* workstation */ + "", /* domain */ + "", /* workstation */ + version_blob.data, version_blob.length); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("ntlmssp_client_initial: failed to generate " "ntlmssp negotiate packet\n")); @@ -220,6 +222,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, int flags = 0; const char *user = NULL, *domain = NULL, *workstation = NULL; bool is_anonymous = false; + const DATA_BLOB version_blob = ntlmssp_version_blob(); TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx); if (!mem_ctx) { @@ -253,7 +256,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, chal_parse_string = "CdUdbdd"; chal_parse_string_short = "CdUdb"; } - auth_gen_string = "CdBBUUUBd"; + auth_gen_string = "CdBBUUUBdb"; } else { if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { chal_parse_string = "CdAdbddB"; @@ -262,7 +265,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, chal_parse_string_short = "CdAdb"; } - auth_gen_string = "CdBBAAABd"; + auth_gen_string = "CdBBAAABdb"; } if (!msrpc_parse(mem_ctx, @@ -508,7 +511,8 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, user, workstation, encrypted_session_key.data, encrypted_session_key.length, - ntlmssp_state->neg_flags); + ntlmssp_state->neg_flags, + version_blob.data, version_blob.length); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; @@ -581,6 +585,7 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) ntlmssp_state->neg_flags = NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_NEGOTIATE_VERSION | NTLMSSP_REQUEST_TARGET; if (ntlmssp_state->unicode) { -- 1.9.1 From 34c83c6012b00b8eadd3717152c2d111c7c29d5c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 14:07:23 +0100 Subject: [PATCH 056/323] auth/ntlmssp: use ntlmssp_version_blob() in the server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already set NTLMSSP_NEGOTIATE_VERSION in gensec_ntlmssp_server_start(), so it's always set in chal_flags. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 8af6b8d2eb6b873620131b4b5b570ec24985d86a) --- auth/ntlmssp/ntlmssp_server.c | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c index 2f3f0bb..94692cd 100644 --- a/auth/ntlmssp/ntlmssp_server.c +++ b/auth/ntlmssp/ntlmssp_server.c @@ -168,29 +168,7 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security { /* Marshal the packet in the right format, be it unicode or ASCII */ const char *gen_string; - DATA_BLOB version_blob = data_blob_null; - - if (chal_flags & NTLMSSP_NEGOTIATE_VERSION) { - enum ndr_err_code err; - struct ntlmssp_VERSION vers; - - /* "What Windows returns" as a version number. */ - ZERO_STRUCT(vers); - vers.ProductMajorVersion = NTLMSSP_WINDOWS_MAJOR_VERSION_6; - vers.ProductMinorVersion = NTLMSSP_WINDOWS_MINOR_VERSION_1; - vers.ProductBuild = 0; - vers.NTLMRevisionCurrent = NTLMSSP_REVISION_W2K3; - - err = ndr_push_struct_blob(&version_blob, - ntlmssp_state, - &vers, - (ndr_push_flags_fn_t)ndr_push_ntlmssp_VERSION); - - if (!NDR_ERR_CODE_IS_SUCCESS(err)) { - data_blob_free(&struct_blob); - return NT_STATUS_NO_MEMORY; - } - } + const DATA_BLOB version_blob = ntlmssp_version_blob(); if (ntlmssp_state->unicode) { gen_string = "CdUdbddBb"; @@ -209,13 +187,10 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security version_blob.data, version_blob.length); if (!NT_STATUS_IS_OK(status)) { - data_blob_free(&version_blob); data_blob_free(&struct_blob); return status; } - data_blob_free(&version_blob); - if (DEBUGLEVEL >= 10) { struct CHALLENGE_MESSAGE *challenge = talloc( ntlmssp_state, struct CHALLENGE_MESSAGE); -- 1.9.1 From a6f91f19a1f3f2ba5ce089aa8ceb3c4aaaaea7fd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 09:06:56 +0100 Subject: [PATCH 057/323] security.idl: add LSAP_TOKEN_INFO_INTEGRITY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is used in [MS-KILE] and implicit in [MS-NLMP]. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 1f88812316144b06b11eb3dc90a6081cb57783da) --- librpc/idl/security.idl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl index f412ffe..f706efd 100644 --- a/librpc/idl/security.idl +++ b/librpc/idl/security.idl @@ -652,6 +652,15 @@ interface security 0); /* + * See [MS-KILE] 2.2.5 LSAP_TOKEN_INFO_INTEGRITY + */ + typedef [public,gensize,flag(NDR_PAHEX)] struct { + uint32 Flags; + uint32 TokenIL; + uint8 MachineId[32]; + } LSAP_TOKEN_INFO_INTEGRITY; + + /* * See [MS-KILE] 2.2.6 Supported Encryption Types Bit Flags */ typedef [public,bitmap32bit] bitmap { -- 1.9.1 From c434aef1f02b4e9169dc7645e518dced7e31744d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 09:07:57 +0100 Subject: [PATCH 058/323] ntlmssp.idl: MsAvRestrictions is MsvAvSingleHost now MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit ab54e0fd7040e7717fe979b54fb4dfa16813524f) --- librpc/idl/ntlmssp.idl | 19 ++++++++++--------- source4/torture/ndr/ntlmssp.c | 13 +++++++------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/librpc/idl/ntlmssp.idl b/librpc/idl/ntlmssp.idl index df6773c..5d8a12a 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -1,5 +1,7 @@ #include "idl_types.h" +import "security.idl"; + /* ntlmssp interface definition */ @@ -127,20 +129,19 @@ interface ntlmssp MsvAvDnsTreeName = 5, MsvAvFlags = 6, MsvAvTimestamp = 7, - MsAvRestrictions = 8, + MsvAvSingleHost = 8, MsvAvTargetName = 9, MsvChannelBindings = 10 } ntlmssp_AvId; - /* [MS-NLMP] 2.2.2.2 Restriction_Encoding */ + /* [MS-NLMP] 2.2.2.2 SingleHostData */ - typedef struct { - uint32 Size; + typedef [flag(NDR_PAHEX)] struct { + [value(8+ndr_size_LSAP_TOKEN_INFO_INTEGRITY(&r->token_info, 0)+r->remaining.length)] uint32 Size; [value(0)] uint32 Z4; - boolean32 IntegrityLevel; - uint32 SubjectIntegrityLevel; - uint8 MachineId[32]; - } Restriction_Encoding; + LSAP_TOKEN_INFO_INTEGRITY token_info; + [flag(NDR_REMAINING)] DATA_BLOB remaining; + } ntlmssp_SingleHostData; typedef [bitmap32bit] bitmap { NTLMSSP_AVFLAG_CONSTRAINTED_ACCOUNT = 0x00000001, @@ -157,7 +158,7 @@ interface ntlmssp [case(MsvAvDnsTreeName)] [flag(ndr_ntlmssp_negotiated_string_flags(NTLMSSP_NEGOTIATE_UNICODE))] string AvDnsTreeName; [case(MsvAvFlags)] ntlmssp_AvFlags AvFlags; [case(MsvAvTimestamp)] NTTIME AvTimestamp; - [case(MsAvRestrictions)] Restriction_Encoding AvRestrictions; + [case(MsvAvSingleHost)] ntlmssp_SingleHostData AvSingleHost; [case(MsvAvTargetName)] [flag(ndr_ntlmssp_negotiated_string_flags(NTLMSSP_NEGOTIATE_UNICODE))] string AvTargetName; [case(MsvChannelBindings)] uint8 ChannelBindings[16]; [default] [flag(NDR_REMAINING)] DATA_BLOB blob; diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c index ae56192..aeac26f 100644 --- a/source4/torture/ndr/ntlmssp.c +++ b/source4/torture/ndr/ntlmssp.c @@ -225,13 +225,14 @@ static bool ntlmssp_AUTHENTICATE_MESSAGE_check(struct torture_context *tctx, torture_assert_int_equal(tctx, AvPairs.pair[3].AvLen, 46, "AvLen"); torture_assert_str_equal(tctx, AvPairs.pair[3].Value.AvDnsComputerName, "mthelena.ber.redhat.com", "Value.AvDnsComputerName"); - torture_assert_int_equal(tctx, AvPairs.pair[4].AvId, MsAvRestrictions, "AvId"); + torture_assert_int_equal(tctx, AvPairs.pair[4].AvId, MsvAvSingleHost, "AvId"); torture_assert_int_equal(tctx, AvPairs.pair[4].AvLen, 48, "AvLen"); - torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.Size, 48, "Value.AvRestrictions.Size"); - torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.Z4, 0, "Value.AvRestrictions.Z4"); - torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.IntegrityLevel, 0, "Value.AvRestrictions.IntegrityLevel"); - torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.SubjectIntegrityLevel, 0x00003000, "Value.AvRestrictions.SubjectIntegrityLevel"); - torture_assert_mem_equal(tctx, AvPairs.pair[4].Value.AvRestrictions.MachineId, MachineId, 32, "Value.AvRestrictions.MachineId"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvSingleHost.Size, 48, "Value.AvSingleHost.Size"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvSingleHost.Z4, 0, "Value.AvSingleHost.Z4"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvSingleHost.token_info.Flags, 0, "Value.AvSingleHost.token_info.Flags"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvSingleHost.token_info.TokenIL, 0x00003000, "Value.AvSingleHost.token_info.TokenIL"); + torture_assert_mem_equal(tctx, AvPairs.pair[4].Value.AvSingleHost.token_info.MachineId, MachineId, 32, "Value.AvSingleHost.token_info.MachineId"); + torture_assert_int_equal(tctx, AvPairs.pair[4].Value.AvSingleHost.remaining.length, 0, "Value.AvSingleHost.remaining.length"); torture_assert_int_equal(tctx, AvPairs.pair[5].AvId, MsvChannelBindings, "AvId"); torture_assert_int_equal(tctx, AvPairs.pair[5].AvLen, 16, "AvLen"); -- 1.9.1 From 8376f34960b98d310471edae2f4bfbc0f599c5f8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Nov 2015 15:38:02 +0100 Subject: [PATCH 059/323] ntlmssp.idl: make AV_PAIR_LIST public MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit f4ff3510164748977de056bb8cdbbd22e5fedb3c) --- librpc/idl/ntlmssp.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/ntlmssp.idl b/librpc/idl/ntlmssp.idl index 5d8a12a..15c700e 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -172,7 +172,7 @@ interface ntlmssp [subcontext(0),subcontext_size(AvLen),switch_is(AvId)] ntlmssp_AvValue Value; } AV_PAIR; - typedef [gensize,nopush,nopull,flag(NDR_NOALIGN)] struct { + typedef [public,gensize,nopush,nopull,flag(NDR_NOALIGN)] struct { uint32 count; AV_PAIR pair[count]; } AV_PAIR_LIST; -- 1.9.1 From 18a94fd5d1ef635750d89bc3e25ca612b242a30e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 15:40:29 +0100 Subject: [PATCH 060/323] librpc/ndr: add ndr_ntlmssp_find_av() helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit c1e2a1f0a75605a8792b615a41392fc018198a10) --- librpc/ndr/ndr_ntlmssp.c | 16 ++++++++++++++++ librpc/ndr/ndr_ntlmssp.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/librpc/ndr/ndr_ntlmssp.c b/librpc/ndr/ndr_ntlmssp.c index d024da5..7027ac0 100644 --- a/librpc/ndr/ndr_ntlmssp.c +++ b/librpc/ndr/ndr_ntlmssp.c @@ -176,4 +176,20 @@ _PUBLIC_ void ndr_print_ntlmssp_Version(struct ndr_print *ndr, const char *name, } } +_PUBLIC_ struct AV_PAIR *ndr_ntlmssp_find_av(const struct AV_PAIR_LIST *av_list, + enum ntlmssp_AvId AvId) +{ + struct AV_PAIR *res = NULL; + uint32_t i = 0; + + for (i = 0; i < av_list->count; i++) { + if (av_list->pair[i].AvId != AvId) { + continue; + } + res = discard_const_p(struct AV_PAIR, &av_list->pair[i]); + break; + } + + return res; +} diff --git a/librpc/ndr/ndr_ntlmssp.h b/librpc/ndr/ndr_ntlmssp.h index e07ff15..5c979ff 100644 --- a/librpc/ndr/ndr_ntlmssp.h +++ b/librpc/ndr/ndr_ntlmssp.h @@ -31,3 +31,5 @@ _PUBLIC_ void ndr_print_ntlmssp_lm_response(TALLOC_CTX *mem_ctx, bool ntlmv2); _PUBLIC_ void ndr_print_ntlmssp_Version(struct ndr_print *ndr, const char *name, const union ntlmssp_Version *r); +_PUBLIC_ struct AV_PAIR *ndr_ntlmssp_find_av(const struct AV_PAIR_LIST *av_list, + enum ntlmssp_AvId AvId); -- 1.9.1 From a075280b168c9ed9ca449380d2745af846440739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Wed, 19 Aug 2009 00:40:12 +0200 Subject: [PATCH 061/323] auth/ntlmssp: use ndr_push_AV_PAIR_LIST in gensec_ntlmssp_server_negotiate(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Günther Deschner BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit f6b9e1feab8d435b1e44fef81e867c01ed01db95) --- auth/ntlmssp/ntlmssp.h | 1 + auth/ntlmssp/ntlmssp_server.c | 43 +++++++++++++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index 4d2ddf9..f1af224 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -82,6 +82,7 @@ struct ntlmssp_state const char *netbios_domain; const char *dns_name; const char *dns_domain; + struct AV_PAIR_LIST av_pair_list; } server; DATA_BLOB internal_chal; /* Random challenge as supplied to the client for NTLM authentication */ diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c index 94692cd..4bb2a64 100644 --- a/auth/ntlmssp/ntlmssp_server.c +++ b/auth/ntlmssp/ntlmssp_server.c @@ -150,16 +150,39 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security cryptkey, 8); /* This creates the 'blob' of names that appears at the end of the packet */ - if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) - { - status = msrpc_gen(ntlmssp_state, &struct_blob, "aaaaa", - MsvAvNbDomainName, target_name, - MsvAvNbComputerName, ntlmssp_state->server.netbios_name, - MsvAvDnsDomainName, ntlmssp_state->server.dns_domain, - MsvAvDnsComputerName, ntlmssp_state->server.dns_name, - MsvAvEOL, ""); - if (!NT_STATUS_IS_OK(status)) { - return status; + if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { + enum ndr_err_code err; + struct AV_PAIR *pairs = NULL; + uint32_t count = 5; + + pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count); + if (pairs == NULL) { + return NT_STATUS_NO_MEMORY; + } + + pairs[0].AvId = MsvAvNbDomainName; + pairs[0].Value.AvNbDomainName = target_name; + + pairs[1].AvId = MsvAvNbComputerName; + pairs[1].Value.AvNbComputerName = ntlmssp_state->server.netbios_name; + + pairs[2].AvId = MsvAvDnsDomainName; + pairs[2].Value.AvDnsDomainName = ntlmssp_state->server.dns_domain; + + pairs[3].AvId = MsvAvDnsComputerName; + pairs[3].Value.AvDnsComputerName= ntlmssp_state->server.dns_name; + + pairs[4].AvId = MsvAvEOL; + + ntlmssp_state->server.av_pair_list.count = count; + ntlmssp_state->server.av_pair_list.pair = pairs; + + err = ndr_push_struct_blob(&struct_blob, + ntlmssp_state, + &ntlmssp_state->server.av_pair_list, + (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST); + if (!NDR_ERR_CODE_IS_SUCCESS(err)) { + return NT_STATUS_NO_MEMORY; } } else { struct_blob = data_blob_null; -- 1.9.1 From afe2efd753aaeba6b58a09eba4a801cc7bce7998 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:48:14 +0100 Subject: [PATCH 062/323] auth/gensec: add GENSEC_FEATURE_LDAP_STYLE define MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will be used for LDAP connections and may trigger backend specific behaviour. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 069aee42c2f12ed5feb23c19dc0a4771d913619a) --- auth/gensec/gensec.h | 1 + 1 file changed, 1 insertion(+) diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h index f09e501..e8bd7b1 100644 --- a/auth/gensec/gensec.h +++ b/auth/gensec/gensec.h @@ -62,6 +62,7 @@ struct gensec_target { #define GENSEC_FEATURE_NEW_SPNEGO 0x00000080 #define GENSEC_FEATURE_UNIX_TOKEN 0x00000100 #define GENSEC_FEATURE_NTLM_CCACHE 0x00000200 +#define GENSEC_FEATURE_LDAP_STYLE 0x00000400 #define GENSEC_EXPIRE_TIME_INFINITY (NTTIME)0x8000000000000000LL -- 1.9.1 From 367f43aa95b2a01b024e815cc0f58aa8b7f9056a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:48:14 +0100 Subject: [PATCH 063/323] auth/ntlmssp: implement GENSEC_FEATURE_LDAP_STYLE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to handle NTLMSSP_NEGOTIATE_SIGN as NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE is requested. This works arround a bug in Windows, which allow signed only messages using NTLMSSP and LDAP. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit f3dbe19e14eaf7a462f14485c6a9138a7348db2e) --- auth/ntlmssp/gensec_ntlmssp_server.c | 9 +++++++++ auth/ntlmssp/ntlmssp.h | 2 ++ auth/ntlmssp/ntlmssp_client.c | 9 +++++++++ auth/ntlmssp/ntlmssp_sign.c | 16 ++++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/auth/ntlmssp/gensec_ntlmssp_server.c b/auth/ntlmssp/gensec_ntlmssp_server.c index 03d539b..5a57413 100644 --- a/auth/ntlmssp/gensec_ntlmssp_server.c +++ b/auth/ntlmssp/gensec_ntlmssp_server.c @@ -153,6 +153,15 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) } if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + + if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) { + /* + * We need to handle NTLMSSP_NEGOTIATE_SIGN as + * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE + * is requested. + */ + ntlmssp_state->force_wrap_seal = true; + } } if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index f1af224..c63c23d 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -94,6 +94,8 @@ struct ntlmssp_state uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */ + bool force_wrap_seal; + union ntlmssp_crypt_state *crypt; }; diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 523a842..652c8f1 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -639,6 +639,15 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) } if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + + if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) { + /* + * We need to handle NTLMSSP_NEGOTIATE_SIGN as + * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE + * is requested. + */ + ntlmssp_state->force_wrap_seal = true; + } } if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; diff --git a/auth/ntlmssp/ntlmssp_sign.c b/auth/ntlmssp/ntlmssp_sign.c index c0be914..743ba2b 100644 --- a/auth/ntlmssp/ntlmssp_sign.c +++ b/auth/ntlmssp/ntlmssp_sign.c @@ -558,6 +558,22 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) return NT_STATUS_NO_MEMORY; } + if (ntlmssp_state->force_wrap_seal && + (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) + { + /* + * We need to handle NTLMSSP_NEGOTIATE_SIGN as + * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE + * is requested. + * + * The negotiation of flags (and authentication) + * is completed when ntlmssp_sign_init() is called + * so we can safely pretent NTLMSSP_NEGOTIATE_SEAL + * was negotiated. + */ + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + } + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { DATA_BLOB weak_session_key = ntlmssp_state->session_key; const char *send_sign_const; -- 1.9.1 From bcc720c5a6ba6125a9220adf9d7a6b9d3ad7576b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:48:14 +0100 Subject: [PATCH 064/323] auth/ntlmssp: add more compat for GENSEC_FEATURE_LDAP_STYLE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want also work against old Samba servers which didn't had GENSEC_FEATURE_LDAP_STYLE we negotiate SEAL too. We may remove this in a few years. As all servers should support GENSEC_FEATURE_LDAP_STYLE by then. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 122a5f6b58e6cead061a7ee64033ccc1940742ed) --- auth/ntlmssp/ntlmssp_client.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 652c8f1..fe9e5d4 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -647,6 +647,14 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) * is requested. */ ntlmssp_state->force_wrap_seal = true; + /* + * We want also work against old Samba servers + * which didn't had GENSEC_FEATURE_LDAP_STYLE + * we negotiate SEAL too. We may remove this + * in a few years. As all servers should have + * GENSEC_FEATURE_LDAP_STYLE by then. + */ + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } } if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { -- 1.9.1 From 7bd7c7c5364f5c7d7a2b316d5fb54992b6c7453f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 8 Mar 2016 12:58:51 +0100 Subject: [PATCH 065/323] auth/ntlmssp: remove ntlmssp_unwrap() fallback for LDAP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is now handled by GENSEC_FEATURE_LDAP_STYLE. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 59301830e27bf537d04808d2ac37d6cf9ef56713) --- auth/ntlmssp/ntlmssp_sign.c | 49 +++++---------------------------------------- 1 file changed, 5 insertions(+), 44 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_sign.c b/auth/ntlmssp/ntlmssp_sign.c index 743ba2b..2f8c6de 100644 --- a/auth/ntlmssp/ntlmssp_sign.c +++ b/auth/ntlmssp/ntlmssp_sign.c @@ -479,57 +479,18 @@ NTSTATUS ntlmssp_unwrap(struct ntlmssp_state *ntlmssp_state, &sig); } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { - NTSTATUS status; - struct ntlmssp_crypt_direction save_direction; - if (in->length < NTLMSSP_SIG_SIZE) { return NT_STATUS_INVALID_PARAMETER; } sig.data = in->data; sig.length = NTLMSSP_SIG_SIZE; - *out = data_blob_talloc(out_mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE); - - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - save_direction = ntlmssp_state->crypt->ntlm2.receiving; - } else { - save_direction = ntlmssp_state->crypt->ntlm; - } - - status = ntlmssp_check_packet(ntlmssp_state, - out->data, out->length, - out->data, out->length, - &sig); - if (!NT_STATUS_IS_OK(status)) { - NTSTATUS check_status = status; - /* - * The Windows LDAP libraries seems to have a bug - * and always use sealing even if only signing was - * negotiated. So we need to fallback. - */ - - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - ntlmssp_state->crypt->ntlm2.receiving = save_direction; - } else { - ntlmssp_state->crypt->ntlm = save_direction; - } - status = ntlmssp_unseal_packet(ntlmssp_state, - out->data, - out->length, - out->data, - out->length, - &sig); - if (NT_STATUS_IS_OK(status)) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; - } else { - status = check_status; - } - } + *out = data_blob_talloc(out_mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("NTLMSSP packet check for unwrap failed due to invalid signature\n")); - } - return status; + return ntlmssp_check_packet(ntlmssp_state, + out->data, out->length, + out->data, out->length, + &sig); } else { *out = data_blob_talloc(out_mem_ctx, in->data, in->length); if (!out->data) { -- 1.9.1 From 620000c928462d91be99c2f2a43c3af9c5229562 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:51:57 +0100 Subject: [PATCH 066/323] s4:libcli/ldap: make use of GENSEC_FEATURE_LDAP_STYLE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit d04663b8b075a69141fe2f45d0906b528d99ab85) --- source4/libcli/ldap/ldap_bind.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 0da49f3..b10b79d 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -318,6 +318,13 @@ try_logon_again: * context, so we don't tatoo it ) */ cli_credentials_set_gensec_features(creds, old_gensec_features); + /* + * This is an indication for the NTLMSSP backend to + * also encrypt when only GENSEC_FEATURE_SIGN is requested + * in gensec_[un]wrap(). + */ + gensec_want_feature(conn->gensec, GENSEC_FEATURE_LDAP_STYLE); + if (conn->host) { status = gensec_set_target_hostname(conn->gensec, conn->host); if (!NT_STATUS_IS_OK(status)) { -- 1.9.1 From 9f0decd7e32c58ea8e2c4e8eed534d3eac0ada16 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 13:10:58 +0100 Subject: [PATCH 067/323] s4:libcli/ldap: fix retry authentication after a bad password MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to start with an empty input buffer. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit d9d0d2d5a2667ea8984772b678272650a8719c21) --- source4/libcli/ldap/ldap_bind.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index b10b79d..d2f4ca7 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -291,6 +291,8 @@ try_logon_again: gensec session. The logon_retries counter ensures we don't loop forever. */ + data_blob_free(&input); + TALLOC_FREE(conn->gensec); status = gensec_client_start(conn, &conn->gensec, lpcfg_gensec_settings(conn, lp_ctx)); @@ -441,8 +443,6 @@ try_logon_again: new credentials, or get a new ticket if using kerberos */ - talloc_free(conn->gensec); - conn->gensec = NULL; goto try_logon_again; } } -- 1.9.1 From 5062c603abebb55c48605c4fddc2056df8d9308b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 09:54:08 +0100 Subject: [PATCH 068/323] s4:selftest: we don't need to run ldap test with --option=socket:testnonblock=true MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LDAP client library uses tstream and that handles non blocking sockets natively. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 5cf8546674a4f49618bdade1567fac00d72db454) --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 3edfcbd..89d1660 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -43,7 +43,7 @@ smbclient4 = binpath('smbclient4') bbdir = os.path.join(srcdir(), "testprogs/blackbox") # Simple tests for LDAP and CLDAP -for options in ['-U"$USERNAME%$PASSWORD" --option=socket:testnonblock=true', '-U"$USERNAME%$PASSWORD"', '-U"$USERNAME%$PASSWORD" -k yes', '-U"$USERNAME%$PASSWORD" -k no', '-U"$USERNAME%$PASSWORD" -k no --sign', '-U"$USERNAME%$PASSWORD" -k no --encrypt', '-U"$USERNAME%$PASSWORD" -k yes --encrypt', '-U"$USERNAME%$PASSWORD" -k yes --sign']: +for options in ['-U"$USERNAME%$PASSWORD"', '-U"$USERNAME%$PASSWORD" -k yes', '-U"$USERNAME%$PASSWORD" -k no', '-U"$USERNAME%$PASSWORD" -k no --sign', '-U"$USERNAME%$PASSWORD" -k no --encrypt', '-U"$USERNAME%$PASSWORD" -k yes --encrypt', '-U"$USERNAME%$PASSWORD" -k yes --sign']: plantestsuite("samba4.ldb.ldap with options %s(ad_dc_ntvfs)" % options, "ad_dc_ntvfs", "%s/test_ldb.sh ldap $SERVER %s" % (bbdir, options)) # see if we support ADS on the Samba3 side -- 1.9.1 From 216ea172346b818879fc3261e7d7fd06a2cb6219 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 11:46:22 +0100 Subject: [PATCH 069/323] s4:selftest: simplify the loops over samba4.ldb.ldap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit c431543fb989938898e33e1ffdb80cb97e4a3bb2) --- source4/selftest/tests.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 89d1660..dc9bed9 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -43,8 +43,11 @@ smbclient4 = binpath('smbclient4') bbdir = os.path.join(srcdir(), "testprogs/blackbox") # Simple tests for LDAP and CLDAP -for options in ['-U"$USERNAME%$PASSWORD"', '-U"$USERNAME%$PASSWORD" -k yes', '-U"$USERNAME%$PASSWORD" -k no', '-U"$USERNAME%$PASSWORD" -k no --sign', '-U"$USERNAME%$PASSWORD" -k no --encrypt', '-U"$USERNAME%$PASSWORD" -k yes --encrypt', '-U"$USERNAME%$PASSWORD" -k yes --sign']: - plantestsuite("samba4.ldb.ldap with options %s(ad_dc_ntvfs)" % options, "ad_dc_ntvfs", "%s/test_ldb.sh ldap $SERVER %s" % (bbdir, options)) +for auth_type in ['', '-k no', '-k yes']: + for auth_level in ['', '--sign', '--encrypt']: + creds = '-U"$USERNAME%$PASSWORD"' + options = creds + ' ' + auth_type + ' ' + auth_level + plantestsuite("samba4.ldb.ldap with options %r(ad_dc_ntvfs)" % options, "ad_dc_ntvfs", "%s/test_ldb.sh ldap $SERVER %s" % (bbdir, options)) # see if we support ADS on the Samba3 side try: -- 1.9.1 From 4a8fff261db0dc6406b8a9f83c03b5abaa4d4d6f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 14:51:57 +0100 Subject: [PATCH 070/323] s4:ldap_server: make use of GENSEC_FEATURE_LDAP_STYLE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit 0ebe929810e922e7cf7742a1f3e4ad222006377f) --- source4/ldap_server/ldap_bind.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c index 69a6b61..fb7a6ed 100644 --- a/source4/ldap_server/ldap_bind.c +++ b/source4/ldap_server/ldap_bind.c @@ -181,6 +181,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call) gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN); gensec_want_feature(conn->gensec, GENSEC_FEATURE_SEAL); gensec_want_feature(conn->gensec, GENSEC_FEATURE_ASYNC_REPLIES); + gensec_want_feature(conn->gensec, GENSEC_FEATURE_LDAP_STYLE); status = gensec_start_mech_by_sasl_name(conn->gensec, req->creds.SASL.mechanism); -- 1.9.1 From 962452a7f0cd6251c414096f129efd6163aab52a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Mar 2016 02:53:45 +0100 Subject: [PATCH 071/323] s3:libads: add missing TALLOC_FREE(frame) in error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 8f9a9633e4f55f85a3f68bf2e8c78414f31511ea) --- source3/libads/sasl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 720ee78..e1dd506 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -46,6 +46,7 @@ static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t } if ((ads->ldap.out.size - 4) < wrapped.length) { + TALLOC_FREE(frame); return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); } -- 1.9.1 From b6d47da891c82630ca74b973e926206c63705453 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 15:04:02 +0100 Subject: [PATCH 072/323] s3:libads: make use of GENSEC_FEATURE_LDAP_STYLE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is more generic and will handle the ntlmssp_[un]wrap() behaviour at the right level. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 357d37fa11b7d944e9f5fe2e0cc6730d498bc2dc) --- source3/libads/sasl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index e1dd506..0251980 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -158,11 +158,11 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) } else { /* * windows servers are broken with sign only, - * so we need to use seal here too + * so we let the NTLMSSP backend to seal here, + * via GENSEC_FEATURE_LDAP_STYLE. */ gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SIGN); - gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SEAL); - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL; + gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_LDAP_STYLE); } break; case ADS_SASLWRAP_TYPE_PLAIN: -- 1.9.1 From a940728f56e991e3a5a7ab1452d7be3d211641c2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 15:02:29 +0100 Subject: [PATCH 073/323] s3:libads: make use of GENSEC_OID_SPNEGO in ads_sasl_spnego_ntlmssp_bind() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids using the hand made spnego code, that doesn't support the GENSEC_FEATURE_NEW_SPNEGO protection. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Reviewed-by: Günther Deschner (cherry picked from commit c6f79cfa86e23217a510c6fe205da0c18ef2a9b2) --- source3/libads/sasl.c | 110 +++++++++++++++++++++----------------------------- 1 file changed, 45 insertions(+), 65 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 0251980..ba33c1d 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -19,6 +19,7 @@ #include "includes.h" #include "../libcli/auth/spnego.h" +#include "auth/credentials/credentials.h" #include "auth/gensec/gensec.h" #include "auth_generic.h" #include "ads.h" @@ -120,16 +121,11 @@ static const struct ads_saslwrap_ops ads_sasl_ntlmssp_ops = { */ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) { - DATA_BLOB msg1 = data_blob_null; - DATA_BLOB blob = data_blob_null; DATA_BLOB blob_in = data_blob_null; DATA_BLOB blob_out = data_blob_null; - struct berval cred, *scred = NULL; int rc; NTSTATUS nt_status; ADS_STATUS status; - int turn = 1; - struct auth_generic_state *auth_generic_state; nt_status = auth_generic_client_prepare(NULL, &auth_generic_state); @@ -147,6 +143,9 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) return ADS_ERROR_NT(nt_status); } + cli_credentials_set_kerberos_state(auth_generic_state->credentials, + CRED_DONT_USE_KERBEROS); + switch (ads->ldap.wrap_type) { case ADS_SASLWRAP_TYPE_SEAL: gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SIGN); @@ -169,87 +168,68 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) break; } - nt_status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP); + nt_status = auth_generic_client_start(auth_generic_state, GENSEC_OID_SPNEGO); if (!NT_STATUS_IS_OK(nt_status)) { return ADS_ERROR_NT(nt_status); } + rc = LDAP_SASL_BIND_IN_PROGRESS; + nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; blob_in = data_blob_null; + blob_out = data_blob_null; + + while (true) { + struct berval cred, *scred = NULL; - do { nt_status = gensec_update(auth_generic_state->gensec_security, talloc_tos(), blob_in, &blob_out); data_blob_free(&blob_in); - if ((NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) - || NT_STATUS_IS_OK(nt_status)) - && blob_out.length) { - if (turn == 1) { - const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL}; - /* and wrap it in a SPNEGO wrapper */ - msg1 = spnego_gen_negTokenInit(talloc_tos(), - OIDs_ntlm, &blob_out, NULL); - } else { - /* wrap it in SPNEGO */ - msg1 = spnego_gen_auth(talloc_tos(), blob_out); - } - + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) + && !NT_STATUS_IS_OK(nt_status)) + { + TALLOC_FREE(auth_generic_state); data_blob_free(&blob_out); + return ADS_ERROR_NT(nt_status); + } - cred.bv_val = (char *)msg1.data; - cred.bv_len = msg1.length; - scred = NULL; - rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); - data_blob_free(&msg1); - if ((rc != LDAP_SASL_BIND_IN_PROGRESS) && (rc != 0)) { - if (scred) { - ber_bvfree(scred); - } + if (NT_STATUS_IS_OK(nt_status) && rc == 0 && blob_out.length == 0) { + break; + } - TALLOC_FREE(auth_generic_state); - return ADS_ERROR(rc); - } + cred.bv_val = (char *)blob_out.data; + cred.bv_len = blob_out.length; + scred = NULL; + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + data_blob_free(&blob_out); + if ((rc != LDAP_SASL_BIND_IN_PROGRESS) && (rc != 0)) { if (scred) { - blob = data_blob(scred->bv_val, scred->bv_len); ber_bvfree(scred); - } else { - blob = data_blob_null; } - } else { - TALLOC_FREE(auth_generic_state); - data_blob_free(&blob_out); - return ADS_ERROR_NT(nt_status); + return ADS_ERROR(rc); } - - if ((turn == 1) && - (rc == LDAP_SASL_BIND_IN_PROGRESS)) { - DATA_BLOB tmp_blob = data_blob_null; - /* the server might give us back two challenges */ - if (!spnego_parse_challenge(talloc_tos(), blob, &blob_in, - &tmp_blob)) { - - TALLOC_FREE(auth_generic_state); - data_blob_free(&blob); - DEBUG(3,("Failed to parse challenges\n")); - return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); - } - data_blob_free(&tmp_blob); - } else if (rc == LDAP_SASL_BIND_IN_PROGRESS) { - if (!spnego_parse_auth_response(talloc_tos(), blob, nt_status, OID_NTLMSSP, - &blob_in)) { - + if (scred) { + blob_in = data_blob_talloc(talloc_tos(), + scred->bv_val, + scred->bv_len); + if (blob_in.length != scred->bv_len) { + ber_bvfree(scred); TALLOC_FREE(auth_generic_state); - data_blob_free(&blob); - DEBUG(3,("Failed to parse auth response\n")); - return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } + ber_bvfree(scred); + } else { + blob_in = data_blob_null; } - data_blob_free(&blob); - data_blob_free(&blob_out); - turn++; - } while (rc == LDAP_SASL_BIND_IN_PROGRESS && !NT_STATUS_IS_OK(nt_status)); - + if (NT_STATUS_IS_OK(nt_status) && rc == 0 && blob_in.length == 0) { + break; + } + } + + data_blob_free(&blob_in); + data_blob_free(&blob_out); + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { size_t max_wrapped = gensec_max_wrapped_size(auth_generic_state->gensec_security); ads->ldap.out.max_unwrapped = gensec_max_input_size(auth_generic_state->gensec_security); -- 1.9.1 From 23292b14eb9a5b64c388e14288985a0326c7fcae Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 13:14:05 +0100 Subject: [PATCH 074/323] s3:libads: provide a generic ads_sasl_spnego_gensec_bind() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It will be possible to use this for more than just NTLMSSP in future. Similar to https://bugzilla.samba.org/show_bug.cgi?id=10288 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 139ce7d8b687cc54560ce353ea6f86a4d2d2ae04) --- source3/libads/sasl.c | 81 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 16 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index ba33c1d..6f1a987 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -29,7 +29,7 @@ #ifdef HAVE_LDAP -static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t len) +static ADS_STATUS ads_sasl_gensec_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t len) { struct gensec_security *gensec_security = talloc_get_type_abort(ads->ldap.wrap_private_data, @@ -62,7 +62,7 @@ static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8_t *buf, uint32_t return ADS_SUCCESS; } -static ADS_STATUS ads_sasl_ntlmssp_unwrap(ADS_STRUCT *ads) +static ADS_STATUS ads_sasl_gensec_unwrap(ADS_STRUCT *ads) { struct gensec_security *gensec_security = talloc_get_type_abort(ads->ldap.wrap_private_data, @@ -96,7 +96,7 @@ static ADS_STATUS ads_sasl_ntlmssp_unwrap(ADS_STRUCT *ads) return ADS_SUCCESS; } -static void ads_sasl_ntlmssp_disconnect(ADS_STRUCT *ads) +static void ads_sasl_gensec_disconnect(ADS_STRUCT *ads) { struct gensec_security *gensec_security = talloc_get_type_abort(ads->ldap.wrap_private_data, @@ -108,18 +108,23 @@ static void ads_sasl_ntlmssp_disconnect(ADS_STRUCT *ads) ads->ldap.wrap_private_data = NULL; } -static const struct ads_saslwrap_ops ads_sasl_ntlmssp_ops = { - .name = "ntlmssp", - .wrap = ads_sasl_ntlmssp_wrap, - .unwrap = ads_sasl_ntlmssp_unwrap, - .disconnect = ads_sasl_ntlmssp_disconnect +static const struct ads_saslwrap_ops ads_sasl_gensec_ops = { + .name = "gensec", + .wrap = ads_sasl_gensec_wrap, + .unwrap = ads_sasl_gensec_unwrap, + .disconnect = ads_sasl_gensec_disconnect }; /* - perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can + perform a LDAP/SASL/SPNEGO/{NTLMSSP,KRB5} bind (just how many layers can we fit on one socket??) */ -static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) +static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads, + const char *sasl, + enum credentials_use_kerberos krb5_state, + const char *target_service, + const char *target_hostname, + const DATA_BLOB server_blob) { DATA_BLOB blob_in = data_blob_null; DATA_BLOB blob_out = data_blob_null; @@ -127,6 +132,8 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) NTSTATUS nt_status; ADS_STATUS status; struct auth_generic_state *auth_generic_state; + bool use_spnego_principal = lp_client_use_spnego_principal(); + const char *sasl_list[] = { sasl, NULL }; nt_status = auth_generic_client_prepare(NULL, &auth_generic_state); if (!NT_STATUS_IS_OK(nt_status)) { @@ -143,8 +150,38 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) return ADS_ERROR_NT(nt_status); } + if (server_blob.length == 0) { + use_spnego_principal = false; + } + + if (krb5_state == CRED_DONT_USE_KERBEROS) { + use_spnego_principal = false; + } + cli_credentials_set_kerberos_state(auth_generic_state->credentials, - CRED_DONT_USE_KERBEROS); + krb5_state); + + if (target_service != NULL) { + nt_status = gensec_set_target_service( + auth_generic_state->gensec_security, + target_service); + if (!NT_STATUS_IS_OK(nt_status)) { + return ADS_ERROR_NT(nt_status); + } + } + + if (target_hostname != NULL) { + nt_status = gensec_set_target_hostname( + auth_generic_state->gensec_security, + target_hostname); + if (!NT_STATUS_IS_OK(nt_status)) { + return ADS_ERROR_NT(nt_status); + } + } + + if (target_service != NULL && target_hostname != NULL) { + use_spnego_principal = false; + } switch (ads->ldap.wrap_type) { case ADS_SASLWRAP_TYPE_SEAL: @@ -168,14 +205,23 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) break; } - nt_status = auth_generic_client_start(auth_generic_state, GENSEC_OID_SPNEGO); + nt_status = auth_generic_client_start_by_sasl(auth_generic_state, + sasl_list); if (!NT_STATUS_IS_OK(nt_status)) { return ADS_ERROR_NT(nt_status); } rc = LDAP_SASL_BIND_IN_PROGRESS; nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; - blob_in = data_blob_null; + if (use_spnego_principal) { + blob_in = data_blob_dup_talloc(talloc_tos(), server_blob); + if (blob_in.length == 0) { + TALLOC_FREE(auth_generic_state); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + } else { + blob_in = data_blob_null; + } blob_out = data_blob_null; while (true) { @@ -199,7 +245,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) cred.bv_val = (char *)blob_out.data; cred.bv_len = blob_out.length; scred = NULL; - rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); + rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, sasl, &cred, NULL, NULL, &scred); data_blob_free(&blob_out); if ((rc != LDAP_SASL_BIND_IN_PROGRESS) && (rc != 0)) { if (scred) { @@ -237,7 +283,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) ads->ldap.out.sig_size = max_wrapped - ads->ldap.out.max_unwrapped; ads->ldap.in.min_wrapped = ads->ldap.out.sig_size; ads->ldap.in.max_wrapped = max_wrapped; - status = ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, auth_generic_state->gensec_security); + status = ads_setup_sasl_wrapping(ads, &ads_sasl_gensec_ops, auth_generic_state->gensec_security); if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", ads_errstr(status))); @@ -1024,7 +1070,10 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) /* lets do NTLMSSP ... this has the big advantage that we don't need to sync clocks, and we don't rely on special versions of the krb5 library for HMAC_MD4 encryption */ - return ads_sasl_spnego_ntlmssp_bind(ads); + return ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", + CRED_DONT_USE_KERBEROS, + NULL, NULL, + data_blob_null); failed: return status; -- 1.9.1 From ecb1570815618951b27e1eb0f88b1c4ee1a0e410 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 11:31:01 +0100 Subject: [PATCH 075/323] s3:libads: don't pass given_principal to ads_generate_service_principal() anymore. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 0c204e11925982d8bd835830985479792b8cc820) --- source3/libads/sasl.c | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 6f1a987..65d3cc1 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -858,7 +858,6 @@ out: } static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, - const char *given_principal, struct ads_service_principal *p) { ADS_STATUS status; @@ -873,27 +872,9 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, ZERO_STRUCTP(p); - /* I've seen a child Windows 2000 domain not send - the principal name back in the first round of - the SASL bind reply. So we guess based on server - name and realm. --jerry */ - /* Also try best guess when we get the w2k8 ignore principal - back, or when we are configured to ignore it - gd, - abartlet */ - - if (!lp_client_use_spnego_principal() || - !given_principal || - strequal(given_principal, ADS_IGNORE_PRINCIPAL)) { - - status = ads_guess_service_principal(ads, &p->string); - if (!ADS_ERR_OK(status)) { - return status; - } - } else { - p->string = SMB_STRDUP(given_principal); - if (!p->string) { - return ADS_ERROR(LDAP_NO_MEMORY); - } + status = ads_guess_service_principal(ads, &p->string); + if (!ADS_ERR_OK(status)) { + return status; } #ifdef HAVE_KRB5 @@ -1008,6 +989,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) goto failed; } data_blob_free(&blob); + TALLOC_FREE(given_principal); /* make sure the server understands kerberos */ for (i=0;OIDs[i];i++) { @@ -1020,7 +1002,6 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #endif talloc_free(OIDs[i]); } - DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", given_principal)); #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && @@ -1028,8 +1009,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) { struct ads_service_principal p; - status = ads_generate_service_principal(ads, given_principal, &p); - TALLOC_FREE(given_principal); + status = ads_generate_service_principal(ads, &p); if (!ADS_ERR_OK(status)) { return status; } @@ -1061,11 +1041,8 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { return status; } - } else -#endif - { - TALLOC_FREE(given_principal); } +#endif /* lets do NTLMSSP ... this has the big advantage that we don't need to sync clocks, and we don't rely on special versions of the krb5 @@ -1297,7 +1274,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ADS_STATUS status; struct ads_service_principal p; - status = ads_generate_service_principal(ads, NULL, &p); + status = ads_generate_service_principal(ads, &p); if (!ADS_ERR_OK(status)) { return status; } -- 1.9.1 From 62c4d3559808e650ebba4b04f169420c4b806f5c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 11:33:04 +0100 Subject: [PATCH 076/323] s3:libads: keep service and hostname separately in ads_service_principal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caller will use them instead of the full principal in future. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit c5d7956364047925dee5d6f71a5b92a38c73e5a6) --- source3/libads/sasl.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 65d3cc1..5d47fd4 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -742,14 +742,18 @@ failed: #ifdef HAVE_KRB5 struct ads_service_principal { - char *string; + char *service; + char *hostname; + char *string; #ifdef HAVE_KRB5 - gss_name_t name; + gss_name_t name; #endif }; static void ads_free_service_principal(struct ads_service_principal *p) { + SAFE_FREE(p->service); + SAFE_FREE(p->hostname); SAFE_FREE(p->string); #ifdef HAVE_KRB5 @@ -761,9 +765,10 @@ static void ads_free_service_principal(struct ads_service_principal *p) ZERO_STRUCTP(p); } - -static ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads, - char **returned_principal) +static ADS_STATUS ads_guess_target(ADS_STRUCT *ads, + char **service, + char **hostname, + char **principal) { ADS_STATUS status = ADS_ERROR(LDAP_NO_MEMORY); char *princ = NULL; @@ -843,13 +848,26 @@ static ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads, goto out; } + *service = SMB_STRDUP("ldap"); + if (*service == NULL) { + status = ADS_ERROR(LDAP_PARAM_ERROR); + goto out; + } + *hostname = SMB_STRDUP(server); + if (*hostname == NULL) { + SAFE_FREE(*service); + status = ADS_ERROR(LDAP_PARAM_ERROR); + goto out; + } rc = asprintf(&princ, "ldap/%s@%s", server, realm); if (rc == -1 || princ == NULL) { + SAFE_FREE(*service); + SAFE_FREE(*hostname); status = ADS_ERROR(LDAP_PARAM_ERROR); goto out; } - *returned_principal = princ; + *principal = princ; status = ADS_SUCCESS; out: @@ -872,7 +890,10 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, ZERO_STRUCTP(p); - status = ads_guess_service_principal(ads, &p->string); + status = ads_guess_target(ads, + &p->service, + &p->hostname, + &p->string); if (!ADS_ERR_OK(status)) { return status; } -- 1.9.1 From 5b626817c353145a3afec4029fda7b347eca16b6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 11:42:51 +0100 Subject: [PATCH 077/323] s3:libads: make use of ads_sasl_spnego_gensec_bind() for GSS-SPNEGO with Kerberos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 2cb07ba50decdfd6d08271cd2b3d893ff95f5af9) --- source3/libads/sasl.c | 384 ++++---------------------------------------------- 1 file changed, 28 insertions(+), 356 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 5d47fd4..e707228 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -464,280 +464,6 @@ static const struct ads_saslwrap_ops ads_sasl_gssapi_ops = { .disconnect = ads_sasl_gssapi_disconnect }; -/* - perform a LDAP/SASL/SPNEGO/GSSKRB5 bind -*/ -static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t serv_name) -{ - ADS_STATUS status; - bool ok; - uint32_t minor_status; - int gss_rc, rc; - gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL; - gss_OID_desc krb5_mech_type = - {9, discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") }; - gss_OID mech_type = &krb5_mech_type; - gss_OID actual_mech_type = GSS_C_NULL_OID; - const char *spnego_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, OID_NTLMSSP, NULL}; - gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; - gss_buffer_desc input_token, output_token; - uint32_t req_flags, ret_flags; - uint32_t req_tmp, ret_tmp; - DATA_BLOB unwrapped; - DATA_BLOB wrapped; - struct berval cred, *scred = NULL; - uint32_t context_validity = 0; - time_t context_endtime = 0; - - status = ads_init_gssapi_cred(ads, &gss_cred); - if (!ADS_ERR_OK(status)) { - goto failed; - } - - input_token.value = NULL; - input_token.length = 0; - - req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; - switch (ads->ldap.wrap_type) { - case ADS_SASLWRAP_TYPE_SEAL: - req_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG; - break; - case ADS_SASLWRAP_TYPE_SIGN: - req_flags |= GSS_C_INTEG_FLAG; - break; - case ADS_SASLWRAP_TYPE_PLAIN: - break; - } - - /* Note: here we explicit ask for the krb5 mech_type */ - gss_rc = gss_init_sec_context(&minor_status, - gss_cred, - &context_handle, - serv_name, - mech_type, - req_flags, - 0, - NULL, - &input_token, - &actual_mech_type, - &output_token, - &ret_flags, - NULL); - if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) { - status = ADS_ERROR_GSS(gss_rc, minor_status); - goto failed; - } - - /* - * As some gssapi krb5 mech implementations - * automaticly add GSS_C_INTEG_FLAG and GSS_C_CONF_FLAG - * to req_flags internaly, it's not possible to - * use plain or signing only connection via - * the gssapi interface. - * - * Because of this we need to check it the ret_flags - * has more flags as req_flags and correct the value - * of ads->ldap.wrap_type. - * - * I ads->auth.flags has ADS_AUTH_SASL_FORCE - * we need to give an error. - */ - req_tmp = req_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); - ret_tmp = ret_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); - - if (req_tmp == ret_tmp) { - /* everythings fine... */ - - } else if (req_flags & GSS_C_CONF_FLAG) { - /* - * here we wanted sealing but didn't got it - * from the gssapi library - */ - status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); - goto failed; - - } else if ((req_flags & GSS_C_INTEG_FLAG) && - !(ret_flags & GSS_C_INTEG_FLAG)) { - /* - * here we wanted siging but didn't got it - * from the gssapi library - */ - status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); - goto failed; - - } else if (ret_flags & GSS_C_CONF_FLAG) { - /* - * here we didn't want sealing - * but the gssapi library forces it - * so correct the needed wrap_type if - * the caller didn't forced siging only - */ - if (ads->auth.flags & ADS_AUTH_SASL_FORCE) { - status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); - goto failed; - } - - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL; - req_flags = ret_flags; - - } else if (ret_flags & GSS_C_INTEG_FLAG) { - /* - * here we didn't want signing - * but the gssapi library forces it - * so correct the needed wrap_type if - * the caller didn't forced plain - */ - if (ads->auth.flags & ADS_AUTH_SASL_FORCE) { - status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); - goto failed; - } - - ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SIGN; - req_flags = ret_flags; - } else { - /* - * This could (should?) not happen - */ - status = ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); - goto failed; - - } - - /* and wrap that in a shiny SPNEGO wrapper */ - unwrapped = data_blob_const(output_token.value, output_token.length); - wrapped = spnego_gen_negTokenInit(talloc_tos(), - spnego_mechs, &unwrapped, NULL); - gss_release_buffer(&minor_status, &output_token); - if (unwrapped.length > wrapped.length) { - status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - goto failed; - } - - cred.bv_val = (char *)wrapped.data; - cred.bv_len = wrapped.length; - - rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, - &scred); - data_blob_free(&wrapped); - if (rc != LDAP_SUCCESS) { - status = ADS_ERROR(rc); - goto failed; - } - - if (scred) { - wrapped = data_blob_const(scred->bv_val, scred->bv_len); - } else { - wrapped = data_blob_null; - } - - ok = spnego_parse_auth_response(talloc_tos(), wrapped, NT_STATUS_OK, - OID_KERBEROS5_OLD, - &unwrapped); - if (scred) ber_bvfree(scred); - if (!ok) { - status = ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); - goto failed; - } - - input_token.value = unwrapped.data; - input_token.length = unwrapped.length; - - /* - * As we asked for mutal authentication - * we need to pass the servers response - * to gssapi - */ - gss_rc = gss_init_sec_context(&minor_status, - gss_cred, - &context_handle, - serv_name, - mech_type, - req_flags, - 0, - NULL, - &input_token, - &actual_mech_type, - &output_token, - &ret_flags, - NULL); - data_blob_free(&unwrapped); - if (gss_rc) { - status = ADS_ERROR_GSS(gss_rc, minor_status); - goto failed; - } - - gss_release_buffer(&minor_status, &output_token); - - /* - * If we the sign and seal options - * doesn't match after getting the response - * from the server, we don't want to use the connection - */ - req_tmp = req_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); - ret_tmp = ret_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG); - - if (req_tmp != ret_tmp) { - /* everythings fine... */ - status = ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); - goto failed; - } - - gss_rc = - gss_context_time(&minor_status, context_handle, &context_validity); - if (gss_rc == GSS_S_COMPLETE) { - if (context_validity != 0) { - context_endtime = time(NULL) + context_validity; - DEBUG(10, ("context (service ticket) valid for " - "%u seconds\n", - context_validity)); - } else { - DEBUG(10, ("context (service ticket) expired\n")); - } - } else { - DEBUG(1, ("gss_context_time failed (%d,%u) -" - " this will be a one-time context\n", - gss_rc, minor_status)); - if (gss_rc == GSS_S_CONTEXT_EXPIRED) { - DEBUG(10, ("context (service ticket) expired\n")); - } - } - - if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { - uint32_t max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED; - - gss_rc = gss_wrap_size_limit(&minor_status, context_handle, - (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL), - GSS_C_QOP_DEFAULT, - max_msg_size, &ads->ldap.out.max_unwrapped); - if (gss_rc) { - status = ADS_ERROR_GSS(gss_rc, minor_status); - goto failed; - } - - ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max_unwrapped; - ads->ldap.in.min_wrapped = 0x2C; /* taken from a capture with LDAP unbind */ - ads->ldap.in.max_wrapped = max_msg_size; - status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle); - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", - ads_errstr(status))); - goto failed; - } - /* make sure we don't free context_handle */ - context_handle = GSS_C_NO_CONTEXT; - } - - ads->auth.tgs_expire = context_endtime; - status = ADS_SUCCESS; - -failed: - if (gss_cred != GSS_C_NO_CREDENTIAL) - gss_release_cred(&minor_status, &gss_cred); - if (context_handle != GSS_C_NO_CONTEXT) - gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER); - return status; -} - #endif /* HAVE_KRB5 */ #ifdef HAVE_KRB5 @@ -912,63 +638,6 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, return ADS_SUCCESS; } -/* - perform a LDAP/SASL/SPNEGO/KRB5 bind -*/ -static ADS_STATUS ads_sasl_spnego_rawkrb5_bind(ADS_STRUCT *ads, const char *principal) -{ - DATA_BLOB blob = data_blob_null; - struct berval cred, *scred = NULL; - DATA_BLOB session_key = data_blob_null; - int rc; - - if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { - return ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); - } - - rc = spnego_gen_krb5_negTokenInit(talloc_tos(), principal, - ads->auth.time_offset, &blob, &session_key, 0, - ads->auth.ccache_name, - &ads->auth.tgs_expire); - - if (rc) { - return ADS_ERROR_KRB5(rc); - } - - /* now send the auth packet and we should be done */ - cred.bv_val = (char *)blob.data; - cred.bv_len = blob.length; - - rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); - - data_blob_free(&blob); - data_blob_free(&session_key); - if(scred) - ber_bvfree(scred); - - return ADS_ERROR(rc); -} - -static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, - struct ads_service_principal *p) -{ -#ifdef HAVE_KRB5 - /* - * we only use the gsskrb5 based implementation - * when sasl sign or seal is requested. - * - * This has the following reasons: - * - it's likely that the gssapi krb5 mech implementation - * doesn't support to negotiate plain connections - * - the ads_sasl_spnego_rawkrb5_bind is more robust - * against clock skew errors - */ - if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { - return ads_sasl_spnego_gsskrb5_bind(ads, p->name); - } -#endif - return ads_sasl_spnego_rawkrb5_bind(ads, p->string); -} #endif /* HAVE_KRB5 */ /* @@ -976,6 +645,8 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, */ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) { + TALLOC_CTX *frame = talloc_stackframe(); + struct ads_service_principal p; struct berval *scred=NULL; int rc, i; ADS_STATUS status; @@ -990,7 +661,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) if (rc != LDAP_SASL_BIND_IN_PROGRESS) { status = ADS_ERROR(rc); - goto failed; + goto done; } blob = data_blob(scred->bv_val, scred->bv_len); @@ -1005,11 +676,9 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) reply */ if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &given_principal, NULL) || OIDs[0] == NULL) { - data_blob_free(&blob); status = ADS_ERROR(LDAP_OPERATIONS_ERROR); - goto failed; + goto done; } - data_blob_free(&blob); TALLOC_FREE(given_principal); /* make sure the server understands kerberos */ @@ -1024,43 +693,45 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) talloc_free(OIDs[i]); } + status = ads_generate_service_principal(ads, &p); + if (!ADS_ERR_OK(status)) { + goto done; + } + #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && got_kerberos_mechanism) { - struct ads_service_principal p; - - status = ads_generate_service_principal(ads, &p); - if (!ADS_ERR_OK(status)) { - return status; - } - - status = ads_sasl_spnego_krb5_bind(ads, &p); + status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", + CRED_MUST_USE_KERBEROS, + p.service, p.hostname, + blob); if (ADS_ERR_OK(status)) { ads_free_service_principal(&p); - return status; + goto done; } - DEBUG(10,("ads_sasl_spnego_krb5_bind failed with: %s, " + DEBUG(10,("ads_sasl_spnego_gensec_bind(KRB5) failed with: %s, " "calling kinit\n", ads_errstr(status))); status = ADS_ERROR_KRB5(ads_kinit_password(ads)); if (ADS_ERR_OK(status)) { - status = ads_sasl_spnego_krb5_bind(ads, &p); + status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", + CRED_MUST_USE_KERBEROS, + p.service, p.hostname, + blob); if (!ADS_ERR_OK(status)) { DEBUG(0,("kinit succeeded but " - "ads_sasl_spnego_krb5_bind failed: %s\n", + "ads_sasl_spnego_gensec_bind(KRB5) failed: %s\n", ads_errstr(status))); } } - ads_free_service_principal(&p); - /* only fallback to NTLMSSP if allowed */ if (ADS_ERR_OK(status) || !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { - return status; + goto done; } } #endif @@ -1068,12 +739,13 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) /* lets do NTLMSSP ... this has the big advantage that we don't need to sync clocks, and we don't rely on special versions of the krb5 library for HMAC_MD4 encryption */ - return ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", - CRED_DONT_USE_KERBEROS, - NULL, NULL, - data_blob_null); - -failed: + status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", + CRED_DONT_USE_KERBEROS, + p.service, p.hostname, + data_blob_null); +done: + ads_free_service_principal(&p); + TALLOC_FREE(frame); return status; } -- 1.9.1 From 2e2a18610af75670b95cd26286fad7f10490e92a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Nov 2015 14:34:46 +0100 Subject: [PATCH 078/323] s3:libsmb: make use gensec based SPNEGO/NTLMSSP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pares a fix for https://bugzilla.samba.org/show_bug.cgi?id=10288 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 4f6fe27c7020822dd1ce88b7dd63725d6082b190) --- source3/libsmb/cliconnect.c | 179 +++++++++++++++++++++++--------------------- 1 file changed, 95 insertions(+), 84 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 530f5c3..e71b8cb 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -26,7 +26,10 @@ #include "../libcli/auth/libcli_auth.h" #include "../libcli/auth/spnego.h" #include "smb_krb5.h" -#include "../auth/ntlmssp/ntlmssp.h" +#include "auth/credentials/credentials.h" +#include "auth/gensec/gensec.h" +#include "auth/ntlmssp/ntlmssp.h" +#include "auth_generic.h" #include "libads/kerberos_proto.h" #include "krb5_env.h" #include "../lib/util/tevent_ntstatus.h" @@ -1414,17 +1417,18 @@ static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req) struct cli_session_setup_ntlmssp_state { struct tevent_context *ev; struct cli_state *cli; - struct ntlmssp_state *ntlmssp_state; - int turn; + struct auth_generic_state *auth_generic; + bool is_anonymous; + DATA_BLOB blob_in; DATA_BLOB blob_out; + DATA_BLOB session_key; }; static int cli_session_setup_ntlmssp_state_destructor( struct cli_session_setup_ntlmssp_state *state) { - if (state->ntlmssp_state != NULL) { - TALLOC_FREE(state->ntlmssp_state); - } + TALLOC_FREE(state->auth_generic); + data_blob_clear_free(&state->session_key); return 0; } @@ -1437,8 +1441,6 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( struct tevent_req *req, *subreq; struct cli_session_setup_ntlmssp_state *state; NTSTATUS status; - DATA_BLOB blob_out; - const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL}; req = tevent_req_create(mem_ctx, &state, struct cli_session_setup_ntlmssp_state); @@ -1447,51 +1449,85 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( } state->ev = ev; state->cli = cli; - state->turn = 1; - state->ntlmssp_state = NULL; talloc_set_destructor( state, cli_session_setup_ntlmssp_state_destructor); - status = ntlmssp_client_start(state, - lp_netbios_name(), - lp_workgroup(), - lp_client_ntlmv2_auth(), - &state->ntlmssp_state); - if (!NT_STATUS_IS_OK(status)) { - goto fail; + status = auth_generic_client_prepare(state, &state->auth_generic); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); } - ntlmssp_want_feature(state->ntlmssp_state, - NTLMSSP_FEATURE_SESSION_KEY); + + gensec_want_feature(state->auth_generic->gensec_security, + GENSEC_FEATURE_SESSION_KEY); if (cli->use_ccache) { - ntlmssp_want_feature(state->ntlmssp_state, - NTLMSSP_FEATURE_CCACHE); + gensec_want_feature(state->auth_generic->gensec_security, + GENSEC_FEATURE_NTLM_CCACHE); + if (pass != NULL && strlen(pass) == 0) { + /* + * some callers pass "" as no password + * + * GENSEC_FEATURE_NTLM_CCACHE only handles + * NULL as no password. + */ + pass = NULL; + } } - status = ntlmssp_set_username(state->ntlmssp_state, user); - if (!NT_STATUS_IS_OK(status)) { - goto fail; + + status = auth_generic_set_username(state->auth_generic, user); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); } - status = ntlmssp_set_domain(state->ntlmssp_state, domain); - if (!NT_STATUS_IS_OK(status)) { - goto fail; + + status = auth_generic_set_domain(state->auth_generic, domain); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); } + if (cli->pw_nt_hash) { - status = ntlmssp_set_password_hash(state->ntlmssp_state, pass); + struct samr_Password nt_hash; + size_t converted; + bool ok; + + converted = strhex_to_str((char *)nt_hash.hash, + sizeof(nt_hash.hash), + pass, strlen(pass)); + if (converted != sizeof(nt_hash.hash)) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); + return tevent_req_post(req, ev); + } + + ok = cli_credentials_set_nt_hash(state->auth_generic->credentials, + &nt_hash, CRED_SPECIFIED); + if (!ok) { + tevent_req_oom(req); + return tevent_req_post(req, ev); + } } else { - status = ntlmssp_set_password(state->ntlmssp_state, pass); + status = auth_generic_set_password(state->auth_generic, pass); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } } - if (!NT_STATUS_IS_OK(status)) { - goto fail; + + cli_credentials_set_kerberos_state(state->auth_generic->credentials, + CRED_DONT_USE_KERBEROS); + + state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials); + + status = auth_generic_client_start(state->auth_generic, + GENSEC_OID_SPNEGO); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); } - status = ntlmssp_update(state->ntlmssp_state, data_blob_null, - &blob_out); + + status = gensec_update(state->auth_generic->gensec_security, + state, state->blob_in, &state->blob_out); if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - goto fail; + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); } - state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL); - data_blob_free(&blob_out); - if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { state->cli->smb2.session = smbXcli_session_create(cli, cli->conn); @@ -1506,9 +1542,6 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( } tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req); return req; -fail: - tevent_req_nterror(req, status); - return tevent_req_post(req, ev); } static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) @@ -1517,32 +1550,41 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) subreq, struct tevent_req); struct cli_session_setup_ntlmssp_state *state = tevent_req_data( req, struct cli_session_setup_ntlmssp_state); - DATA_BLOB blob_in, msg_in, blob_out; uint8_t *inbuf = NULL; struct iovec *recv_iov = NULL; - bool parse_ret; NTSTATUS status; - status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in, + status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in, &inbuf, &recv_iov); TALLOC_FREE(subreq); data_blob_free(&state->blob_out); if (NT_STATUS_IS_OK(status)) { - if (state->cli->server_domain[0] == '\0') { + const char *server_domain = NULL; + + server_domain = gensec_ntlmssp_server_domain( + state->auth_generic->gensec_security); + + if (state->cli->server_domain[0] == '\0' && server_domain != NULL) { TALLOC_FREE(state->cli->server_domain); state->cli->server_domain = talloc_strdup(state->cli, - state->ntlmssp_state->server.netbios_domain); + server_domain); if (state->cli->server_domain == NULL) { tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } } + status = gensec_session_key(state->auth_generic->gensec_security, + state, &state->session_key); + if (tevent_req_nterror(req, status)) { + return; + } + if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { struct smbXcli_session *session = state->cli->smb2.session; - if (ntlmssp_is_anonymous(state->ntlmssp_state)) { + if (state->is_anonymous) { /* * Windows server does not set the * SMB2_SESSION_FLAG_IS_GUEST nor @@ -1552,13 +1594,12 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) * to verify a signature on the final * session setup response. */ - TALLOC_FREE(state->ntlmssp_state); tevent_req_done(req); return; } status = smb2cli_session_set_session_key(session, - state->ntlmssp_state->session_key, + state->session_key, recv_iov); if (tevent_req_nterror(req, status)) { return; @@ -1567,20 +1608,19 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) struct smbXcli_session *session = state->cli->smb1.session; status = smb1cli_session_set_session_key(session, - state->ntlmssp_state->session_key); + state->session_key); if (tevent_req_nterror(req, status)) { return; } if (smb1cli_conn_activate_signing( - state->cli->conn, state->ntlmssp_state->session_key, + state->cli->conn, state->session_key, data_blob_null) && !smb1cli_conn_check_signing(state->cli->conn, inbuf, 1)) { tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); return; } } - TALLOC_FREE(state->ntlmssp_state); tevent_req_done(req); return; } @@ -1589,49 +1629,20 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) return; } - if (blob_in.length == 0) { + if (state->blob_in.length == 0) { tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); return; } - if ((state->turn == 1) - && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DATA_BLOB tmp_blob = data_blob_null; - /* the server might give us back two challenges */ - parse_ret = spnego_parse_challenge(state, blob_in, &msg_in, - &tmp_blob); - data_blob_free(&tmp_blob); - } else { - parse_ret = spnego_parse_auth_response(state, blob_in, status, - OID_NTLMSSP, &msg_in); - } - state->turn += 1; - - if (!parse_ret) { - DEBUG(3,("Failed to parse auth response\n")); - if (NT_STATUS_IS_OK(status) - || NT_STATUS_EQUAL(status, - NT_STATUS_MORE_PROCESSING_REQUIRED)) { - tevent_req_nterror( - req, NT_STATUS_INVALID_NETWORK_RESPONSE); - return; - } - } - - status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out); - + status = gensec_update(state->auth_generic->gensec_security, + state, state->blob_in, &state->blob_out); + data_blob_free(&state->blob_in); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - TALLOC_FREE(state->ntlmssp_state); tevent_req_nterror(req, status); return; } - state->blob_out = spnego_gen_auth(state, blob_out); - if (tevent_req_nomem(state->blob_out.data, req)) { - return; - } - subreq = cli_sesssetup_blob_send(state, state->ev, state->cli, state->blob_out); if (tevent_req_nomem(subreq, req)) { -- 1.9.1 From 7887485f4c8116ac474b2a00d0fbdfec482c4f70 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 11:49:37 +0100 Subject: [PATCH 079/323] s3:libsmb: unused ntlmssp.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Everything uses the top level ntlmssp code via gensec now. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit afffe797547a97ec839913e1ca89045989bbea49) --- source3/include/proto.h | 25 -- source3/libsmb/ntlmssp.c | 765 ----------------------------------------------- source3/wscript_build | 9 +- 3 files changed, 2 insertions(+), 797 deletions(-) delete mode 100644 source3/libsmb/ntlmssp.c diff --git a/source3/include/proto.h b/source3/include/proto.h index e18aaf4..f6e9b77 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -862,31 +862,6 @@ bool get_dc_name(const char *domain, fstring srv_name, struct sockaddr_storage *ss_out); -/* The following definitions come from libsmb/ntlmssp.c */ -struct ntlmssp_state; -NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) ; -NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password) ; -NTSTATUS ntlmssp_set_password_hash(struct ntlmssp_state *ntlmssp_state, - const char *hash); -NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) ; -void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list); -void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature); -NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, - const DATA_BLOB in, DATA_BLOB *out) ; -bool ntlmssp_is_anonymous(struct ntlmssp_state *ntlmssp_state); -NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, - bool is_standalone, - const char *netbios_name, - const char *netbios_domain, - const char *dns_name, - const char *dns_domain, - struct ntlmssp_state **ntlmssp_state); -NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, - const char *netbios_name, - const char *netbios_domain, - bool use_ntlmv2, - struct ntlmssp_state **_ntlmssp_state); - /* The following definitions come from libsmb/passchange.c */ NTSTATUS remote_password_change(const char *remote_machine, const char *user_name, diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c deleted file mode 100644 index e661aeb..0000000 --- a/source3/libsmb/ntlmssp.c +++ /dev/null @@ -1,765 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 3.0 - handle NLTMSSP, server side - - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Andrew Bartlett 2001-2010 - Copyright (C) Stefan Metzmacher 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "../auth/ntlmssp/ntlmssp.h" -#include "../auth/ntlmssp/ntlmssp_private.h" -#include "../libcli/auth/libcli_auth.h" -#include "../librpc/gen_ndr/ndr_ntlmssp.h" -#include "../auth/ntlmssp/ntlmssp_ndr.h" -#include "../lib/crypto/md5.h" -#include "../lib/crypto/arcfour.h" -#include "../lib/crypto/hmacmd5.h" -#include "../nsswitch/libwbclient/wbclient.h" - -static NTSTATUS ntlmssp3_client_initial(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - DATA_BLOB reply, DATA_BLOB *next_request); -static NTSTATUS ntlmssp3_client_challenge(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, /* Unused at this time */ - const DATA_BLOB reply, DATA_BLOB *next_request); -/** - * Callbacks for NTLMSSP - for both client and server operating modes - * - */ - -static const struct ntlmssp_callbacks { - enum ntlmssp_role role; - enum ntlmssp_message_type ntlmssp_command; - NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - DATA_BLOB in, DATA_BLOB *out); -} ntlmssp_callbacks[] = { - {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp3_client_initial}, - {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp3_client_challenge}, - {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL}, - {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL} -}; - -/** - * Set a username on an NTLMSSP context - ensures it is talloc()ed - * - */ - -NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) -{ - ntlmssp_state->user = talloc_strdup(ntlmssp_state, user ? user : "" ); - if (!ntlmssp_state->user) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Converts a password to the hashes on an NTLMSSP context. - * - */ -NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password) -{ - uint8_t lm_hash[16]; - uint8_t nt_hash[16]; - - TALLOC_FREE(ntlmssp_state->lm_hash); - TALLOC_FREE(ntlmssp_state->nt_hash); - - if (password == NULL) { - return NT_STATUS_OK; - } - - if (E_deshash(password, lm_hash)) { - ntlmssp_state->lm_hash = (uint8_t *) - talloc_memdup(ntlmssp_state, lm_hash, 16); - if (!ntlmssp_state->lm_hash) { - return NT_STATUS_NO_MEMORY; - } - } - - E_md4hash(password, nt_hash); - - ntlmssp_state->nt_hash = (uint8_t *) - talloc_memdup(ntlmssp_state, nt_hash, 16); - if (!ntlmssp_state->nt_hash) { - TALLOC_FREE(ntlmssp_state->lm_hash); - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_set_password_hash(struct ntlmssp_state *state, - const char *pwhash) -{ - char nt_hash[16]; - size_t converted; - - converted = strhex_to_str( - nt_hash, sizeof(nt_hash), pwhash, strlen(pwhash)); - if (converted != sizeof(nt_hash)) { - return NT_STATUS_INVALID_PARAMETER; - } - - TALLOC_FREE(state->lm_hash); - TALLOC_FREE(state->nt_hash); - - state->nt_hash = (uint8_t *)talloc_memdup(state, nt_hash, 16); - if (!state->nt_hash) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Set a domain on an NTLMSSP context - ensures it is talloc()ed - * - */ -NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) -{ - ntlmssp_state->domain = talloc_strdup(ntlmssp_state, - domain ? domain : "" ); - if (!ntlmssp_state->domain) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Request features for the NTLMSSP negotiation - * - * @param ntlmssp_state NTLMSSP state - * @param feature_list List of space separated features requested from NTLMSSP. - */ -void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list) -{ - /* - * We need to set this to allow a later SetPassword - * via the SAMR pipe to succeed. Strange.... We could - * also add NTLMSSP_NEGOTIATE_SEAL here. JRA. - */ - if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; - } - if (in_list("NTLMSSP_FEATURE_CCACHE", feature_list, true)) { - ntlmssp_state->use_ccache = true; - } -} - -/** - * Request a feature for the NTLMSSP negotiation - * - * @param ntlmssp_state NTLMSSP state - * @param feature Bit flag specifying the requested feature - */ -void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature) -{ - /* As per JRA's comment above */ - if (feature & NTLMSSP_FEATURE_SESSION_KEY) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if (feature & NTLMSSP_FEATURE_SIGN) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } - if (feature & NTLMSSP_FEATURE_SEAL) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; - } - if (feature & NTLMSSP_FEATURE_CCACHE) { - ntlmssp_state->use_ccache = true; - } -} - -/** - * Next state function for the NTLMSSP state machine - * - * @param ntlmssp_state NTLMSSP State - * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB - * @param out The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. - */ - -NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, - const DATA_BLOB input, DATA_BLOB *out) -{ - uint32_t ntlmssp_command; - int i; - - if (ntlmssp_state->expected_state == NTLMSSP_DONE) { - /* Called update after negotiations finished. */ - DEBUG(1, ("Called NTLMSSP after state machine was 'done'\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - *out = data_blob_null; - - if (!input.length) { - switch (ntlmssp_state->role) { - case NTLMSSP_CLIENT: - ntlmssp_command = NTLMSSP_INITIAL; - break; - case NTLMSSP_SERVER: - /* 'datagram' mode - no neg packet */ - ntlmssp_command = NTLMSSP_NEGOTIATE; - break; - default: - DEBUG(1, ("Invalid role: %d\n", ntlmssp_state->role)); - return NT_STATUS_INVALID_PARAMETER; - } - } else { - if (!msrpc_parse(ntlmssp_state, &input, "Cd", - "NTLMSSP", - &ntlmssp_command)) { - DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n")); - dump_data(2, input.data, input.length); - return NT_STATUS_INVALID_PARAMETER; - } - } - - if (ntlmssp_command != ntlmssp_state->expected_state) { - DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); - return NT_STATUS_INVALID_PARAMETER; - } - - for (i=0; ntlmssp_callbacks[i].fn; i++) { - if (ntlmssp_callbacks[i].role == ntlmssp_state->role - && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) { - return ntlmssp_callbacks[i].fn(ntlmssp_state, ntlmssp_state, input, out); - } - } - - DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n", - ntlmssp_state->role, ntlmssp_command)); - - return NT_STATUS_INVALID_PARAMETER; -} - -/********************************************************************* - Client side NTLMSSP -*********************************************************************/ - -/** - * Next state function for the Initial packet - * - * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB. reply.data must be NULL - * @param request The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors or NT_STATUS_OK. - */ - -static NTSTATUS ntlmssp3_client_initial(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, - DATA_BLOB in, DATA_BLOB *out) -{ - const char *domain = ntlmssp_state->client.netbios_domain; - const char *workstation = ntlmssp_state->client.netbios_name; - NTSTATUS status; - - /* These don't really matter in the initial packet, so don't panic if they are not set */ - if (!domain) { - domain = ""; - } - - if (!workstation) { - workstation = ""; - } - - if (ntlmssp_state->unicode) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; - } else { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; - } - - if (ntlmssp_state->use_ntlmv2) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; - } - - /* generate the ntlmssp negotiate packet */ - status = msrpc_gen(out_mem_ctx, - out, "CddAA", - "NTLMSSP", - NTLMSSP_NEGOTIATE, - ntlmssp_state->neg_flags, - domain, - workstation); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("ntlmssp_client_initial: failed to generate " - "ntlmssp negotiate packet\n")); - return status; - } - - if (DEBUGLEVEL >= 10) { - struct NEGOTIATE_MESSAGE *negotiate = talloc( - talloc_tos(), struct NEGOTIATE_MESSAGE); - if (negotiate != NULL) { - status = ntlmssp_pull_NEGOTIATE_MESSAGE( - out, negotiate, negotiate); - if (NT_STATUS_IS_OK(status)) { - NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE, - negotiate); - } - TALLOC_FREE(negotiate); - } - } - - ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; - - return NT_STATUS_MORE_PROCESSING_REQUIRED; -} - -bool ntlmssp_is_anonymous(struct ntlmssp_state *ntlmssp_state) -{ - const char *user = ntlmssp_state->user; - - if (user == NULL) { - return true; - } - - if (strlen(user) == 0) { - return true; - } - - return false; -} - -/** - * Next state function for the Challenge Packet. Generate an auth packet. - * - * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB. reply.data must be NULL - * @param request The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors or NT_STATUS_OK. - */ - -static NTSTATUS ntlmssp3_client_challenge(struct ntlmssp_state *ntlmssp_state, - TALLOC_CTX *out_mem_ctx, /* Unused at this time */ - const DATA_BLOB reply, DATA_BLOB *next_request) -{ - uint32_t chal_flags, ntlmssp_command, unkn1 = 0, unkn2 = 0; - DATA_BLOB server_domain_blob; - DATA_BLOB challenge_blob; - DATA_BLOB struct_blob = data_blob_null; - char *server_domain; - const char *chal_parse_string; - const char *chal_parse_string_short = NULL; - const char *auth_gen_string; - DATA_BLOB lm_response = data_blob_null; - DATA_BLOB nt_response = data_blob_null; - DATA_BLOB session_key = data_blob_null; - DATA_BLOB encrypted_session_key = data_blob_null; - NTSTATUS nt_status = NT_STATUS_OK; - bool anon = ntlmssp_is_anonymous(ntlmssp_state); - - if (!anon && ntlmssp_state->use_ccache) { - struct wbcCredentialCacheParams params; - struct wbcCredentialCacheInfo *info = NULL; - struct wbcAuthErrorInfo *error = NULL; - struct wbcNamedBlob auth_blob; - struct wbcBlob *wbc_next = NULL; - struct wbcBlob *wbc_session_key = NULL; - wbcErr wbc_status; - int i; - - /* - * We need to set the netbios name or we are not able to connect - * a Windows DC. - */ - if (ntlmssp_state->server.netbios_domain == NULL || - ntlmssp_state->server.netbios_domain[0] == '\0') { - ntlmssp_state->server.netbios_domain = ntlmssp_state->domain; - } - - params.account_name = ntlmssp_state->user; - params.domain_name = ntlmssp_state->domain; - params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP; - - auth_blob.name = "challenge_blob"; - auth_blob.flags = 0; - auth_blob.blob.data = reply.data; - auth_blob.blob.length = reply.length; - params.num_blobs = 1; - params.blobs = &auth_blob; - - wbc_status = wbcCredentialCache(¶ms, &info, &error); - wbcFreeMemory(error); - if (!WBC_ERROR_IS_OK(wbc_status)) { - goto noccache; - } - - for (i=0; inum_blobs; i++) { - if (strequal(info->blobs[i].name, "auth_blob")) { - wbc_next = &info->blobs[i].blob; - } - if (strequal(info->blobs[i].name, "session_key")) { - wbc_session_key = &info->blobs[i].blob; - } - } - if ((wbc_next == NULL) || (wbc_session_key == NULL)) { - wbcFreeMemory(info); - goto noccache; - } - - *next_request = data_blob_talloc(ntlmssp_state, - wbc_next->data, - wbc_next->length); - ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state, - wbc_session_key->data, - wbc_session_key->length); - - wbcFreeMemory(info); - goto done; - } - -noccache: - - if (!msrpc_parse(ntlmssp_state, &reply, "CdBd", - "NTLMSSP", - &ntlmssp_command, - &server_domain_blob, - &chal_flags)) { - DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); - dump_data(2, reply.data, reply.length); - - return NT_STATUS_INVALID_PARAMETER; - } - - if (DEBUGLEVEL >= 10) { - struct CHALLENGE_MESSAGE *challenge = talloc( - talloc_tos(), struct CHALLENGE_MESSAGE); - if (challenge != NULL) { - NTSTATUS status; - challenge->NegotiateFlags = chal_flags; - status = ntlmssp_pull_CHALLENGE_MESSAGE( - &reply, challenge, challenge); - if (NT_STATUS_IS_OK(status)) { - NDR_PRINT_DEBUG(CHALLENGE_MESSAGE, - challenge); - } - TALLOC_FREE(challenge); - } - } - - data_blob_free(&server_domain_blob); - - DEBUG(3, ("Got challenge flags:\n")); - debug_ntlmssp_flags(chal_flags); - - ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth()); - - if (ntlmssp_state->unicode) { - if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { - chal_parse_string = "CdUdbddB"; - } else { - chal_parse_string = "CdUdbdd"; - chal_parse_string_short = "CdUdb"; - } - auth_gen_string = "CdBBUUUBd"; - } else { - if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { - chal_parse_string = "CdAdbddB"; - } else { - chal_parse_string = "CdAdbdd"; - chal_parse_string_short = "CdAdb"; - } - - auth_gen_string = "CdBBAAABd"; - } - - DEBUG(3, ("NTLMSSP: Set final flags:\n")); - debug_ntlmssp_flags(ntlmssp_state->neg_flags); - - if (!msrpc_parse(ntlmssp_state, &reply, chal_parse_string, - "NTLMSSP", - &ntlmssp_command, - &server_domain, - &chal_flags, - &challenge_blob, 8, - &unkn1, &unkn2, - &struct_blob)) { - - bool ok = false; - - DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); - - if (chal_parse_string_short != NULL) { - /* - * In the case where NTLMSSP_NEGOTIATE_TARGET_INFO - * is not used, some NTLMSSP servers don't return - * the unused unkn1 and unkn2 fields. - * See bug: - * https://bugzilla.samba.org/show_bug.cgi?id=10016 - * for packet traces. - * Try and parse again without them. - */ - ok = msrpc_parse(ntlmssp_state, &reply, - chal_parse_string_short, - "NTLMSSP", - &ntlmssp_command, - &server_domain, - &chal_flags, - &challenge_blob, 8); - if (!ok) { - DEBUG(1, ("Failed to short parse " - "the NTLMSSP Challenge: (#2)\n")); - } - } - - if (!ok) { - dump_data(2, reply.data, reply.length); - return NT_STATUS_INVALID_PARAMETER; - } - } - - if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) { - ntlmssp_state->server.is_standalone = true; - } else { - ntlmssp_state->server.is_standalone = false; - } - /* TODO: parse struct_blob and fill in the rest */ - ntlmssp_state->server.netbios_name = ""; - ntlmssp_state->server.netbios_domain = server_domain; - ntlmssp_state->server.dns_name = ""; - ntlmssp_state->server.dns_domain = ""; - - if (challenge_blob.length != 8) { - data_blob_free(&struct_blob); - return NT_STATUS_INVALID_PARAMETER; - } - - if (anon || !ntlmssp_state->nt_hash) { - static const uint8_t zeros[16] = {0, }; - /* do nothing - blobs are zero length */ - - /* session key is all zeros */ - session_key = data_blob_talloc(ntlmssp_state, zeros, 16); - - /* not doing NLTM2 without a password */ - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; - } else if (ntlmssp_state->use_ntlmv2) { - if (!struct_blob.length) { - /* be lazy, match win2k - we can't do NTLMv2 without it */ - DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - /* TODO: if the remote server is standalone, then we should replace 'domain' - with the server name as supplied above */ - - if (!SMBNTLMv2encrypt_hash(ntlmssp_state, - ntlmssp_state->user, - ntlmssp_state->domain, - ntlmssp_state->nt_hash, &challenge_blob, - &struct_blob, - &lm_response, &nt_response, NULL, - &session_key)) { - data_blob_free(&challenge_blob); - data_blob_free(&struct_blob); - return NT_STATUS_NO_MEMORY; - } - } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - MD5_CTX md5_session_nonce_ctx; - uint8_t session_nonce[16]; - uint8_t session_nonce_hash[16]; - uint8_t user_session_key[16]; - - lm_response = data_blob_talloc(ntlmssp_state, NULL, 24); - generate_random_buffer(lm_response.data, 8); - memset(lm_response.data+8, 0, 16); - - memcpy(session_nonce, challenge_blob.data, 8); - memcpy(&session_nonce[8], lm_response.data, 8); - - MD5Init(&md5_session_nonce_ctx); - MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8); - MD5Update(&md5_session_nonce_ctx, lm_response.data, 8); - MD5Final(session_nonce_hash, &md5_session_nonce_ctx); - - DEBUG(5, ("NTLMSSP challenge set by NTLM2\n")); - DEBUG(5, ("challenge is: \n")); - dump_data(5, session_nonce_hash, 8); - - nt_response = data_blob_talloc(ntlmssp_state, NULL, 24); - SMBNTencrypt_hash(ntlmssp_state->nt_hash, - session_nonce_hash, - nt_response.data); - - session_key = data_blob_talloc(ntlmssp_state, NULL, 16); - - SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, user_session_key); - hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data); - dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); - } else { - /* lanman auth is insecure, it may be disabled */ - if (lp_client_lanman_auth() && ntlmssp_state->lm_hash) { - lm_response = data_blob_talloc(ntlmssp_state, - NULL, 24); - SMBencrypt_hash(ntlmssp_state->lm_hash,challenge_blob.data, - lm_response.data); - } - - nt_response = data_blob_talloc(ntlmssp_state, NULL, 24); - SMBNTencrypt_hash(ntlmssp_state->nt_hash,challenge_blob.data, - nt_response.data); - - session_key = data_blob_talloc(ntlmssp_state, NULL, 16); - if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - && lp_client_lanman_auth() && ntlmssp_state->lm_hash) { - SMBsesskeygen_lm_sess_key(ntlmssp_state->lm_hash, lm_response.data, - session_key.data); - dump_data_pw("LM session key\n", session_key.data, session_key.length); - } else { - SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, session_key.data); - dump_data_pw("NT session key:\n", session_key.data, session_key.length); - } - } - data_blob_free(&struct_blob); - - /* Key exchange encryptes a new client-generated session key with - the password-derived key */ - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { - /* Make up a new session key */ - uint8_t client_session_key[16]; - generate_random_buffer(client_session_key, sizeof(client_session_key)); - - /* Encrypt the new session key with the old one */ - encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); - dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); - arcfour_crypt_blob(encrypted_session_key.data, encrypted_session_key.length, &session_key); - dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); - - /* Mark the new session key as the 'real' session key */ - data_blob_free(&session_key); - session_key = data_blob_talloc(ntlmssp_state, - client_session_key, - sizeof(client_session_key)); - } - - /* this generates the actual auth packet */ - nt_status = msrpc_gen(ntlmssp_state, next_request, auth_gen_string, - "NTLMSSP", - NTLMSSP_AUTH, - lm_response.data, lm_response.length, - nt_response.data, nt_response.length, - ntlmssp_state->domain, - ntlmssp_state->user, - ntlmssp_state->client.netbios_name, - encrypted_session_key.data, encrypted_session_key.length, - ntlmssp_state->neg_flags); - - if (!NT_STATUS_IS_OK(nt_status)) { - return NT_STATUS_NO_MEMORY; - } - - if (DEBUGLEVEL >= 10) { - struct AUTHENTICATE_MESSAGE *authenticate = talloc( - talloc_tos(), struct AUTHENTICATE_MESSAGE); - if (authenticate != NULL) { - NTSTATUS status; - authenticate->NegotiateFlags = - ntlmssp_state->neg_flags; - status = ntlmssp_pull_AUTHENTICATE_MESSAGE( - next_request, authenticate, authenticate); - if (NT_STATUS_IS_OK(status)) { - NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE, - authenticate); - } - TALLOC_FREE(authenticate); - } - } - - data_blob_free(&encrypted_session_key); - - data_blob_free(&ntlmssp_state->chal); - - ntlmssp_state->session_key = session_key; - - ntlmssp_state->chal = challenge_blob; - ntlmssp_state->lm_resp = lm_response; - ntlmssp_state->nt_resp = nt_response; - -done: - - ntlmssp_state->expected_state = NTLMSSP_DONE; - - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) { - DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status))); - } - - return nt_status; -} - -NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, - const char *netbios_name, - const char *netbios_domain, - bool use_ntlmv2, - struct ntlmssp_state **_ntlmssp_state) -{ - struct ntlmssp_state *ntlmssp_state; - - if (!netbios_name) { - netbios_name = ""; - } - - if (!netbios_domain) { - netbios_domain = ""; - } - - ntlmssp_state = talloc_zero(mem_ctx, struct ntlmssp_state); - if (!ntlmssp_state) { - return NT_STATUS_NO_MEMORY; - } - - ntlmssp_state->role = NTLMSSP_CLIENT; - - ntlmssp_state->unicode = True; - - ntlmssp_state->use_ntlmv2 = use_ntlmv2; - - ntlmssp_state->expected_state = NTLMSSP_INITIAL; - - ntlmssp_state->neg_flags = - NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_ALWAYS_SIGN | - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_NEGOTIATE_NTLM2 | - NTLMSSP_NEGOTIATE_KEY_EXCH | - NTLMSSP_REQUEST_TARGET; - - ntlmssp_state->client.netbios_name = talloc_strdup(ntlmssp_state, netbios_name); - if (!ntlmssp_state->client.netbios_name) { - talloc_free(ntlmssp_state); - return NT_STATUS_NO_MEMORY; - } - ntlmssp_state->client.netbios_domain = talloc_strdup(ntlmssp_state, netbios_domain); - if (!ntlmssp_state->client.netbios_domain) { - talloc_free(ntlmssp_state); - return NT_STATUS_NO_MEMORY; - } - - *_ntlmssp_state = ntlmssp_state; - return NT_STATUS_OK; -} diff --git a/source3/wscript_build b/source3/wscript_build index 5c3b667..3f6a43e 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -369,13 +369,9 @@ bld.SAMBA3_LIBRARY('smbd_shim', deps='talloc', private_library=True) -bld.SAMBA3_SUBSYSTEM('LIBNTLMSSP', - source='''libsmb/ntlmssp.c''', - deps='NDR_NTLMSSP NTLMSSP_COMMON wbclient') - bld.SAMBA3_SUBSYSTEM('auth_generic', source='libsmb/auth_generic.c', - deps='LIBNTLMSSP gse gensec') + deps='gse gensec') bld.SAMBA3_LIBRARY('libsmb', source='''libsmb/clientgen.c @@ -403,7 +399,6 @@ bld.SAMBA3_LIBRARY('libsmb', libsmb/smbsock_connect.c libsmb/cli_smb2_fnum.c''', deps=''' - LIBNTLMSSP auth_generic CLDAP LIBNMB @@ -1447,7 +1442,7 @@ bld.SAMBA3_BINARY('ntlm_auth', tiniparser libsmb popt_samba3 - LIBNTLMSSP gse gensec''') + gse gensec''') bld.SAMBA3_BINARY('timelimit', source='script/tests/timelimit.c', -- 1.9.1 From 65cdb404c7b8a04449520dd2fe324fe74796c015 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 18:31:50 +0100 Subject: [PATCH 080/323] s3:libsmb: let cli_session_setup_ntlmssp*() use gensec_update_send/recv() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pares a fix for https://bugzilla.samba.org/show_bug.cgi?id=10288 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 576257f6e1488a623306dc368c806e218b1fcdf2) --- source3/libsmb/cliconnect.c | 283 ++++++++++++++++++++++++++++++-------------- 1 file changed, 191 insertions(+), 92 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index e71b8cb..9f75b89 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1420,7 +1420,11 @@ struct cli_session_setup_ntlmssp_state { struct auth_generic_state *auth_generic; bool is_anonymous; DATA_BLOB blob_in; + uint8_t *inbuf; + struct iovec *recv_iov; DATA_BLOB blob_out; + bool local_ready; + bool remote_ready; DATA_BLOB session_key; }; @@ -1432,13 +1436,17 @@ static int cli_session_setup_ntlmssp_state_destructor( return 0; } -static void cli_session_setup_ntlmssp_done(struct tevent_req *req); +static void cli_session_setup_ntlmssp_local_next(struct tevent_req *req); +static void cli_session_setup_ntlmssp_local_done(struct tevent_req *subreq); +static void cli_session_setup_ntlmssp_remote_next(struct tevent_req *req); +static void cli_session_setup_ntlmssp_remote_done(struct tevent_req *subreq); +static void cli_session_setup_ntlmssp_ready(struct tevent_req *req); static struct tevent_req *cli_session_setup_ntlmssp_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, const char *user, const char *pass, const char *domain) { - struct tevent_req *req, *subreq; + struct tevent_req *req; struct cli_session_setup_ntlmssp_state *state; NTSTATUS status; @@ -1521,13 +1529,6 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( return tevent_req_post(req, ev); } - status = gensec_update(state->auth_generic->gensec_security, - state, state->blob_in, &state->blob_out); - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - tevent_req_nterror(req, status); - return tevent_req_post(req, ev); - } - if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { state->cli->smb2.session = smbXcli_session_create(cli, cli->conn); @@ -1536,125 +1537,223 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( } } - subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out); - if (tevent_req_nomem(subreq, req)) { + cli_session_setup_ntlmssp_local_next(req); + if (!tevent_req_is_in_progress(req)) { return tevent_req_post(req, ev); } - tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req); + return req; } -static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) +static void cli_session_setup_ntlmssp_local_next(struct tevent_req *req) { - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct cli_session_setup_ntlmssp_state *state = tevent_req_data( - req, struct cli_session_setup_ntlmssp_state); - uint8_t *inbuf = NULL; - struct iovec *recv_iov = NULL; + struct cli_session_setup_ntlmssp_state *state = + tevent_req_data(req, + struct cli_session_setup_ntlmssp_state); + struct tevent_req *subreq = NULL; + + if (state->local_ready) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + + subreq = gensec_update_send(state, state->ev, + state->auth_generic->gensec_security, + state->blob_in); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_local_done, req); +} + +static void cli_session_setup_ntlmssp_local_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct cli_session_setup_ntlmssp_state *state = + tevent_req_data(req, + struct cli_session_setup_ntlmssp_state); NTSTATUS status; - status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in, - &inbuf, &recv_iov); + status = gensec_update_recv(subreq, state, &state->blob_out); TALLOC_FREE(subreq); - data_blob_free(&state->blob_out); + state->blob_in = data_blob_null; + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) + { + tevent_req_nterror(req, status); + return; + } if (NT_STATUS_IS_OK(status)) { - const char *server_domain = NULL; + state->local_ready = true; + } - server_domain = gensec_ntlmssp_server_domain( - state->auth_generic->gensec_security); + if (state->local_ready && state->remote_ready) { + cli_session_setup_ntlmssp_ready(req); + return; + } - if (state->cli->server_domain[0] == '\0' && server_domain != NULL) { - TALLOC_FREE(state->cli->server_domain); - state->cli->server_domain = talloc_strdup(state->cli, - server_domain); - if (state->cli->server_domain == NULL) { - tevent_req_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - } + cli_session_setup_ntlmssp_remote_next(req); +} - status = gensec_session_key(state->auth_generic->gensec_security, - state, &state->session_key); - if (tevent_req_nterror(req, status)) { - return; - } +static void cli_session_setup_ntlmssp_remote_next(struct tevent_req *req) +{ + struct cli_session_setup_ntlmssp_state *state = + tevent_req_data(req, + struct cli_session_setup_ntlmssp_state); + struct tevent_req *subreq = NULL; - if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { - struct smbXcli_session *session = state->cli->smb2.session; + if (state->remote_ready) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } - if (state->is_anonymous) { - /* - * Windows server does not set the - * SMB2_SESSION_FLAG_IS_GUEST nor - * SMB2_SESSION_FLAG_IS_NULL flag. - * - * This fix makes sure we do not try - * to verify a signature on the final - * session setup response. - */ - tevent_req_done(req); - return; - } + subreq = cli_sesssetup_blob_send(state, state->ev, + state->cli, state->blob_out); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, + cli_session_setup_ntlmssp_remote_done, + req); +} - status = smb2cli_session_set_session_key(session, - state->session_key, - recv_iov); - if (tevent_req_nterror(req, status)) { - return; - } - } else { - struct smbXcli_session *session = state->cli->smb1.session; +static void cli_session_setup_ntlmssp_remote_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct cli_session_setup_ntlmssp_state *state = + tevent_req_data(req, + struct cli_session_setup_ntlmssp_state); + NTSTATUS status; - status = smb1cli_session_set_session_key(session, - state->session_key); - if (tevent_req_nterror(req, status)) { - return; - } + TALLOC_FREE(state->inbuf); + TALLOC_FREE(state->recv_iov); - if (smb1cli_conn_activate_signing( - state->cli->conn, state->session_key, - data_blob_null) - && !smb1cli_conn_check_signing(state->cli->conn, inbuf, 1)) { - tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); - return; - } - } - tevent_req_done(req); + status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in, + &state->inbuf, &state->recv_iov); + TALLOC_FREE(subreq); + data_blob_free(&state->blob_out); + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) + { + tevent_req_nterror(req, status); return; } - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - tevent_req_nterror(req, status); + + if (NT_STATUS_IS_OK(status)) { + state->remote_ready = true; + } + + if (state->local_ready && state->remote_ready) { + cli_session_setup_ntlmssp_ready(req); return; } - if (state->blob_in.length == 0) { - tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); + cli_session_setup_ntlmssp_local_next(req); +} + +static void cli_session_setup_ntlmssp_ready(struct tevent_req *req) +{ + struct cli_session_setup_ntlmssp_state *state = + tevent_req_data(req, + struct cli_session_setup_ntlmssp_state); + const char *server_domain = NULL; + NTSTATUS status; + + if (state->blob_in.length != 0) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); return; } - status = gensec_update(state->auth_generic->gensec_security, - state, state->blob_in, &state->blob_out); - data_blob_free(&state->blob_in); - if (!NT_STATUS_IS_OK(status) - && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - tevent_req_nterror(req, status); + if (state->blob_out.length != 0) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); return; } - subreq = cli_sesssetup_blob_send(state, state->ev, state->cli, - state->blob_out); - if (tevent_req_nomem(subreq, req)) { + /* + * We can remove this later + * and leave the server domain empty for SMB2 and above + * in future releases. + */ + server_domain = gensec_ntlmssp_server_domain( + state->auth_generic->gensec_security); + + if (state->cli->server_domain[0] == '\0' && server_domain != NULL) { + TALLOC_FREE(state->cli->server_domain); + state->cli->server_domain = talloc_strdup(state->cli, + server_domain); + if (state->cli->server_domain == NULL) { + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + } + + status = gensec_session_key(state->auth_generic->gensec_security, + state, &state->session_key); + if (tevent_req_nterror(req, status)) { return; } - tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req); + + if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { + struct smbXcli_session *session = state->cli->smb2.session; + + if (state->is_anonymous) { + /* + * Windows server does not set the + * SMB2_SESSION_FLAG_IS_GUEST nor + * SMB2_SESSION_FLAG_IS_NULL flag. + * + * This fix makes sure we do not try + * to verify a signature on the final + * session setup response. + */ + tevent_req_done(req); + return; + } + + status = smb2cli_session_set_session_key(session, + state->session_key, + state->recv_iov); + if (tevent_req_nterror(req, status)) { + return; + } + } else { + struct smbXcli_session *session = state->cli->smb1.session; + bool active; + + status = smb1cli_session_set_session_key(session, + state->session_key); + if (tevent_req_nterror(req, status)) { + return; + } + + active = smb1cli_conn_activate_signing(state->cli->conn, + state->session_key, + data_blob_null); + if (active) { + bool ok; + + ok = smb1cli_conn_check_signing(state->cli->conn, + state->inbuf, 1); + if (!ok) { + tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); + return; + } + } + } + + tevent_req_done(req); } static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req) { - struct cli_session_setup_ntlmssp_state *state = tevent_req_data( - req, struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_ntlmssp_state *state = + tevent_req_data(req, + struct cli_session_setup_ntlmssp_state); NTSTATUS status; if (tevent_req_is_nterror(req, &status)) { -- 1.9.1 From e2e2664c91f444e8be04a190013b88d4cacafaf9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 15:47:11 +0100 Subject: [PATCH 081/323] s3:libsmb: provide generic cli_session_setup_gensec_send/recv() pair MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It will be possible to use this for more than just NTLMSSP in future. This prepares a fix for https://bugzilla.samba.org/show_bug.cgi?id=10288 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 285c342f01a6e9a892f03360f8d2d0097e7a41cb) --- source3/libsmb/cliconnect.c | 151 ++++++++++++++++++++++++++++++-------------- 1 file changed, 103 insertions(+), 48 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 9f75b89..bb8d018 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1414,7 +1414,7 @@ static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req) Do a spnego/NTLMSSP encrypted session setup. ****************************************************************************/ -struct cli_session_setup_ntlmssp_state { +struct cli_session_setup_gensec_state { struct tevent_context *ev; struct cli_state *cli; struct auth_generic_state *auth_generic; @@ -1428,30 +1428,35 @@ struct cli_session_setup_ntlmssp_state { DATA_BLOB session_key; }; -static int cli_session_setup_ntlmssp_state_destructor( - struct cli_session_setup_ntlmssp_state *state) +static int cli_session_setup_gensec_state_destructor( + struct cli_session_setup_gensec_state *state) { TALLOC_FREE(state->auth_generic); data_blob_clear_free(&state->session_key); return 0; } -static void cli_session_setup_ntlmssp_local_next(struct tevent_req *req); -static void cli_session_setup_ntlmssp_local_done(struct tevent_req *subreq); -static void cli_session_setup_ntlmssp_remote_next(struct tevent_req *req); -static void cli_session_setup_ntlmssp_remote_done(struct tevent_req *subreq); -static void cli_session_setup_ntlmssp_ready(struct tevent_req *req); +static void cli_session_setup_gensec_local_next(struct tevent_req *req); +static void cli_session_setup_gensec_local_done(struct tevent_req *subreq); +static void cli_session_setup_gensec_remote_next(struct tevent_req *req); +static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq); +static void cli_session_setup_gensec_ready(struct tevent_req *req); -static struct tevent_req *cli_session_setup_ntlmssp_send( +static struct tevent_req *cli_session_setup_gensec_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, - const char *user, const char *pass, const char *domain) + const char *user, const char *pass, const char *domain, + enum credentials_use_kerberos krb5_state, + const char *target_service, + const char *target_hostname, + const char *target_principal) { struct tevent_req *req; - struct cli_session_setup_ntlmssp_state *state; + struct cli_session_setup_gensec_state *state; NTSTATUS status; + bool use_spnego_principal = lp_client_use_spnego_principal(); req = tevent_req_create(mem_ctx, &state, - struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_gensec_state); if (req == NULL) { return NULL; } @@ -1459,7 +1464,7 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( state->cli = cli; talloc_set_destructor( - state, cli_session_setup_ntlmssp_state_destructor); + state, cli_session_setup_gensec_state_destructor); status = auth_generic_client_prepare(state, &state->auth_generic); if (tevent_req_nterror(req, status)) { @@ -1519,7 +1524,49 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( } cli_credentials_set_kerberos_state(state->auth_generic->credentials, - CRED_DONT_USE_KERBEROS); + krb5_state); + + if (krb5_state == CRED_DONT_USE_KERBEROS) { + use_spnego_principal = false; + } + + if (target_service != NULL) { + status = gensec_set_target_service( + state->auth_generic->gensec_security, + target_service); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + } + + if (target_hostname != NULL) { + status = gensec_set_target_hostname( + state->auth_generic->gensec_security, + target_hostname); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + } + + if (target_principal != NULL) { + status = gensec_set_target_principal( + state->auth_generic->gensec_security, + target_principal); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + use_spnego_principal = false; + } else if (target_service != NULL && target_hostname != NULL) { + use_spnego_principal = false; + } + + if (use_spnego_principal) { + const DATA_BLOB *b; + b = smbXcli_conn_server_gss_blob(cli->conn); + if (b != NULL) { + state->blob_in = *b; + } + } state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials); @@ -1537,7 +1584,7 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( } } - cli_session_setup_ntlmssp_local_next(req); + cli_session_setup_gensec_local_next(req); if (!tevent_req_is_in_progress(req)) { return tevent_req_post(req, ev); } @@ -1545,11 +1592,11 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( return req; } -static void cli_session_setup_ntlmssp_local_next(struct tevent_req *req) +static void cli_session_setup_gensec_local_next(struct tevent_req *req) { - struct cli_session_setup_ntlmssp_state *state = + struct cli_session_setup_gensec_state *state = tevent_req_data(req, - struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_gensec_state); struct tevent_req *subreq = NULL; if (state->local_ready) { @@ -1563,17 +1610,17 @@ static void cli_session_setup_ntlmssp_local_next(struct tevent_req *req) if (tevent_req_nomem(subreq, req)) { return; } - tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_local_done, req); + tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req); } -static void cli_session_setup_ntlmssp_local_done(struct tevent_req *subreq) +static void cli_session_setup_gensec_local_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct cli_session_setup_ntlmssp_state *state = + struct cli_session_setup_gensec_state *state = tevent_req_data(req, - struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_gensec_state); NTSTATUS status; status = gensec_update_recv(subreq, state, &state->blob_out); @@ -1591,18 +1638,18 @@ static void cli_session_setup_ntlmssp_local_done(struct tevent_req *subreq) } if (state->local_ready && state->remote_ready) { - cli_session_setup_ntlmssp_ready(req); + cli_session_setup_gensec_ready(req); return; } - cli_session_setup_ntlmssp_remote_next(req); + cli_session_setup_gensec_remote_next(req); } -static void cli_session_setup_ntlmssp_remote_next(struct tevent_req *req) +static void cli_session_setup_gensec_remote_next(struct tevent_req *req) { - struct cli_session_setup_ntlmssp_state *state = + struct cli_session_setup_gensec_state *state = tevent_req_data(req, - struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_gensec_state); struct tevent_req *subreq = NULL; if (state->remote_ready) { @@ -1616,18 +1663,18 @@ static void cli_session_setup_ntlmssp_remote_next(struct tevent_req *req) return; } tevent_req_set_callback(subreq, - cli_session_setup_ntlmssp_remote_done, + cli_session_setup_gensec_remote_done, req); } -static void cli_session_setup_ntlmssp_remote_done(struct tevent_req *subreq) +static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct cli_session_setup_ntlmssp_state *state = + struct cli_session_setup_gensec_state *state = tevent_req_data(req, - struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_gensec_state); NTSTATUS status; TALLOC_FREE(state->inbuf); @@ -1649,18 +1696,18 @@ static void cli_session_setup_ntlmssp_remote_done(struct tevent_req *subreq) } if (state->local_ready && state->remote_ready) { - cli_session_setup_ntlmssp_ready(req); + cli_session_setup_gensec_ready(req); return; } - cli_session_setup_ntlmssp_local_next(req); + cli_session_setup_gensec_local_next(req); } -static void cli_session_setup_ntlmssp_ready(struct tevent_req *req) +static void cli_session_setup_gensec_ready(struct tevent_req *req) { - struct cli_session_setup_ntlmssp_state *state = + struct cli_session_setup_gensec_state *state = tevent_req_data(req, - struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_gensec_state); const char *server_domain = NULL; NTSTATUS status; @@ -1675,6 +1722,9 @@ static void cli_session_setup_ntlmssp_ready(struct tevent_req *req) } /* + * gensec_ntlmssp_server_domain() returns NULL + * if NTLMSSP is not used. + * * We can remove this later * and leave the server domain empty for SMB2 and above * in future releases. @@ -1749,11 +1799,11 @@ static void cli_session_setup_ntlmssp_ready(struct tevent_req *req) tevent_req_done(req); } -static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req) +static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req) { - struct cli_session_setup_ntlmssp_state *state = + struct cli_session_setup_gensec_state *state = tevent_req_data(req, - struct cli_session_setup_ntlmssp_state); + struct cli_session_setup_gensec_state); NTSTATUS status; if (tevent_req_is_nterror(req, &status)) { @@ -1833,6 +1883,7 @@ static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx, struct cli_session_setup_spnego_state { struct tevent_context *ev; struct cli_state *cli; + const char *target_hostname; const char *user; const char *account; const char *pass; @@ -1876,6 +1927,7 @@ static struct tevent_req *cli_session_setup_spnego_send( return tevent_req_post(req, ev); } + state->target_hostname = smbXcli_conn_remote_name(cli->conn); server_blob = smbXcli_conn_server_gss_blob(cli->conn); DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", @@ -1923,12 +1975,10 @@ static struct tevent_req *cli_session_setup_spnego_send( * and do not store results */ if (user && *user && cli->got_kerberos_mechanism && cli->use_kerberos) { - const char *remote_name = smbXcli_conn_remote_name(cli->conn); char *tmp; - tmp = cli_session_setup_get_principal( - talloc_tos(), principal, remote_name, dest_realm); + talloc_tos(), principal, state->target_hostname, dest_realm); TALLOC_FREE(principal); principal = tmp; @@ -1964,8 +2014,11 @@ static struct tevent_req *cli_session_setup_spnego_send( #endif ntlmssp: - subreq = cli_session_setup_ntlmssp_send( - state, ev, cli, state->account, pass, user_domain); + subreq = cli_session_setup_gensec_send( + state, state->ev, state->cli, + state->account, state->pass, state->user_domain, + CRED_DONT_USE_KERBEROS, + "cifs", state->target_hostname, NULL); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -1991,9 +2044,11 @@ static void cli_session_setup_spnego_done_krb(struct tevent_req *subreq) return; } - subreq = cli_session_setup_ntlmssp_send( - state, state->ev, state->cli, state->account, state->pass, - state->user_domain); + subreq = cli_session_setup_gensec_send( + state, state->ev, state->cli, + state->account, state->pass, state->user_domain, + CRED_DONT_USE_KERBEROS, + "cifs", state->target_hostname, NULL); if (tevent_req_nomem(subreq, req)) { return; } @@ -2010,7 +2065,7 @@ static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req *subreq) req, struct cli_session_setup_spnego_state); NTSTATUS status; - status = cli_session_setup_ntlmssp_recv(subreq); + status = cli_session_setup_gensec_recv(subreq); TALLOC_FREE(subreq); state->result = ADS_ERROR_NT(status); tevent_req_done(req); -- 1.9.1 From 831e6368b47f9292a8895242babf2328eb2b6b13 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 14:35:21 +0100 Subject: [PATCH 082/323] s3:libsmb: call cli_state_remote_realm() within cli_session_setup_spnego_send() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 907e2b1f665cdafc863f4702ede5dcf16e6cc269) --- source3/libsmb/cliconnect.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index bb8d018..84ad783 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1900,14 +1900,14 @@ static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req *subreq); static struct tevent_req *cli_session_setup_spnego_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, - const char *user, const char *pass, const char *user_domain, - const char *dest_realm) + const char *user, const char *pass, const char *user_domain) { struct tevent_req *req, *subreq; struct cli_session_setup_spnego_state *state; char *principal = NULL; char *OIDs[ASN1_MAX_OIDS]; int i; + const char *dest_realm = cli_state_remote_realm(cli); const DATA_BLOB *server_blob; req = tevent_req_create(mem_ctx, &state, @@ -2179,10 +2179,8 @@ struct tevent_req *cli_session_setup_send(TALLOC_CTX *mem_ctx, } if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { - const char *remote_realm = cli_state_remote_realm(cli); - subreq = cli_session_setup_spnego_send( - state, ev, cli, user, pass, workgroup, remote_realm); + state, ev, cli, user, pass, workgroup); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -2242,10 +2240,8 @@ struct tevent_req *cli_session_setup_send(TALLOC_CTX *mem_ctx, /* if the server supports extended security then use SPNEGO */ if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) { - const char *remote_realm = cli_state_remote_realm(cli); - subreq = cli_session_setup_spnego_send( - state, ev, cli, user, pass, workgroup, remote_realm); + state, ev, cli, user, pass, workgroup); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } -- 1.9.1 From b0a6df17f5c5105bc7ba217f6b2a86bb6d91f9d1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 14:58:30 +0100 Subject: [PATCH 083/323] s3:libsmb: make use of cli_session_setup_gensec*() for Kerberos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pares a fix for https://bugzilla.samba.org/show_bug.cgi?id=10288 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 0e1b2ebf884c6f2033b3b9aa7b6f72af54a716b2) --- source3/libsmb/cliconnect.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 84ad783..a4e4828 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1270,7 +1270,7 @@ static void use_in_memory_ccache(void) { /**************************************************************************** Do a spnego/kerberos encrypted session setup. ****************************************************************************/ - +#if 0 struct cli_session_setup_kerberos_state { struct cli_state *cli; DATA_BLOB negTokenTarg; @@ -1407,7 +1407,7 @@ static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req) tevent_req_received(req); return ADS_SUCCESS; } - +#endif #endif /* HAVE_KRB5 */ /**************************************************************************** @@ -2000,8 +2000,11 @@ static struct tevent_req *cli_session_setup_spnego_send( } if (principal) { - subreq = cli_session_setup_kerberos_send( - state, ev, cli, principal); + subreq = cli_session_setup_gensec_send( + state, ev, cli, + state->account, pass, user_domain, + CRED_MUST_USE_KERBEROS, + "cifs", state->target_hostname, principal); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -2034,9 +2037,11 @@ static void cli_session_setup_spnego_done_krb(struct tevent_req *subreq) subreq, struct tevent_req); struct cli_session_setup_spnego_state *state = tevent_req_data( req, struct cli_session_setup_spnego_state); + NTSTATUS status; - state->result = cli_session_setup_kerberos_recv(subreq); + status = cli_session_setup_gensec_recv(subreq); TALLOC_FREE(subreq); + state->result = ADS_ERROR_NT(status); if (ADS_ERR_OK(state->result) || !state->cli->fallback_after_kerberos) { -- 1.9.1 From b1bad3c9c0bd03ec832987e894bcbba1ff3cf5a2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 07:27:16 +0100 Subject: [PATCH 084/323] s3:libsmb: remove unused cli_session_setup_kerberos*() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 95b953950d1fd454121ff23a43a8b13a34385ef1) --- source3/libsmb/cliconnect.c | 141 -------------------------------------------- 1 file changed, 141 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index a4e4828..97d0352 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1267,147 +1267,6 @@ static void use_in_memory_ccache(void) { setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1); } -/**************************************************************************** - Do a spnego/kerberos encrypted session setup. -****************************************************************************/ -#if 0 -struct cli_session_setup_kerberos_state { - struct cli_state *cli; - DATA_BLOB negTokenTarg; - DATA_BLOB session_key_krb5; - ADS_STATUS ads_status; -}; - -static void cli_session_setup_kerberos_done(struct tevent_req *subreq); - -static struct tevent_req *cli_session_setup_kerberos_send( - TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, - const char *principal) -{ - struct tevent_req *req, *subreq; - struct cli_session_setup_kerberos_state *state; - int rc; - - DEBUG(2,("Doing kerberos session setup\n")); - - req = tevent_req_create(mem_ctx, &state, - struct cli_session_setup_kerberos_state); - if (req == NULL) { - return NULL; - } - state->cli = cli; - state->ads_status = ADS_SUCCESS; - - /* - * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if - * we have to acquire a ticket. To be fixed later :-) - */ - rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg, - &state->session_key_krb5, 0, NULL, NULL); - if (rc) { - NTSTATUS status; - - state->ads_status = ADS_ERROR_KRB5(rc); - status = ads_ntstatus(state->ads_status); - if (NT_STATUS_EQUAL(status, NT_STATUS_UNSUCCESSFUL)) { - status = NT_STATUS_LOGON_FAILURE; - state->ads_status = ADS_ERROR_NT(status); - } - DEBUG(1, ("cli_session_setup_kerberos: " - "spnego_gen_krb5_negTokenInit failed: %s - %s\n", - error_message(rc), nt_errstr(status))); - tevent_req_nterror(req, status); - return tevent_req_post(req, ev); - } - -#if 0 - file_save("negTokenTarg.dat", state->negTokenTarg.data, - state->negTokenTarg.length); -#endif - - if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { - state->cli->smb2.session = smbXcli_session_create(cli, - cli->conn); - if (tevent_req_nomem(state->cli->smb2.session, req)) { - return tevent_req_post(req, ev); - } - } - - subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req); - return req; -} - -static void cli_session_setup_kerberos_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct cli_session_setup_kerberos_state *state = tevent_req_data( - req, struct cli_session_setup_kerberos_state); - uint8_t *inbuf = NULL; - struct iovec *recv_iov = NULL; - NTSTATUS status; - - status = cli_sesssetup_blob_recv(subreq, state, - NULL, &inbuf, &recv_iov); - TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - return; - } - - if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { - struct smbXcli_session *session = state->cli->smb2.session; - status = smb2cli_session_set_session_key(session, - state->session_key_krb5, - recv_iov); - if (tevent_req_nterror(req, status)) { - return; - } - } else { - struct smbXcli_session *session = state->cli->smb1.session; - - status = smb1cli_session_set_session_key(session, - state->session_key_krb5); - if (tevent_req_nterror(req, status)) { - return; - } - - if (smb1cli_conn_activate_signing(state->cli->conn, state->session_key_krb5, - data_blob_null) - && !smb1cli_conn_check_signing(state->cli->conn, inbuf, 1)) { - tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); - return; - } - } - - tevent_req_done(req); -} - -static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req) -{ - struct cli_session_setup_kerberos_state *state = tevent_req_data( - req, struct cli_session_setup_kerberos_state); - NTSTATUS status; - - if (tevent_req_is_nterror(req, &status)) { - ADS_STATUS ads = state->ads_status; - - if (!ADS_ERR_OK(state->ads_status)) { - ads = state->ads_status; - } else { - ads = ADS_ERROR_NT(status); - } - tevent_req_received(req); - return ads; - } - tevent_req_received(req); - return ADS_SUCCESS; -} -#endif #endif /* HAVE_KRB5 */ /**************************************************************************** -- 1.9.1 From 300510f74eea46084da98223c7a6da1ab733a9b8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 2 Mar 2016 07:27:41 +0100 Subject: [PATCH 085/323] s3:libsmb: remove unused functions in clispnego.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 14335018229801dd6d2b18f8d19ab5b45b8394fc) --- source3/include/proto.h | 19 --- source3/libsmb/clispnego.c | 282 --------------------------------------------- 2 files changed, 301 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index f6e9b77..3d59690 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -693,13 +693,6 @@ bool wins_server_tag_ips(const char *tag, TALLOC_CTX *mem_ctx, struct in_addr **pservers, int *pnum_servers); unsigned wins_srv_count_tag(const char *tag); -/* The following definitions come from libsmb/clispnego.c */ - -DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx, - const char *OIDs[], - DATA_BLOB *psecblob, - const char *principal); - #ifndef ASN1_MAX_OIDS #define ASN1_MAX_OIDS 20 #endif @@ -709,18 +702,6 @@ bool spnego_parse_negTokenInit(TALLOC_CTX *ctx, char **principal, DATA_BLOB *secblob); DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const uint8_t tok_id[2]); -int spnego_gen_krb5_negTokenInit(TALLOC_CTX *ctx, - const char *principal, int time_offset, - DATA_BLOB *targ, - DATA_BLOB *session_key_krb5, uint32_t extra_ap_opts, - const char *ccname, time_t *expire_time); -bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob, - DATA_BLOB *chal1, DATA_BLOB *chal2); -DATA_BLOB spnego_gen_auth(TALLOC_CTX *ctx, DATA_BLOB blob); -bool spnego_parse_auth_response(TALLOC_CTX *ctx, - DATA_BLOB blob, NTSTATUS nt_status, - const char *mechOID, - DATA_BLOB *auth); /* The following definitions come from libsmb/conncache.c */ diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 9aab8fd..4a0fbcd 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -26,81 +26,6 @@ #include "../lib/util/asn1.h" /* - generate a negTokenInit packet given a list of supported - OIDs (the mechanisms) a blob, and a principal name string -*/ - -DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx, - const char *OIDs[], - DATA_BLOB *psecblob, - const char *principal) -{ - int i; - ASN1_DATA *data; - DATA_BLOB ret = data_blob_null; - - data = asn1_init(talloc_tos()); - if (data == NULL) { - return data_blob_null; - } - - if (!asn1_push_tag(data,ASN1_APPLICATION(0))) goto err; - if (!asn1_write_OID(data,OID_SPNEGO)) goto err; - if (!asn1_push_tag(data,ASN1_CONTEXT(0))) goto err; - if (!asn1_push_tag(data,ASN1_SEQUENCE(0))) goto err; - - if (!asn1_push_tag(data,ASN1_CONTEXT(0))) goto err; - if (!asn1_push_tag(data,ASN1_SEQUENCE(0))) goto err; - for (i=0; OIDs[i]; i++) { - if (!asn1_write_OID(data,OIDs[i])) goto err; - } - if (!asn1_pop_tag(data)) goto err; - if (!asn1_pop_tag(data)) goto err; - - if (psecblob && psecblob->length && psecblob->data) { - if (!asn1_push_tag(data, ASN1_CONTEXT(2))) goto err; - if (!asn1_write_OctetString(data,psecblob->data, - psecblob->length)) goto err; - if (!asn1_pop_tag(data)) goto err; - } - - if (principal) { - if (!asn1_push_tag(data, ASN1_CONTEXT(3))) goto err; - if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err; - if (!asn1_push_tag(data, ASN1_CONTEXT(0))) goto err; - if (!asn1_write_GeneralString(data,principal)) goto err; - if (!asn1_pop_tag(data)) goto err; - if (!asn1_pop_tag(data)) goto err; - if (!asn1_pop_tag(data)) goto err; - } - - if (!asn1_pop_tag(data)) goto err; - if (!asn1_pop_tag(data)) goto err; - - if (!asn1_pop_tag(data)) goto err; - - if (!asn1_extract_blob(data, ctx, &ret)) { - goto err; - } - - asn1_free(data); - data = NULL; - - err: - - if (data != NULL) { - if (asn1_has_error(data)) { - DEBUG(1, ("Failed to build negTokenInit at offset %d\n", - (int)asn1_current_ofs(data))); - } - - asn1_free(data); - } - - return ret; -} - -/* parse a negTokenInit packet giving a GUID, a list of supported OIDs (the mechanisms) and a principal name string */ @@ -278,210 +203,3 @@ DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const ui return ret; } - -/* - generate a SPNEGO krb5 negTokenInit packet, ready for a EXTENDED_SECURITY - kerberos session setup -*/ -int spnego_gen_krb5_negTokenInit(TALLOC_CTX *ctx, - const char *principal, int time_offset, - DATA_BLOB *targ, - DATA_BLOB *session_key_krb5, uint32_t extra_ap_opts, - const char *ccname, time_t *expire_time) -{ - int retval; - DATA_BLOB tkt, tkt_wrapped; - const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, OID_NTLMSSP, NULL}; - - /* get a kerberos ticket for the service and extract the session key */ - retval = cli_krb5_get_ticket(ctx, principal, time_offset, - &tkt, session_key_krb5, - extra_ap_opts, ccname, - expire_time, NULL); - if (retval) { - return retval; - } - - /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap(ctx, tkt, TOK_ID_KRB_AP_REQ); - - /* and wrap that in a shiny SPNEGO wrapper */ - *targ = spnego_gen_negTokenInit(ctx, krb_mechs, &tkt_wrapped, NULL); - - data_blob_free(&tkt_wrapped); - data_blob_free(&tkt); - - return retval; -} - - -/* - parse a spnego NTLMSSP challenge packet giving two security blobs -*/ -bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob, - DATA_BLOB *chal1, DATA_BLOB *chal2) -{ - bool ret = false; - ASN1_DATA *data; - - ZERO_STRUCTP(chal1); - ZERO_STRUCTP(chal2); - - data = asn1_init(talloc_tos()); - if (data == NULL) { - return false; - } - - if (!asn1_load(data, blob)) goto err; - if (!asn1_start_tag(data,ASN1_CONTEXT(1))) goto err; - if (!asn1_start_tag(data,ASN1_SEQUENCE(0))) goto err; - - if (!asn1_start_tag(data,ASN1_CONTEXT(0))) goto err; - if (!asn1_check_enumerated(data,1)) goto err; - if (!asn1_end_tag(data)) goto err; - - if (!asn1_start_tag(data,ASN1_CONTEXT(1))) goto err; - if (!asn1_check_OID(data, OID_NTLMSSP)) goto err; - if (!asn1_end_tag(data)) goto err; - - if (!asn1_start_tag(data,ASN1_CONTEXT(2))) goto err; - if (!asn1_read_OctetString(data, ctx, chal1)) goto err; - if (!asn1_end_tag(data)) goto err; - - /* the second challenge is optional (XP doesn't send it) */ - if (asn1_tag_remaining(data) > 0) { - if (!asn1_start_tag(data,ASN1_CONTEXT(3))) goto err; - if (!asn1_read_OctetString(data, ctx, chal2)) goto err; - if (!asn1_end_tag(data)) goto err; - } - - if (!asn1_end_tag(data)) goto err; - if (!asn1_end_tag(data)) goto err; - - ret = !asn1_has_error(data); - - err: - - if (asn1_has_error(data)) { - data_blob_free(chal1); - data_blob_free(chal2); - } - - asn1_free(data); - return ret; -} - - -/* - generate a SPNEGO auth packet. This will contain the encrypted passwords -*/ -DATA_BLOB spnego_gen_auth(TALLOC_CTX *ctx, DATA_BLOB blob) -{ - ASN1_DATA *data; - DATA_BLOB ret = data_blob_null; - - data = asn1_init(talloc_tos()); - if (data == NULL) { - return data_blob_null; - } - - if (!asn1_push_tag(data, ASN1_CONTEXT(1))) goto err; - if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err; - if (!asn1_push_tag(data, ASN1_CONTEXT(2))) goto err; - if (!asn1_write_OctetString(data,blob.data,blob.length)) goto err; - if (!asn1_pop_tag(data)) goto err; - if (!asn1_pop_tag(data)) goto err; - if (!asn1_pop_tag(data)) goto err; - - if (!asn1_extract_blob(data, ctx, &ret)) { - goto err; - } - - err: - - asn1_free(data); - - return ret; -} - -/* - parse a SPNEGO auth packet. This contains the encrypted passwords -*/ -bool spnego_parse_auth_response(TALLOC_CTX *ctx, - DATA_BLOB blob, NTSTATUS nt_status, - const char *mechOID, - DATA_BLOB *auth) -{ - ASN1_DATA *data; - uint8_t negResult; - bool ret = false; - - if (NT_STATUS_IS_OK(nt_status)) { - negResult = SPNEGO_ACCEPT_COMPLETED; - } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - negResult = SPNEGO_ACCEPT_INCOMPLETE; - } else { - negResult = SPNEGO_REJECT; - } - - data = asn1_init(talloc_tos()); - if (data == NULL) { - return false; - } - - *auth = data_blob_null; - - if (!asn1_load(data, blob)) goto err; - if (!asn1_start_tag(data, ASN1_CONTEXT(1))) goto err; - if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto err; - if (!asn1_start_tag(data, ASN1_CONTEXT(0))) goto err; - if (!asn1_check_enumerated(data, negResult)) goto err; - if (!asn1_end_tag(data)) goto err; - - if (asn1_tag_remaining(data) > 0) { - if (!asn1_start_tag(data,ASN1_CONTEXT(1))) goto err; - if (!asn1_check_OID(data, mechOID)) goto err; - if (!asn1_end_tag(data)) goto err; - - if (asn1_tag_remaining(data) > 0) { - if (!asn1_start_tag(data,ASN1_CONTEXT(2))) goto err; - if (!asn1_read_OctetString(data, ctx, auth)) goto err; - if (!asn1_end_tag(data)) goto err; - } - } else if (negResult == SPNEGO_ACCEPT_INCOMPLETE) { - asn1_set_error(data); - goto err; - } - - /* Binding against Win2K DC returns a duplicate of the responseToken in - * the optional mechListMIC field. This is a bug in Win2K. We ignore - * this field if it exists. Win2K8 may return a proper mechListMIC at - * which point we need to implement the integrity checking. */ - if (asn1_tag_remaining(data) > 0) { - DATA_BLOB mechList = data_blob_null; - if (!asn1_start_tag(data, ASN1_CONTEXT(3))) goto err; - if (!asn1_read_OctetString(data, ctx, &mechList)) goto err; - data_blob_free(&mechList); - if (!asn1_end_tag(data)) goto err; - DEBUG(5,("spnego_parse_auth_response received mechListMIC, " - "ignoring.\n")); - } - - if (!asn1_end_tag(data)) goto err; - if (!asn1_end_tag(data)) goto err; - - ret = !asn1_has_error(data); - - err: - - if (asn1_has_error(data)) { - DEBUG(3, ("spnego_parse_auth_response failed at %d\n", - (int)asn1_current_ofs(data))); - asn1_free(data); - data_blob_free(auth); - return false; - } - - asn1_free(data); - return ret; -} -- 1.9.1 From fca9921cabd497f0026e9afaf23cb92e7ef4ebbc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 17 Dec 2015 08:55:03 +0100 Subject: [PATCH 086/323] s4:torture/rpc: do testjoin only via ncalrpc or ncacn_np MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ncacn_ip_tcp doesn't have the required session key. It used to be the wellknown "SystemLibraryDTC" constant, but that's not available in modern systems anymore. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 0400f301e3bcf495748cff009755426a040596fa) --- source4/torture/rpc/testjoin.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c index 5ee2c2a..7fbf301 100644 --- a/source4/torture/rpc/testjoin.c +++ b/source4/torture/rpc/testjoin.c @@ -503,10 +503,36 @@ _PUBLIC_ struct test_join *torture_join_domain(struct torture_context *tctx, struct test_join *tj; struct samr_SetUserInfo s; union samr_UserInfo u; - + const char *binding_str = NULL; + struct dcerpc_binding *binding = NULL; + enum dcerpc_transport_t transport; + tj = talloc_zero(tctx, struct test_join); if (!tj) return NULL; + binding_str = torture_setting_string(tctx, "binding", NULL); + if (binding_str == NULL) { + const char *host = torture_setting_string(tctx, "host", NULL); + binding_str = talloc_asprintf(tj, "ncacn_np:%s", host); + } + status = dcerpc_parse_binding(tj, binding_str, &binding); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("dcerpc_parse_binding(%s) failed - %s\n", + binding_str, nt_errstr(status))); + talloc_free(tj); + return NULL; + } + transport = dcerpc_binding_get_transport(binding); + switch (transport) { + case NCALRPC: + case NCACN_UNIX_STREAM: + break; + default: + dcerpc_binding_set_transport(binding, NCACN_NP); + dcerpc_binding_set_flags(binding, 0, DCERPC_AUTH_OPTIONS); + break; + } + libnet_r = talloc_zero(tj, struct libnet_JoinDomain); if (!libnet_r) { talloc_free(tj); @@ -522,9 +548,10 @@ _PUBLIC_ struct test_join *torture_join_domain(struct torture_context *tctx, tj->libnet_r = libnet_r; libnet_ctx->cred = cmdline_credentials; - libnet_r->in.binding = torture_setting_string(tctx, "binding", NULL); - if (!libnet_r->in.binding) { - libnet_r->in.binding = talloc_asprintf(libnet_r, "ncacn_np:%s", torture_setting_string(tctx, "host", NULL)); + libnet_r->in.binding = dcerpc_binding_string(libnet_r, binding); + if (libnet_r->in.binding == NULL) { + talloc_free(tj); + return NULL; } libnet_r->in.level = LIBNET_JOINDOMAIN_SPECIFIED; libnet_r->in.netbios_name = machine_name; -- 1.9.1 From abd7e59eac9a37c66787b82f80d1df74bb13b8cb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Feb 2016 07:47:39 +0100 Subject: [PATCH 087/323] s4:torture: the backupkey tests need to use ncacn_np: for LSA calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit c793b23ddb7c048110bc4718574e5b99d5bbcfae) --- source4/torture/rpc/backupkey.c | 19 ++++++++++++++++--- source4/torture/rpc/backupkey_heimdal.c | 19 ++++++++++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/source4/torture/rpc/backupkey.c b/source4/torture/rpc/backupkey.c index aaff59f..ca981c2 100644 --- a/source4/torture/rpc/backupkey.c +++ b/source4/torture/rpc/backupkey.c @@ -1770,8 +1770,10 @@ static bool test_ServerWrap_encrypt_decrypt_manual(struct torture_context *tctx, struct bkrp_server_side_wrapped *server_side_wrapped, enum test_wrong wrong) { - struct dcerpc_pipe *lsa_p; - struct dcerpc_binding_handle *lsa_b; + char *lsa_binding_string = NULL; + struct dcerpc_binding *lsa_binding = NULL; + struct dcerpc_pipe *lsa_p = NULL; + struct dcerpc_binding_handle *lsa_b = NULL; struct lsa_OpenSecret r_secret; struct lsa_QuerySecret r_query_secret; struct policy_handle *handle, sec_handle; @@ -1800,8 +1802,19 @@ static bool test_ServerWrap_encrypt_decrypt_manual(struct torture_context *tctx, /* Now read BCKUPKEY_P and prove we can do a matching decrypt and encrypt */ + /* lsa_OpenSecret only works with ncacn_np and AUTH_LEVEL_NONE */ + lsa_binding_string = talloc_asprintf(tctx, "ncacn_np:%s", + torture_setting_string(tctx, "host", NULL)); + torture_assert(tctx, lsa_binding_string != NULL, "lsa_binding_string"); + + torture_assert_ntstatus_ok(tctx, + dcerpc_parse_binding(tctx, lsa_binding_string, &lsa_binding), + "Failed to parse dcerpc binding"); + torture_assert_ntstatus_ok(tctx, - torture_rpc_connection(tctx, &lsa_p, &ndr_table_lsarpc), + dcerpc_pipe_connect_b(tctx, &lsa_p, + lsa_binding, &ndr_table_lsarpc, + cmdline_credentials, tctx->ev, tctx->lp_ctx), "Opening LSA pipe"); lsa_b = lsa_p->binding_handle; diff --git a/source4/torture/rpc/backupkey_heimdal.c b/source4/torture/rpc/backupkey_heimdal.c index 9c388c0..042cd23 100644 --- a/source4/torture/rpc/backupkey_heimdal.c +++ b/source4/torture/rpc/backupkey_heimdal.c @@ -1544,8 +1544,10 @@ static bool test_ServerWrap_encrypt_decrypt_manual(struct torture_context *tctx, struct bkrp_server_side_wrapped *server_side_wrapped, enum test_wrong wrong) { - struct dcerpc_pipe *lsa_p; - struct dcerpc_binding_handle *lsa_b; + char *lsa_binding_string = NULL; + struct dcerpc_binding *lsa_binding = NULL; + struct dcerpc_pipe *lsa_p = NULL; + struct dcerpc_binding_handle *lsa_b = NULL; struct lsa_OpenSecret r_secret; struct lsa_QuerySecret r_query_secret; struct policy_handle *handle, sec_handle; @@ -1571,8 +1573,19 @@ static bool test_ServerWrap_encrypt_decrypt_manual(struct torture_context *tctx, /* Now read BCKUPKEY_P and prove we can do a matching decrypt and encrypt */ + /* lsa_OpenSecret only works with ncacn_np and AUTH_LEVEL_NONE */ + lsa_binding_string = talloc_asprintf(tctx, "ncacn_np:%s", + torture_setting_string(tctx, "host", NULL)); + torture_assert(tctx, lsa_binding_string != NULL, "lsa_binding_string"); + + torture_assert_ntstatus_ok(tctx, + dcerpc_parse_binding(tctx, lsa_binding_string, &lsa_binding), + "Failed to parse dcerpc binding"); + torture_assert_ntstatus_ok(tctx, - torture_rpc_connection(tctx, &lsa_p, &ndr_table_lsarpc), + dcerpc_pipe_connect_b(tctx, &lsa_p, + lsa_binding, &ndr_table_lsarpc, + cmdline_credentials, tctx->ev, tctx->lp_ctx), "Opening LSA pipe"); lsa_b = lsa_p->binding_handle; -- 1.9.1 From a7c2f9c00d553896689cfd63b5edebd0ad4d4350 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 20:18:42 +0100 Subject: [PATCH 088/323] s4:selftest: run rpc.samr over ncacn_np instead of ncacn_ip_tcp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It requires a transport session key, which is only reliable available over SMB. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit f699eb3b1a0660ace3ca99d3f3b5d79ed5537c80) --- source4/selftest/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index dc9bed9..98d9058 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -96,8 +96,8 @@ ncacn_np_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.alt ncalrpc_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.drsuapi", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] drs_rpc_tests = smbtorture4_testsuites("drs.rpc") ncacn_ip_tcp_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.netlogon", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext", "rpc.samr.passwords.validate"] + drs_rpc_tests -slow_ncacn_np_tests = ["rpc.samlogon", "rpc.samr.users", "rpc.samr.large-dc", "rpc.samr.users.privileges", "rpc.samr.passwords", "rpc.samr.passwords.pwdlastset", "rpc.samr.passwords.lockout", "rpc.samr.passwords.badpwdcount"] -slow_ncacn_ip_tcp_tests = ["rpc.samr", "rpc.cracknames"] +slow_ncacn_np_tests = ["rpc.samlogon", "rpc.samr", "rpc.samr.users", "rpc.samr.large-dc", "rpc.samr.users.privileges", "rpc.samr.passwords", "rpc.samr.passwords.pwdlastset", "rpc.samr.passwords.lockout", "rpc.samr.passwords.badpwdcount"] +slow_ncacn_ip_tcp_tests = ["rpc.cracknames"] all_rpc_tests = ncalrpc_tests + ncacn_np_tests + ncacn_ip_tcp_tests + slow_ncacn_np_tests + slow_ncacn_ip_tcp_tests + ["rpc.lsa.secrets", "rpc.pac", "rpc.samba3-sharesec", "rpc.countcalls"] -- 1.9.1 From 8d92529a9268812d8085948cbb6bebcbac70de39 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 22:44:24 +0100 Subject: [PATCH 089/323] s4:torture:samba3rpc: use an authenticated SMB connection and an anonymous DCERPC connection on top MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the only way to get a reliable transport session key. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit af8c4ebf9be314ddd13ef9ca17a0237927dd2ede) --- source4/torture/rpc/samba3rpc.c | 55 ++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 36 deletions(-) diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index ade4a40..5f3f3d5 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -1362,7 +1362,6 @@ static bool torture_netlogon_samba3(struct torture_context *torture) { NTSTATUS status; struct smbcli_state *cli; - struct cli_credentials *anon_creds; struct cli_credentials *wks_creds; const char *wks_name; int i; @@ -1374,10 +1373,6 @@ static bool torture_netlogon_samba3(struct torture_context *torture) wks_name = get_myname(torture); } - if (!(anon_creds = cli_credentials_init_anon(torture))) { - torture_fail(torture, "create_anon_creds failed\n"); - } - lpcfg_smbcli_options(torture->lp_ctx, &options); lpcfg_smbcli_session_options(torture->lp_ctx, &session_options); @@ -1386,7 +1381,7 @@ static bool torture_netlogon_samba3(struct torture_context *torture) lpcfg_smb_ports(torture->lp_ctx), "IPC$", NULL, lpcfg_socket_options(torture->lp_ctx), - anon_creds, + cmdline_credentials, lpcfg_resolve_context(torture->lp_ctx), torture->ev, &options, &session_options, lpcfg_gensec_settings(torture, torture->lp_ctx)); @@ -1406,7 +1401,7 @@ static bool torture_netlogon_samba3(struct torture_context *torture) CRED_SPECIFIED); torture_assert(torture, - join3(torture, cli, false, cmdline_credentials, wks_creds), + join3(torture, cli, false, NULL, wks_creds), "join failed"); cli_credentials_set_domain( @@ -1433,7 +1428,7 @@ static bool torture_netlogon_samba3(struct torture_context *torture) } torture_assert(torture, - leave(torture, cli, cmdline_credentials, wks_creds), + leave(torture, cli, NULL, wks_creds), "leave failed"); return true; @@ -1532,26 +1527,14 @@ static bool torture_samba3_sessionkey(struct torture_context *torture) } torture_assert(torture, - test_join3(torture, false, anon_creds, cmdline_credentials, wks_name), - "join using ntlmssp bind on an anonymous smb connection failed"); - - torture_assert(torture, test_join3(torture, false, cmdline_credentials, NULL, wks_name), "join using anonymous bind on an authenticated smb connection failed"); - torture_assert(torture, - test_join3(torture, false, cmdline_credentials, cmdline_credentials, wks_name), - "join using ntlmssp bind on an authenticated smb connection failed"); - /* * The following two are tests for setuserinfolevel 25 */ torture_assert(torture, - test_join3(torture, true, anon_creds, cmdline_credentials, wks_name), - "join using ntlmssp bind on an anonymous smb connection failed"); - - torture_assert(torture, test_join3(torture, true, cmdline_credentials, NULL, wks_name), "join using anonymous bind on an authenticated smb connection failed"); @@ -1799,20 +1782,6 @@ static bool torture_samba3_rpc_getusername(struct torture_context *torture) lpcfg_smbcli_options(torture->lp_ctx, &options); lpcfg_smbcli_session_options(torture->lp_ctx, &session_options); - status = smbcli_full_connection( - torture, &cli, torture_setting_string(torture, "host", NULL), - lpcfg_smb_ports(torture->lp_ctx), - "IPC$", NULL, lpcfg_socket_options(torture->lp_ctx), cmdline_credentials, - lpcfg_resolve_context(torture->lp_ctx), torture->ev, &options, - &session_options, lpcfg_gensec_settings(torture, torture->lp_ctx)); - torture_assert_ntstatus_ok(torture, status, "smbcli_full_connection failed\n"); - - if (!(user_sid = whoami(torture, torture, cli->tree))) { - torture_fail(torture, "whoami on auth'ed connection failed\n"); - } - - talloc_free(cli); - if (!(anon_creds = cli_credentials_init_anon(torture))) { torture_fail(torture, "create_anon_creds failed\n"); } @@ -1833,6 +1802,20 @@ static bool torture_samba3_rpc_getusername(struct torture_context *torture) torture_assert_sid_equal(torture, user_sid, dom_sid_parse_talloc(torture, "s-1-5-7"), "Anon lsa_GetUserName returned unexpected SID"); + talloc_free(cli); + + status = smbcli_full_connection( + torture, &cli, torture_setting_string(torture, "host", NULL), + lpcfg_smb_ports(torture->lp_ctx), + "IPC$", NULL, lpcfg_socket_options(torture->lp_ctx), cmdline_credentials, + lpcfg_resolve_context(torture->lp_ctx), torture->ev, &options, + &session_options, lpcfg_gensec_settings(torture, torture->lp_ctx)); + torture_assert_ntstatus_ok(torture, status, "smbcli_full_connection failed\n"); + + if (!(user_sid = whoami(torture, torture, cli->tree))) { + torture_fail(torture, "whoami on auth'ed connection failed\n"); + } + if (!(user_creds = cli_credentials_init(torture))) { torture_fail(torture, "cli_credentials_init failed\n"); } @@ -1844,7 +1827,7 @@ static bool torture_samba3_rpc_getusername(struct torture_context *torture) generate_random_password(user_creds, 8, 255), CRED_SPECIFIED); - if (!create_user(torture, torture, cli, cmdline_credentials, + if (!create_user(torture, torture, cli, NULL, cli_credentials_get_username(user_creds), cli_credentials_get_password(user_creds), &domain_name, &created_sid)) { @@ -1899,7 +1882,7 @@ static bool torture_samba3_rpc_getusername(struct torture_context *torture) del: if (!delete_user(torture, cli, - cmdline_credentials, + NULL, cli_credentials_get_username(user_creds))) { torture_fail(torture, "delete_user failed\n"); } -- 1.9.1 From 09516e3e545c23ff2a179d014fb617305d64cd45 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 Nov 2015 10:25:10 +0100 Subject: [PATCH 090/323] s4:librpc/rpc: dcerpc_generic_session_key() should only be available on local transports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 5a397216d40ff18fd1c0980cd9b7b7c0a970bbbb) --- selftest/knownfail | 4 ++++ source4/librpc/rpc/dcerpc_util.c | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/selftest/knownfail b/selftest/knownfail index 77d186c..eb2f0ba 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -86,6 +86,9 @@ ^samba4.rpc.lsalookup with seal,padcheck ^samba4.rpc.lsalookup with validate ^samba4.rpc.lsalookup with bigendian +^samba4.rpc.lsa on ncacn_np with seal # This gives NT_STATUS_LOCAL_USER_SESSION_KEY +^samba4.rpc.lsa with seal # This gives NT_STATUS_LOCAL_USER_SESSION_KEY +^samba4.rpc.lsa.secrets.*seal # This gives NT_STATUS_LOCAL_USER_SESSION_KEY ^samba4.rpc.netlogon.*.LogonUasLogon ^samba4.rpc.netlogon.*.LogonUasLogoff ^samba4.rpc.netlogon.*.DatabaseSync @@ -208,6 +211,7 @@ ^samba3.smb2.replay.replay4 ^samba3.smb2.lock.*replay ^samba3.raw.session.*reauth2 # maybe fix this? +^samba3.rpc.lsa.secrets.seal # This gives NT_STATUS_LOCAL_USER_SESSION_KEY ^samba3.rpc.samr.passwords.badpwdcount.samr.badPwdCount\(nt4_dc\) # We fail this test currently ^samba3.rpc.samr.passwords.lockout.*\(nt4_dc\)$ # We fail this test currently ^samba3.rpc.spoolss.printer.addprinter.driver_info_winreg # knownfail or flapping? diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index ff3e60e..9adaa61 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -776,6 +776,16 @@ _PUBLIC_ NTSTATUS dcerpc_pipe_auth(TALLOC_CTX *mem_ctx, NTSTATUS dcerpc_generic_session_key(struct dcecli_connection *c, DATA_BLOB *session_key) { + *session_key = data_blob_null; + + if (c != NULL) { + if (c->transport.transport != NCALRPC && + c->transport.transport != NCACN_UNIX_STREAM) + { + return NT_STATUS_LOCAL_USER_SESSION_KEY; + } + } + /* this took quite a few CPU cycles to find ... */ session_key->data = discard_const_p(unsigned char, "SystemLibraryDTC"); session_key->length = 16; -- 1.9.1 From b212e2ebcb50e5dc25264f9e0421a50278540a32 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Feb 2016 16:41:10 +0100 Subject: [PATCH 091/323] s4:rpc_server/samr: hide a possible NO_USER_SESSION_KEY error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Windows servers doesn't return the raw NT_STATUS_NO_USER_SESSION_KEY error, but return WRONG_PASSWORD or even hide the error by using a random session key, that results in an invalid, unknown, random NTHASH. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett (cherry picked from commit 58b33896b65c5b51486eaf01f5f935ace2369fd0) --- source4/rpc_server/samr/samr_password.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c index 1466dec..f053dad 100644 --- a/source4/rpc_server/samr/samr_password.c +++ b/source4/rpc_server/samr/samr_password.c @@ -419,7 +419,10 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call, nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; + DEBUG(3,("samr: failed to get session key: %s " + "=> NT_STATUS_WRONG_PASSWORD\n", + nt_errstr(nt_status))); + return NT_STATUS_WRONG_PASSWORD; } arcfour_crypt_blob(pwbuf->data, 516, &session_key); @@ -458,7 +461,10 @@ NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call, nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; + DEBUG(3,("samr: failed to get session key: %s " + "=> NT_STATUS_WRONG_PASSWORD\n", + nt_errstr(nt_status))); + return NT_STATUS_WRONG_PASSWORD; } co_session_key = data_blob_talloc(mem_ctx, NULL, 16); @@ -500,11 +506,26 @@ NTSTATUS samr_set_password_buffers(struct dcesrv_call_state *dce_call, const uint8_t *nt_pwd_hash) { struct samr_Password *d_lm_pwd_hash = NULL, *d_nt_pwd_hash = NULL; + uint8_t random_session_key[16] = { 0, }; DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB in, out; NTSTATUS nt_status = NT_STATUS_OK; nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_USER_SESSION_KEY)) { + DEBUG(3,("samr: failed to get session key: %s " + "=> use a random session key\n", + nt_errstr(nt_status))); + + /* + * Windows just uses a random key + */ + generate_random_buffer(random_session_key, + sizeof(random_session_key)); + session_key = data_blob_const(random_session_key, + sizeof(random_session_key)); + nt_status = NT_STATUS_OK; + } if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } -- 1.9.1 From 6affd2bb771881fd8377b1d4a8d3a1f4f7e97861 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 Nov 2015 10:25:10 +0100 Subject: [PATCH 092/323] s4:rpc_server: dcesrv_generic_session_key should only work on local transports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches modern Windows servers. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Andrew Bartlett Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Thu Mar 10 10:15:21 CET 2016 on sn-devel-144 (cherry picked from commit 645e777b0aca7d997867e0b3f0b48bfb138cc25c) --- source4/rpc_server/common/reply.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index 59c289c..93bce7a 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -259,5 +259,12 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *c, DATA_BLOB *session_key) { + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(c->endpoint->ep_description); + + if (transport != NCALRPC && transport != NCACN_UNIX_STREAM) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + return dcerpc_generic_session_key(NULL, session_key); } -- 1.9.1 From 6cc6803d7df995a8542351718b2d29a84de82c37 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 16 Jan 2016 13:57:47 +0100 Subject: [PATCH 093/323] selftest: s!addc.samba.example.com!addom.samba.example.com! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's confusing to have addc.samba.example.com as domain name and addc.addc.samba.example.com as hostname. We now have addom.samba.example.com as domain name and addc.addom.samba.example.com as hostname. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit c561a42ff68bc4561147839e3a65951924f6af21) --- selftest/target/Samba4.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index fbefda7..d25e495 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -1879,7 +1879,7 @@ sub provision_ad_dc($$) "domain controller", "addc", "ADDOMAIN", - "addc.samba.example.com", + "addom.samba.example.com", "2008", "locDCpass1", undef, -- 1.9.1 From 165cc3ad0aec796c2065665624881fe61793845d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 01:06:05 +0100 Subject: [PATCH 094/323] selftest: add some helper scripts to mange a CA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is partly based on the SmartCard HowTo from: https://wiki.samba.org/index.php/Samba_AD_Smart_Card_Login BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit b0bdbeeef44259782c9941b5cfff7d4925e1f2f2) --- selftest/manage-ca/manage-ca.sh | 387 +++++++++++++++++++++ .../manage-CA-example.com.cnf | 17 + .../openssl-BASE-template.cnf | 201 +++++++++++ .../manage-ca.templates.d/openssl-CA-template.cnf | 2 + .../manage-ca.templates.d/openssl-DC-template.cnf | 49 +++ .../openssl-USER-template.cnf | 41 +++ 6 files changed, 697 insertions(+) create mode 100755 selftest/manage-ca/manage-ca.sh create mode 100644 selftest/manage-ca/manage-ca.templates.d/manage-CA-example.com.cnf create mode 100644 selftest/manage-ca/manage-ca.templates.d/openssl-BASE-template.cnf create mode 100644 selftest/manage-ca/manage-ca.templates.d/openssl-CA-template.cnf create mode 100644 selftest/manage-ca/manage-ca.templates.d/openssl-DC-template.cnf create mode 100644 selftest/manage-ca/manage-ca.templates.d/openssl-USER-template.cnf diff --git a/selftest/manage-ca/manage-ca.sh b/selftest/manage-ca/manage-ca.sh new file mode 100755 index 0000000..ab796b7 --- /dev/null +++ b/selftest/manage-ca/manage-ca.sh @@ -0,0 +1,387 @@ +#!/bin/bash +# + +set -e +set -u +#set -x + +umask 022 + +function print_usage() +{ + echo "Usage:" + echo "" + echo "${0} [ []]" + echo "" + echo "${0} init_ca" + echo "${0} update_crl" + echo "${0} publish_crl" + echo "${0} create_dc " + echo "${0} revoke_dc " + echo "${0} create_user " + echo "${0} revoke_user " + echo "" +} + +function check_arg() +{ + local k="${1}" + local v="${2}" + + test -n "${v}" || { + print_usage + echo "ERROR: CMD[${CMD}] argument <${k}> missing" + return 1 + } + + return 0 +} +CNF="${1-}" +test -n "${CNF}" || { + print_usage + echo "ERROR: speficy see manage-ca.templates.d/manage-CA-example.com.cnf" + exit 1 +} +test -e "${CNF}" || { + print_usage + echo "ERROR: CNF_FILE[${CNF}] does not exist" + exit 1 +} +CMD="${2-}" +CMDARG1="${3-}" +CMDARG2="${4-}" + +TEMPLATE_DIR="manage-ca.templates.d" +DEFAULT_VARS="" +DEFAULT_VARS="${DEFAULT_VARS} CRL_HTTP_BASE DNS_DOMAIN DEFAULT_BITS" +DEFAULT_VARS="${DEFAULT_VARS} DEFAULT_BITS DEFAULT_DAYS DEFAULT_CRL_DAYS" +DEFAULT_VARS="${DEFAULT_VARS} COUNTRY_NAME STATE_NAME LOCALITY_NAME ORGANIZATION_NAME" +DEFAULT_VARS="${DEFAULT_VARS} ORGANIZATIONAL_UNIT_NAME COMMON_NAME EMAIL_ADDRESS" + +source "${CNF}" + +DEFAULT_BITS=${DEFAULT_BITS:=8192} +CA_BITS=${CA_BITS:=${DEFAULT_BITS}} +DC_BITS=${DC_BITS:=${DEFAULT_BITS}} +USER_BITS=${USER_BITS:=${DEFAULT_BITS}} + +CA_DAYS=${CA_DAYS:=3650} +CRL_DAYS=${CRL_DAYS:=30} +DC_DAYS=${DC_DAYS:=730} +USER_DAYS=${USER_DAYS:=730} + +CA_DIR="CA-${DNS_DOMAIN}" +DEFAULT_VARS="${DEFAULT_VARS} CA_DIR" + +CACERT_PEM="${CA_DIR}/Public/CA-${DNS_DOMAIN}-cert.pem" +CACERT_CER="${CA_DIR}/Public/CA-${DNS_DOMAIN}-cert.cer" +CACRL_PEM="${CA_DIR}/Public/CA-${DNS_DOMAIN}-crl.pem" +CACRL_CRL="${CA_DIR}/Public/CA-${DNS_DOMAIN}-crl.crl" +CA_SERIAL="${CA_DIR}/Private/CA-${DNS_DOMAIN}-serial.txt" + +function generate_from_template() +{ + local base_template="${TEMPLATE_DIR}/$1" + local cmd_template="${TEMPLATE_DIR}/$2" + local cnf_file="$3" + shift 3 + local vars="$@" + + test -f "${base_template}" || { + echo "base_template[${base_template}] does not exists" + return 1 + } + test -f "${cmd_template}" || { + echo "cmd_template[${cmd_template}] does not exists" + return 1 + } + test -e "${cnf_file}" && { + echo "cnf_file[${cnf_file}] already exists" + return 1 + } + + local sedargs="" + for k in $vars; do + v=$(eval echo "\${${k}}") + sedargs="${sedargs} -e 's!@@${k}@@!${v}!g'" + done + + #echo "sedargs[${sedargs}]" + cat "${base_template}" "${cmd_template}" | eval sed ${sedargs} > "${cnf_file}" + grep '@@' "${cnf_file}" | wc -l | grep -q '^0' || { + echo "invalid context in cnf_file[${cnf_file}]" + grep '@@' "${cnf_file}" + return 1 + } + + return 0 +} + +case "${CMD}" in +init_ca) + test -e "${CA_DIR}" && { + echo "CA with CA_DIR[${CA_DIR}] already exists" + exit 1 + } + + OPENSSLCNF="${CA_DIR}/Private/CA-${DNS_DOMAIN}-openssl.cnf" + CA_INDEX="${CA_DIR}/Private/CA-${DNS_DOMAIN}-index.txt" + CA_CRLNUMBER="${CA_DIR}/Private/CA-${DNS_DOMAIN}-crlnumber.txt" + PRIVATEKEY="${CA_DIR}/Private/CA-${DNS_DOMAIN}-private-key.pem" + + ORGANIZATIONAL_UNIT_NAME="CA Administration" + COMMON_NAME="CA of ${DNS_DOMAIN}" + EMAIL_ADDRESS="ca-${DNS_DOMAIN}@${DNS_DOMAIN}" + + DEFAULT_BITS="${CA_BITS}" + DEFAULT_DAYS="1" + DEFAULT_CRL_DAYS="${CRL_DAYS}" + + mkdir -p "${CA_DIR}/"{,Public} + umask 077 + mkdir -p "${CA_DIR}/"{,Private,NewCerts,DCs,Users} + umask 022 + touch "${CA_INDEX}" + echo "00" > "${CA_SERIAL}" + echo "00" > "${CA_CRLNUMBER}" + + generate_from_template \ + "openssl-BASE-template.cnf" \ + "openssl-CA-template.cnf" \ + "${OPENSSLCNF}" \ + ${DEFAULT_VARS} + openssl req -new -x509 -sha256 -extensions v3_ca -days "${CA_DAYS}" -keyout "${PRIVATEKEY}" -out "${CACERT_PEM}" -config "${OPENSSLCNF}" + openssl x509 -in "${CACERT_PEM}" -inform PEM -out "${CACERT_CER}" -outform DER + echo -n "Generate CRL [ENTER] to continue" + read + openssl ca -config "${OPENSSLCNF}" -gencrl -out "${CACRL_PEM}" + openssl crl -in "${CACRL_PEM}" -inform PEM -out "${CACRL_CRL}" -outform DER + ls -la "${CA_DIR}"/Public/CA-* + echo "Please run: '${0} ${CNF} publish_crl'" + exit 0 + ;; +update_crl) + test -e "${CA_DIR}" || { + echo "CA with CA_DIR[${CA_DIR}] does not exists" + exit 1 + } + + OPENSSLCNF="${CA_DIR}/Private/CA-${DNS_DOMAIN}-openssl.cnf" + openssl ca -config "${OPENSSLCNF}" -gencrl -out "${CACRL_PEM}" + openssl crl -in "${CACRL_PEM}" -inform PEM -out "${CACRL_CRL}" -outform DER + ls -la "${CACRL_PEM}" "${CACRL_CRL}" + echo "Please run: '${0} ${CNF} publish_crl'" + exit 0 + ;; +publish_crl) + test -e "${CA_DIR}" || { + echo "CA with CA_DIR[${CA_DIR}] does not exists" + exit 1 + } + + echo "Upload ${CACRL_CRL} to ${CRL_SSH_BASE}/" + rsync -a -P "${CACRL_CRL}" "${CRL_SSH_BASE}/" + echo "Check ${CRL_HTTP_BASE}/CA-${DNS_DOMAIN}-crl.crl" + exit 0 + ;; +create_dc) + test -e "${CA_DIR}" || { + echo "CA with CA_DIR[${CA_DIR}] does not exists" + exit 1 + } + # + # + # ldbsearch -H ldap://DC_DNS_NAME '(dnsHostName=DC_DNS_NAME)' distinguishedName --controls=search_options:1:1 --controls=extended_dn:1:0 + DC_DNS_NAME="${CMDARG1}" + check_arg "DC_DNS_NAME" "${DC_DNS_NAME}" + DC_OBJECTGUID_HEX=$(echo "${CMDARG2}" | tr a-z A-Z) + check_arg "DC_OBJECTGUID_HEX" "${DC_OBJECTGUID_HEX}" + + DC_DIR="${CA_DIR}/DCs/${DC_DNS_NAME}" + test -e "${DC_DIR}" && { + echo "DC with DC_DIR[${DC_DIR}] already exists" + exit 1 + } + + NEXT_SERIAL=$(cat "${CA_SERIAL}" | xargs) + DCFILE_BASE="DC-${DC_DNS_NAME}-S${NEXT_SERIAL}" + OPENSSLCNF="${DC_DIR}/${DCFILE_BASE}-openssl.cnf" + DCKEY_PEM="${DC_DIR}/${DCFILE_BASE}-key.pem" + DCKEY_PRIVATE_PEM="${DC_DIR}/${DCFILE_BASE}-private-key.pem" + DCKEY_PRIVATE_PEM_BASE="${DCFILE_BASE}-private-key.pem" + DCKEY_PRIVATE_PEM_LINK="${DC_DIR}/DC-${DC_DNS_NAME}-private-key.pem" + DCREQ_PEM="${DC_DIR}/${DCFILE_BASE}-req.pem" + DCCERT_PEM="${DC_DIR}/${DCFILE_BASE}-cert.pem" + DCCERT_PEM_BASE="${DCFILE_BASE}-cert.pem" + DCCERT_PEM_LINK="${DC_DIR}/DC-${DC_DNS_NAME}-cert.pem" + DCCERT_CER="${DC_DIR}/${DCFILE_BASE}-cert.cer" + DCCERT_P12="${DC_DIR}/${DCFILE_BASE}-private.p12" + + ORGANIZATIONAL_UNIT_NAME="Domain Controllers" + COMMON_NAME="${DC_DNS_NAME}" + EMAIL_ADDRESS="ca-${DNS_DOMAIN}@${DNS_DOMAIN}" + + DEFAULT_BITS="${DC_BITS}" + DEFAULT_DAYS="${DC_DAYS}" + DEFAULT_CRL_DAYS="${CRL_DAYS}" + + umask 077 + mkdir -p "${DC_DIR}/" + + generate_from_template \ + "openssl-BASE-template.cnf" \ + "openssl-DC-template.cnf" \ + "${OPENSSLCNF}" \ + ${DEFAULT_VARS} DC_DNS_NAME DC_OBJECTGUID_HEX + + openssl req -new -newkey rsa -keyout "${DCKEY_PEM}" -out "${DCREQ_PEM}" -config "${OPENSSLCNF}" + openssl rsa -in "${DCKEY_PEM}" -inform PEM -out "${DCKEY_PRIVATE_PEM}" -outform PEM + openssl ca -config "${OPENSSLCNF}" -in "${DCREQ_PEM}" -out "${DCCERT_PEM}" + ln -s "${DCKEY_PRIVATE_PEM_BASE}" "${DCKEY_PRIVATE_PEM_LINK}" + ln -s "${DCCERT_PEM_BASE}" "${DCCERT_PEM_LINK}" + openssl x509 -in "${DCCERT_PEM}" -inform PEM -out "${DCCERT_CER}" -outform DER + echo "Generate ${DCCERT_P12}" + openssl pkcs12 -in "${DCCERT_PEM}" -inkey "${DCKEY_PRIVATE_PEM}" -export -out "${DCCERT_P12}" + ls -la "${DC_DIR}"/*.* + exit 0 + ;; +revoke_dc) + test -e "${CA_DIR}" || { + echo "CA with CA_DIR[${CA_DIR}] does not exists" + exit 1 + } + DC_DNS_NAME="${CMDARG1}" + check_arg "DC_DNS_NAME" "${DC_DNS_NAME}" + REVOKE_REASON="${CMDARG2}" + check_arg "REVOKE_REASON" "${REVOKE_REASON}" + + DC_DIR="${CA_DIR}/DCs/${DC_DNS_NAME}" + test -e "${DC_DIR}" || { + echo "DC with DC_DIR[${DC_DIR}] does not exists" + exit 1 + } + + OPENSSLCNF="${CA_DIR}/Private/CA-${DNS_DOMAIN}-openssl.cnf" + DCKEY_PRIVATE_PEM_LINK="${DC_DIR}/DC-${DC_DNS_NAME}-private-key.pem" + DCCERT_PEM_LINK="${DC_DIR}/DC-${DC_DNS_NAME}-cert.pem" + + REVOKE_DATE=$(date +%Y%m%d-%H%M%S) + REVOKE_DC_DIR="${DC_DIR}.${REVOKE_DATE}.revoked-${REVOKE_REASON}" + + openssl ca -config "${OPENSSLCNF}" -revoke "${DCCERT_PEM_LINK}" -crl_reason "${REVOKE_REASON}" + + mv "${DCKEY_PRIVATE_PEM_LINK}" "${DCKEY_PRIVATE_PEM_LINK}.revoked" + mv "${DCCERT_PEM_LINK}" "${DCCERT_PEM_LINK}.revoked" + mv "${DC_DIR}" "${REVOKE_DC_DIR}" + echo "${REVOKE_DC_DIR}" + + openssl ca -config "${OPENSSLCNF}" -gencrl -out "${CACRL_PEM}" + openssl crl -in "${CACRL_PEM}" -inform PEM -out "${CACRL_CRL}" -outform DER + ls -la "${CACRL_PEM}" "${CACRL_CRL}" + echo "Please run: '${0} ${CNF} publish_crl'" + exit 0 + ;; +create_user) + test -e "${CA_DIR}" || { + echo "CA with CA_DIR[${CA_DIR}] does not exists" + exit 1 + } + USER_PRINCIPAL_NAME="${CMDARG1}" + check_arg "USER_PRINCIPAL_NAME" "${USER_PRINCIPAL_NAME}" + + USER_DIR="${CA_DIR}/Users/${USER_PRINCIPAL_NAME}" + test -e "${USER_DIR}" && { + echo "USER with USER_DIR[${USER_DIR}] already exists" + exit 1 + } + + NEXT_SERIAL=$(cat "${CA_SERIAL}" | xargs) + USERFILE_BASE="USER-${USER_PRINCIPAL_NAME}-S${NEXT_SERIAL}" + OPENSSLCNF="${USER_DIR}/${USERFILE_BASE}-openssl.cnf" + USERKEY_PEM="${USER_DIR}/${USERFILE_BASE}-key.pem" + USERKEY_PRIVATE_PEM="${USER_DIR}/${USERFILE_BASE}-private-key.pem" + USERKEY_PRIVATE_PEM_BASE="${USERFILE_BASE}-private-key.pem" + USERKEY_PRIVATE_PEM_LINK="${USER_DIR}/USER-${USER_PRINCIPAL_NAME}-private-key.pem" + USERREQ_PEM="${USER_DIR}/${USERFILE_BASE}-req.pem" + USERCERT_PEM="${USER_DIR}/${USERFILE_BASE}-cert.pem" + USERCERT_PEM_BASE="${USERFILE_BASE}-cert.pem" + USERCERT_PEM_LINK="${USER_DIR}/USER-${USER_PRINCIPAL_NAME}-cert.pem" + USERCERT_CER="${USER_DIR}/${USERFILE_BASE}-cert.cer" + USERCERT_P12="${USER_DIR}/${USERFILE_BASE}-private.p12" + + ORGANIZATIONAL_UNIT_NAME="Users" + COMMON_NAME="${USER_PRINCIPAL_NAME}" + EMAIL_ADDRESS="${USER_PRINCIPAL_NAME}" + + DEFAULT_BITS="${USER_BITS}" + DEFAULT_DAYS="${USER_DAYS}" + DEFAULT_CRL_DAYS="${CRL_DAYS}" + + umask 077 + mkdir -p "${USER_DIR}/" + + generate_from_template \ + "openssl-BASE-template.cnf" \ + "openssl-USER-template.cnf" \ + "${OPENSSLCNF}" \ + ${DEFAULT_VARS} USER_PRINCIPAL_NAME + + openssl req -new -newkey rsa -keyout "${USERKEY_PEM}" -out "${USERREQ_PEM}" -config "${OPENSSLCNF}" + openssl rsa -in "${USERKEY_PEM}" -inform PEM -out "${USERKEY_PRIVATE_PEM}" -outform PEM + openssl ca -config "${OPENSSLCNF}" -in "${USERREQ_PEM}" -out "${USERCERT_PEM}" + ln -s "${USERKEY_PRIVATE_PEM_BASE}" "${USERKEY_PRIVATE_PEM_LINK}" + ln -s "${USERCERT_PEM_BASE}" "${USERCERT_PEM_LINK}" + openssl x509 -in "${USERCERT_PEM}" -inform PEM -out "${USERCERT_CER}" -outform DER + echo "Generate ${USERCERT_P12}" + openssl pkcs12 -in "${USERCERT_PEM}" -inkey "${USERKEY_PRIVATE_PEM}" -export -out "${USERCERT_P12}" + ls -la "${USER_DIR}"/*.* + exit 0 + ;; +revoke_user) + test -e "${CA_DIR}" || { + echo "CA with CA_DIR[${CA_DIR}] does not exists" + exit 1 + } + USER_PRINCIPAL_NAME="${CMDARG1}" + check_arg "USER_PRINCIPAL_NAME" "${USER_PRINCIPAL_NAME}" + REVOKE_REASON="${CMDARG2}" + check_arg "REVOKE_REASON" "${REVOKE_REASON}" + + USER_DIR="${CA_DIR}/Users/${USER_PRINCIPAL_NAME}" + test -e "${USER_DIR}" || { + echo "USER with USER_DIR[${USER_DIR}] does not exists" + exit 1 + } + + OPENSSLCNF="${CA_DIR}/Private/CA-${DNS_DOMAIN}-openssl.cnf" + USERKEY_PRIVATE_PEM_LINK="${USER_DIR}/USER-${USER_PRINCIPAL_NAME}-private-key.pem" + USERCERT_PEM_LINK="${USER_DIR}/USER-${USER_PRINCIPAL_NAME}-cert.pem" + + REVOKE_DATE=$(date +%Y%m%d-%H%M%S) + REVOKE_USER_DIR="${USER_DIR}.${REVOKE_DATE}.revoked-${REVOKE_REASON}" + + openssl ca -config "${OPENSSLCNF}" -revoke "${USERCERT_PEM_LINK}" -crl_reason "${REVOKE_REASON}" + + mv "${USERKEY_PRIVATE_PEM_LINK}" "${USERKEY_PRIVATE_PEM_LINK}.revoked" + mv "${USERCERT_PEM_LINK}" "${USERCERT_PEM_LINK}.revoked" + mv "${USER_DIR}" "${REVOKE_USER_DIR}.revoked" + echo "${REVOKE_USER_DIR}" + + openssl ca -config "${OPENSSLCNF}" -gencrl -out "${CACRL_PEM}" + openssl crl -in "${CACRL_PEM}" -inform PEM -out "${CACRL_CRL}" -outform DER + ls -la "${CACRL_PEM}" "${CACRL_CRL}" + echo "Please run: '${0} ${CNF} publish_crl'" + exit 0 + ;; +usage) + print_usage + exit 1 + ;; +*) + print_usage + echo "ERROR: CMD[${CMD}] - unknown" + exit 1 + ;; +esac + +exit 1 diff --git a/selftest/manage-ca/manage-ca.templates.d/manage-CA-example.com.cnf b/selftest/manage-ca/manage-ca.templates.d/manage-CA-example.com.cnf new file mode 100644 index 0000000..1f3d24e --- /dev/null +++ b/selftest/manage-ca/manage-ca.templates.d/manage-CA-example.com.cnf @@ -0,0 +1,17 @@ + +CRL_HTTP_BASE="http://www.example.com/crls" +CRL_SSH_BASE="www.example.com:/path/to/crls" +DNS_DOMAIN="example.com" + +#CA_BITS="8192" +#DC_BITS="8192" +#USER_BITS="8192" +#CA_DAYS="3650" +#CRL_DAYS="30" +#DC_DAYS="730" +#USER_DAYS="730" + +COUNTRY_NAME="US" +STATE_NAME="ExampleState" +LOCALITY_NAME="ExampleCity" +ORGANIZATION_NAME="ExampleOrganization" diff --git a/selftest/manage-ca/manage-ca.templates.d/openssl-BASE-template.cnf b/selftest/manage-ca/manage-ca.templates.d/openssl-BASE-template.cnf new file mode 100644 index 0000000..ca8415b --- /dev/null +++ b/selftest/manage-ca/manage-ca.templates.d/openssl-BASE-template.cnf @@ -0,0 +1,201 @@ +# +# Based on the OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +#CRLDISTPT = [CRL Distribution Point; e.g., http://crl-list.base/w4edom-l4.base.crl] +CRLDISTPT = @@CRL_HTTP_BASE@@/CA-@@DNS_DOMAIN@@-crl.crl + +# Extra OBJECT IDENTIFIER info: +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used as a login credential +scardLogin=1.3.6.1.4.1.311.20.2.2 +# Used in a smart card login certificate's subject alternative name +msUPN=1.3.6.1.4.1.311.20.2.3 +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used to identify a domain controller +msKDC=1.3.6.1.5.2.3.5 +# Identifies the AD GUID +msADGUID=1.3.6.1.4.1.311.25.1 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = @@CA_DIR@@ # Where everything is kept +certs = $dir/_none_certs # Where the issued certs are kept +crl_dir = $dir/_none_crl # Where the issued crl are kept +database = $dir/Private/CA-@@DNS_DOMAIN@@-index.txt # database index file. +unique_subject = yes # Set to 'no' to allow creation of + # several certificates with same subject. +new_certs_dir = $dir/NewCerts # default place for new certs. + +certificate = $dir/Public/CA-@@DNS_DOMAIN@@-cert.pem # The CA certificate +serial = $dir/Private/CA-@@DNS_DOMAIN@@-serial.txt # The current serial number +crlnumber = $dir/Private/CA-@@DNS_DOMAIN@@-crlnumber.txt # the current crl number + # must be commented out to leave a V1 CRL + +#crl = $dir/Public/CA-@@DNS_DOMAIN@@-crl.pem # The current CRL +crl = $dir/Public/CA-@@DNS_DOMAIN@@-crl.crl # The current CRL +private_key = $dir/Private/CA-@@DNS_DOMAIN@@-private-key.pem # The private key +RANDFILE = $dir/Private/CA-@@DNS_DOMAIN@@.rand # private random number file + +#x509_extensions = # The extensions to add to the cert +x509_extensions = template_x509_extensions + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +crl_extensions = crl_ext + +default_days = @@DEFAULT_DAYS@@ # how long to certify for +default_crl_days= @@DEFAULT_CRL_DAYS@@ # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = match +stateOrProvinceName = match +localityName = match +organizationName = match +organizationalUnitName = match +commonName = supplied +emailAddress = supplied + +#################################################################### +[ req ] +default_bits = @@DEFAULT_BITS@@ +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = @@COUNTRY_NAME@@ +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = @@STATE_NAME@@ + +localityName = Locality Name (eg, city) +localityName_default = @@LOCALITY_NAME@@ + +organizationName = Organization Name (eg, company) +organizationName_default = @@ORGANIZATION_NAME@@ + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = @@ORGANIZATIONAL_UNIT_NAME@@ + +commonName = Common Name (eg, YOUR name) +commonName_default = @@COMMON_NAME@@ +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = @@EMAIL_ADDRESS@@ +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +#challengePassword = A challenge password +#challengePassword_min = 4 +#challengePassword_max = 20 +# +#unstructuredName = An optional company name + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +# Extensions for a typical CA +# PKIX recommendation. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. +keyUsage = cRLSign, keyCertSign + +crlDistributionPoints=URI:$CRLDISTPT + +# Some might want this also +nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +subjectAltName=email:copy +# Copy issuer details +issuerAltName=issuer:copy + +[ crl_ext ] +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + diff --git a/selftest/manage-ca/manage-ca.templates.d/openssl-CA-template.cnf b/selftest/manage-ca/manage-ca.templates.d/openssl-CA-template.cnf new file mode 100644 index 0000000..4c6bb4a --- /dev/null +++ b/selftest/manage-ca/manage-ca.templates.d/openssl-CA-template.cnf @@ -0,0 +1,2 @@ +[ template_x509_extensions ] + diff --git a/selftest/manage-ca/manage-ca.templates.d/openssl-DC-template.cnf b/selftest/manage-ca/manage-ca.templates.d/openssl-DC-template.cnf new file mode 100644 index 0000000..0b0424d --- /dev/null +++ b/selftest/manage-ca/manage-ca.templates.d/openssl-DC-template.cnf @@ -0,0 +1,49 @@ +#[ usr_cert_mskdc ] +[ template_x509_extensions ] + +# These extensions are added when 'ca' signs a request for a domain controller certificate. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE +crlDistributionPoints=URI:$CRLDISTPT + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +nsCertType = server + +# This is typical in keyUsage for a client certificate. +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "Domain Controller Certificate @@DC_DNS_NAME@@" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. + +subjectAltName=@dc_subjalt + +# Copy subject details +issuerAltName=issuer:copy + +nsCaRevocationUrl = $CRLDISTPT +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +#Extended Key requirements for our domain controller certs +# serverAuth - says cert can be used to identify an ssl/tls server +# msKDC - says cert can be used to identify a Kerberos Domain Controller. +extendedKeyUsage = clientAuth,serverAuth,msKDC + +[dc_subjalt] +DNS=@@DC_DNS_NAME@@ +otherName=msADGUID;FORMAT:HEX,OCTETSTRING:@@DC_OBJECTGUID_HEX@@ diff --git a/selftest/manage-ca/manage-ca.templates.d/openssl-USER-template.cnf b/selftest/manage-ca/manage-ca.templates.d/openssl-USER-template.cnf new file mode 100644 index 0000000..71674b9 --- /dev/null +++ b/selftest/manage-ca/manage-ca.templates.d/openssl-USER-template.cnf @@ -0,0 +1,41 @@ +#[ usr_cert_scarduser ] +[ template_x509_extensions ] + +# These extensions are added when 'ca' signs a request for a certificate that will be used to login from a smart card + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE +crlDistributionPoints=URI:$CRLDISTPT + +# For normal client use this is typical +nsCertType = client, email + +# This is typical in keyUsage for a client certificate. +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "Smart Card Login Certificate for @@USER_PRINCIPAL_NAME@@" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. + +subjectAltName=email:copy,otherName:msUPN;UTF8:@@USER_PRINCIPAL_NAME@@ + +# Copy subject details +issuerAltName=issuer:copy + +nsCaRevocationUrl = $CRLDISTPT +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +#Extended Key requirements for client certs +extendedKeyUsage = clientAuth,scardLogin + -- 1.9.1 From 9507f341ca77599f6b86eca275e7d18a50db18a5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 01:08:02 +0100 Subject: [PATCH 095/323] selftest: add config and script to create a samba.example.com CA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit bdc1f036a8a66256afe8dc88f8a9dc47655640bd) --- selftest/manage-ca/manage-CA-samba.example.com.cnf | 21 +++++++++++++++++++++ selftest/manage-ca/manage-CA-samba.example.com.sh | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 selftest/manage-ca/manage-CA-samba.example.com.cnf create mode 100644 selftest/manage-ca/manage-CA-samba.example.com.sh diff --git a/selftest/manage-ca/manage-CA-samba.example.com.cnf b/selftest/manage-ca/manage-CA-samba.example.com.cnf new file mode 100644 index 0000000..65c9b95 --- /dev/null +++ b/selftest/manage-ca/manage-CA-samba.example.com.cnf @@ -0,0 +1,21 @@ +# +# All passwords are "1234" +# + +CRL_HTTP_BASE="http://www.samba.example.com/crls" +CRL_SSH_BASE="none@samba.example.com:/none/crls" +DNS_DOMAIN="samba.example.com" + +CA_BITS="8192" +DC_BITS="4096" +USER_BITS="2048" +# 20 years should be enough +CA_DAYS="7300" +CRL_DAYS="7300" +DC_DAYS="7300" +USER_DAYS="7300" + +COUNTRY_NAME="US" +STATE_NAME="SambaState" +LOCALITY_NAME="SambaCity" +ORGANIZATION_NAME="SambaSelfTesting" diff --git a/selftest/manage-ca/manage-CA-samba.example.com.sh b/selftest/manage-ca/manage-CA-samba.example.com.sh new file mode 100644 index 0000000..86956aa --- /dev/null +++ b/selftest/manage-ca/manage-CA-samba.example.com.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# + +set -e +set -u +set -x + +# +# All passwords are "1234" +# + +./manage-ca.sh manage-CA-samba.example.com.cnf init_ca + +./manage-ca.sh manage-CA-samba.example.com.cnf create_dc localdc.samba.example.com 0123456789ABCDEF +./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@samba.example.com + +./manage-ca.sh manage-CA-samba.example.com.cnf create_dc addc.addom.samba.example.com 0123456789ABCDEF +./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@addom.samba.example.com -- 1.9.1 From 48b302ac49efd164e693840d762554ef74c695d6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 01:09:31 +0100 Subject: [PATCH 096/323] selftest: add CA-samba.example.com (non-binary) files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The binary files will follow in the next, this allows the next commit to be skipped as the binary files are not used by samba yet. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (similar to commit 520c85a15fa1f4718e2e793303327abea22db149) --- .../DC-addc.addom.samba.example.com-S02-cert.pem | 191 ++++++++++++++++ .../DC-addc.addom.samba.example.com-S02-key.pem | 54 +++++ ...DC-addc.addom.samba.example.com-S02-openssl.cnf | 250 +++++++++++++++++++++ ...ddc.addom.samba.example.com-S02-private-key.pem | 51 +++++ .../DC-addc.addom.samba.example.com-S02-req.pem | 30 +++ .../DC-addc.addom.samba.example.com-cert.pem | 1 + ...DC-addc.addom.samba.example.com-private-key.pem | 1 + .../DC-localdc.samba.example.com-S00-cert.pem | 190 ++++++++++++++++ .../DC-localdc.samba.example.com-S00-key.pem | 54 +++++ .../DC-localdc.samba.example.com-S00-openssl.cnf | 250 +++++++++++++++++++++ ...C-localdc.samba.example.com-S00-private-key.pem | 51 +++++ .../DC-localdc.samba.example.com-S00-req.pem | 30 +++ .../DC-localdc.samba.example.com-cert.pem | 1 + .../DC-localdc.samba.example.com-private-key.pem | 1 + .../manage-ca/CA-samba.example.com/NewCerts/00.pem | 190 ++++++++++++++++ .../manage-ca/CA-samba.example.com/NewCerts/01.pem | 169 ++++++++++++++ .../manage-ca/CA-samba.example.com/NewCerts/02.pem | 191 ++++++++++++++++ .../manage-ca/CA-samba.example.com/NewCerts/03.pem | 169 ++++++++++++++ .../Private/CA-samba.example.com-crlnumber.txt | 1 + .../Private/CA-samba.example.com-crlnumber.txt.old | 1 + .../Private/CA-samba.example.com-index.txt | 4 + .../Private/CA-samba.example.com-index.txt.attr | 1 + .../CA-samba.example.com-index.txt.attr.old | 1 + .../Private/CA-samba.example.com-index.txt.old | 3 + .../Private/CA-samba.example.com-openssl.cnf | 203 +++++++++++++++++ .../Private/CA-samba.example.com-private-key.pem | 102 +++++++++ .../Private/CA-samba.example.com-serial.txt | 1 + .../Private/CA-samba.example.com-serial.txt.old | 1 + .../Public/CA-samba.example.com-cert.pem | 62 +++++ .../Public/CA-samba.example.com-crl.pem | 32 +++ ...inistrator@addom.samba.example.com-S03-cert.pem | 169 ++++++++++++++ ...ministrator@addom.samba.example.com-S03-key.pem | 30 +++ ...strator@addom.samba.example.com-S03-openssl.cnf | 242 ++++++++++++++++++++ ...tor@addom.samba.example.com-S03-private-key.pem | 27 +++ ...ministrator@addom.samba.example.com-S03-req.pem | 19 ++ ...-administrator@addom.samba.example.com-cert.pem | 1 + ...strator@addom.samba.example.com-private-key.pem | 1 + ...ER-administrator@samba.example.com-S01-cert.pem | 169 ++++++++++++++ ...SER-administrator@samba.example.com-S01-key.pem | 30 +++ ...administrator@samba.example.com-S01-openssl.cnf | 242 ++++++++++++++++++++ ...nistrator@samba.example.com-S01-private-key.pem | 27 +++ ...SER-administrator@samba.example.com-S01-req.pem | 19 ++ .../USER-administrator@samba.example.com-cert.pem | 1 + ...administrator@samba.example.com-private-key.pem | 1 + 44 files changed, 3264 insertions(+) create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-cert.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-openssl.cnf create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-req.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-cert.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-cert.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-openssl.cnf create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-req.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-cert.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/NewCerts/00.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/NewCerts/01.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/NewCerts/02.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/NewCerts/03.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt.old create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr.old create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.old create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-openssl.cnf create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt create mode 100644 selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt.old create mode 100644 selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-cert.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-crl.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-cert.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-openssl.cnf create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-req.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-cert.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-cert.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-openssl.cnf create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-private-key.pem create mode 100644 selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-req.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-cert.pem create mode 120000 selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-private-key.pem diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-cert.pem b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-cert.pem new file mode 100644 index 0000000..2e2a8b9 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-cert.pem @@ -0,0 +1,191 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 16 23:29:25 2016 GMT + Not After : Mar 11 23:29:25 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Domain Controllers, CN=addc.addom.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:a6:c4:a9:bf:75:ea:4c:8d:3b:fd:8a:0f:b0:a2: + b6:c7:a8:1f:e4:0e:3e:41:ef:d6:10:48:77:7b:4e: + 4c:59:e1:bf:6d:c7:18:7b:a8:01:a7:d5:d2:2c:21: + 3e:d0:1a:da:58:03:e8:42:f1:53:0e:a7:91:b9:2c: + b9:e7:7a:c9:de:5e:ed:4c:93:6b:cc:dd:17:d0:c7: + d1:f1:7c:3d:0d:6f:df:5d:53:5a:b1:1f:a3:7b:5b: + 41:65:0c:7c:ea:53:df:bb:da:41:15:da:49:e3:b9: + 2d:bb:b5:af:ef:8c:b8:84:74:d0:18:16:8e:5c:e4: + c2:e7:a1:87:8f:e3:87:8b:0b:bb:90:30:e8:e0:f3: + eb:c0:50:5f:b5:7f:54:9a:1b:34:43:fd:be:5a:80: + 6e:0f:63:a2:b3:79:42:4a:85:c8:07:c7:82:55:23: + 88:d4:4e:03:2f:f1:95:bd:ed:15:2d:3e:16:cd:ff: + c7:9b:03:29:36:a6:5d:c9:1a:1e:89:a5:ba:66:83: + 0f:96:a8:07:9f:24:b9:1b:8f:02:9a:b8:50:29:8b: + be:63:45:fa:45:c3:38:23:a0:98:3a:b4:6b:42:99: + 13:36:4b:84:ef:27:89:39:34:79:f8:67:16:7b:9c: + 2a:03:41:15:63:46:e4:db:2f:f2:3e:6d:fe:7c:20: + 1e:9f:02:48:a4:bc:15:42:a6:f8:38:86:dc:6b:7c: + 4e:67:a3:31:81:8e:b6:30:1a:eb:3d:08:25:19:5f: + 42:dc:39:ec:79:1d:30:0a:fb:16:8f:3d:19:14:cc: + f5:af:d7:c6:75:cf:b3:96:a2:b2:9b:d9:03:01:a3: + ca:88:1d:72:ed:6f:d1:bf:57:56:8e:b9:07:9b:b9: + 04:13:1e:0b:5a:06:6b:2b:43:a2:dc:d5:b7:f4:ba: + d3:ae:9d:ad:fd:d3:8a:7c:2f:87:32:fa:89:88:58: + 00:ae:16:2b:9c:1d:58:82:4d:e5:21:da:d5:6c:f7: + a8:40:8b:c7:02:d5:36:30:ef:3f:09:9b:a6:d2:31: + a3:bf:20:d4:a2:9e:26:c4:b4:c3:0f:0b:6c:00:d1: + 2c:16:b1:2a:eb:06:d9:d5:98:c3:cd:cb:20:68:ad: + 0a:2c:a1:2f:27:41:5c:91:de:49:62:ed:d8:3a:ef: + 68:1c:6d:fe:94:c3:28:68:32:60:08:65:cd:02:9f: + 97:96:2f:0f:87:27:3d:b9:0f:85:62:e8:2b:9a:b4: + f4:d3:d7:c1:93:96:27:23:29:88:b1:39:99:53:3a: + 20:aa:88:44:3b:4a:24:2a:8b:e0:b4:8d:dd:66:30: + df:a6:6e:b7:fc:21:43:16:9e:3e:12:20:c8:7a:30: + c1:3d:ab + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Domain Controller Certificate addc.addom.samba.example.com + X509v3 Subject Key Identifier: + 3D:BC:70:0C:74:D4:B8:85:49:1D:08:84:C4:1B:27:F2:AF:72:37:D3 + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + X509v3 Subject Alternative Name: + DNS:addc.addom.samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, TLS Web Server Authentication, msKDC + Signature Algorithm: sha256WithRSAEncryption + 9e:8b:bb:0a:7a:dc:c0:94:33:bc:18:a5:e6:4a:1f:ff:8e:21: + b1:8f:33:f0:3e:8b:6c:72:55:c4:47:71:5f:ce:e7:31:ef:5b: + 62:04:b7:57:8f:a8:27:9f:ed:69:d2:ec:a8:0d:e2:76:33:8d: + 41:3a:67:61:5c:53:60:c7:53:ed:d7:99:72:29:1d:ae:d3:ee: + c9:76:1c:6d:18:47:e9:94:dd:2e:97:3f:99:af:b5:f4:a1:7c: + 92:f6:4d:b5:c1:7a:0c:38:ba:d1:b6:19:9a:9f:e2:02:84:d4: + 54:01:38:7b:55:86:4a:ee:3d:85:48:01:da:34:09:69:43:25: + 7e:6e:06:73:e0:b9:7c:b5:9c:4e:9c:b5:52:85:32:62:62:25: + 39:fa:02:4b:51:2e:df:8e:52:17:02:50:f4:99:29:bf:7e:97: + 53:91:12:85:9a:69:62:45:59:c4:5b:3f:af:18:e6:7b:e4:86: + 5d:f1:9e:5a:2b:3e:14:6e:7e:d4:47:24:ef:d9:a8:ec:d9:a6: + cb:b8:4f:1a:86:d9:43:20:41:16:15:5f:81:0d:fe:6b:31:53: + c1:f6:84:4c:f3:03:64:d2:e6:44:3d:7a:60:79:d7:37:6f:33: + de:c0:a8:b9:6e:fe:b2:79:ac:b4:53:92:b8:0a:59:2b:cc:6b: + 37:c4:6f:c6:44:02:f7:7c:c5:c6:a6:6f:c2:ad:de:78:1e:48: + 96:cc:fe:59:2e:53:ce:34:d6:e8:f0:56:43:30:32:90:6f:f9: + 47:76:ab:99:63:e3:e8:a3:f3:83:98:e9:05:2b:ea:f9:f9:9d: + 66:70:c7:2c:00:c2:9e:57:3e:31:43:50:50:c8:db:a8:2d:21: + 4e:6f:39:c2:bd:ef:d8:47:99:27:0d:48:b2:58:f1:be:45:bd: + fe:c4:a2:56:fc:06:02:dc:19:33:85:53:ed:38:59:01:16:bc: + aa:c5:d3:4b:37:54:83:1b:e5:c1:4b:dd:34:6b:e5:d8:35:86: + 95:e6:9f:d2:22:84:b1:e2:4f:a7:2e:4d:e6:9c:eb:db:df:42: + e1:b4:66:e6:58:d3:28:10:34:97:f3:9c:6b:5f:05:2c:47:2c: + e3:75:eb:6f:74:0a:ec:d7:1d:30:80:56:44:12:26:f6:4e:5f: + ff:92:f4:62:02:36:9c:62:eb:39:98:53:68:68:95:fb:94:68: + 69:b8:3c:66:1a:ce:78:c4:cf:c4:6f:21:ac:a8:a6:f4:ab:69: + 2a:2e:00:5d:f7:67:06:b1:4f:97:58:88:55:d8:6e:eb:a5:98: + 50:36:21:70:3d:b0:a4:f5:3b:21:b3:1c:f5:a9:dd:c6:4a:c2: + 89:b8:5a:b3:bc:1f:21:ce:4c:68:5f:98:d8:39:70:d2:7e:a0: + 90:df:ad:a3:13:eb:3c:93:f6:b8:f4:d9:a7:51:b3:0d:ea:ee: + d4:57:aa:db:ca:7c:8a:a0:08:c3:98:9a:3a:b7:ba:2a:50:92: + 26:c2:e3:11:ba:12:60:24:b9:59:df:62:a8:d7:4d:a3:cb:ea: + 46:e8:39:f9:83:14:a8:5c:44:75:71:6b:7f:99:bd:68:58:d9: + 6b:d1:cd:c7:45:95:9e:44:1e:85:35:c0:30:2b:18:aa:eb:2f: + 93:d5:be:66:5d:70:ed:1d:04:f2:c1:1e:b5:ec:45:0c:04:f6: + 9d:88:d3:0c:20:5e:5b:23:df:34:a1:f5:ea:b4:a1:44:c0:da: + d5:ea:89:e8:b5:cb:dc:f8:92:ee:ac:8d:61:ed:bf:74:2b:28: + 79:1f:f4:9a:ff:63:bd:e6:aa:79:1d:2c:26:4a:b2:26:53:57: + ba:88:0e:eb:19:57:c0:10:a0:1e:81:2a:c0:56:2e:c3:2a:81: + bf:c1:5a:e7:48:ce:c1:6a:b9:6c:41:cc:44:a6:b8:70:e2:57: + 0e:6d:41:d6:61:da:bf:ac:20:2c:a7:2a:67:23:98:00:ba:ce: + 8b:a8:c2:45:66:a7:08:eb:7f:0a:b5:e7:9b:d6:f4:07:d5:b3: + 43:cd:27:d4:fa:c9:40:8f:af:b2:36:1c:e7:44:b4:4e:cc:5a: + 2b:73:ad:8f:c4:d9:47:a6:fb:2c:7d:1a:80:2a:55:b3:80:34: + 6f:8e:17:27:93:05:21:40:e9:8f:bf:47:6a:52:f5:2e:b5:18: + d1:8c:1d:83:04:80:55:fd:21:28:dc:7c:be:c8:c1:5f:e4:40: + d3:13:e4:66:bf:ad:92:4e:9b:db:c1:be:a3:42:74:da:c3:2c: + 0a:da:3f:94:14:ad:7e:de:81:c6:01:6a:f7:7a:b4:25:51:b0: + ab:cd:b3:3a:77:bf:c3:6b:04:44:30:73:41:ad:93:49:67:ee: + 43:d1:96:8e:36:83:2b:1b:6c:e7:cc:3e:d6:16:b9:88:4a:ab: + 56:c0:76:00:f6:9a:6a:8a:e3:e0:41:75:9d:3b:47:0f:c9:0a: + 8e:9f:9c:00:92:bb:ae:d8:42:56:35:64:eb:59:13:da:2c:63: + 83:c3:ec:68:91:b5:f3:71:85:48:54:c3:9d:a1:c8:63:f3:de: + 5d:a5:34:a9:1e:85:2c:2c:b5:d8:a9:62:8d:26:1f:b2:9e:a7: + 83:4d:df:69:63:b5:b7:e5:dd:e7:3b:18:e5:b3:77:df:c5:47: + b3:f7:8c:e7:5e:87:2e:46:e3:8f:b1:2b:9b:c6:26:2d:1a:28: + 30:13:10:86:5b:46:87:b1:2d:12:ce:b6:fe:1c:4e:44 +-----BEGIN CERTIFICATE----- +MIIJ9DCCBdygAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI5MjVaFw0zNjAzMTEyMzI5MjVaMIG4MQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEbMBkGA1UE +CwwSRG9tYWluIENvbnRyb2xsZXJzMSUwIwYDVQQDDBxhZGRjLmFkZG9tLnNhbWJh +LmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkBFiZjYS1zYW1iYS5leGFtcGxlLmNv +bUBzYW1iYS5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAKbEqb916kyNO/2KD7CitseoH+QOPkHv1hBId3tOTFnhv23HGHuoAafV0iwh +PtAa2lgD6ELxUw6nkbksued6yd5e7UyTa8zdF9DH0fF8PQ1v311TWrEfo3tbQWUM +fOpT37vaQRXaSeO5Lbu1r++MuIR00BgWjlzkwuehh4/jh4sLu5Aw6ODz68BQX7V/ +VJobNEP9vlqAbg9jorN5QkqFyAfHglUjiNROAy/xlb3tFS0+Fs3/x5sDKTamXcka +HomlumaDD5aoB58kuRuPApq4UCmLvmNF+kXDOCOgmDq0a0KZEzZLhO8niTk0efhn +FnucKgNBFWNG5Nsv8j5t/nwgHp8CSKS8FUKm+DiG3Gt8TmejMYGOtjAa6z0IJRlf +Qtw57HkdMAr7Fo89GRTM9a/XxnXPs5aispvZAwGjyogdcu1v0b9XVo65B5u5BBMe +C1oGaytDotzVt/S6066drf3TinwvhzL6iYhYAK4WK5wdWIJN5SHa1Wz3qECLxwLV +NjDvPwmbptIxo78g1KKeJsS0ww8LbADRLBaxKusG2dWYw83LIGitCiyhLydBXJHe +SWLt2DrvaBxt/pTDKGgyYAhlzQKfl5YvD4cnPbkPhWLoK5q09NPXwZOWJyMpiLE5 +mVM6IKqIRDtKJCqL4LSN3WYw36Zut/whQxaePhIgyHowwT2rAgMBAAGjggH3MIIB +8zAJBgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly93d3cuc2FtYmEu +ZXhhbXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMBEG +CWCGSAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwSQYJYIZIAYb4QgENBDwWOkRv +bWFpbiBDb250cm9sbGVyIENlcnRpZmljYXRlIGFkZGMuYWRkb20uc2FtYmEuZXhh +bXBsZS5jb20wHQYDVR0OBBYEFD28cAx01LiFSR0IhMQbJ/KvcjfTMB8GA1UdIwQY +MBaAFKI+Aiqjp005tAhNmcwMdTbqJ8M+MEAGA1UdEQQ5MDeCHGFkZGMuYWRkb20u +c2FtYmEuZXhhbXBsZS5jb22gFwYJKwYBBAGCNxkBoAoECAEjRWeJq83vMDEGA1Ud +EgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0G +CWCGSAGG+EIBBARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMv +Q0Etc2FtYmEuZXhhbXBsZS5jb20tY3JsLmNybDAmBgNVHSUEHzAdBggrBgEFBQcD +AgYIKwYBBQUHAwEGBysGAQUCAwUwDQYJKoZIhvcNAQELBQADggQBAJ6Luwp63MCU +M7wYpeZKH/+OIbGPM/A+i2xyVcRHcV/O5zHvW2IEt1ePqCef7WnS7KgN4nYzjUE6 +Z2FcU2DHU+3XmXIpHa7T7sl2HG0YR+mU3S6XP5mvtfShfJL2TbXBegw4utG2GZqf +4gKE1FQBOHtVhkruPYVIAdo0CWlDJX5uBnPguXy1nE6ctVKFMmJiJTn6AktRLt+O +UhcCUPSZKb9+l1OREoWaaWJFWcRbP68Y5nvkhl3xnlorPhRuftRHJO/ZqOzZpsu4 +TxqG2UMgQRYVX4EN/msxU8H2hEzzA2TS5kQ9emB51zdvM97AqLlu/rJ5rLRTkrgK +WSvMazfEb8ZEAvd8xcamb8Kt3ngeSJbM/lkuU8401ujwVkMwMpBv+Ud2q5lj4+ij +84OY6QUr6vn5nWZwxywAwp5XPjFDUFDI26gtIU5vOcK979hHmScNSLJY8b5Fvf7E +olb8BgLcGTOFU+04WQEWvKrF00s3VIMb5cFL3TRr5dg1hpXmn9IihLHiT6cuTeac +69vfQuG0ZuZY0ygQNJfznGtfBSxHLON16290CuzXHTCAVkQSJvZOX/+S9GICNpxi +6zmYU2holfuUaGm4PGYaznjEz8RvIayopvSraSouAF33ZwaxT5dYiFXYbuulmFA2 +IXA9sKT1OyGzHPWp3cZKwom4WrO8HyHOTGhfmNg5cNJ+oJDfraMT6zyT9rj02adR +sw3q7tRXqtvKfIqgCMOYmjq3uipQkibC4xG6EmAkuVnfYqjXTaPL6kboOfmDFKhc +RHVxa3+ZvWhY2WvRzcdFlZ5EHoU1wDArGKrrL5PVvmZdcO0dBPLBHrXsRQwE9p2I +0wwgXlsj3zSh9eq0oUTA2tXqiei1y9z4ku6sjWHtv3QrKHkf9Jr/Y73mqnkdLCZK +siZTV7qIDusZV8AQoB6BKsBWLsMqgb/BWudIzsFquWxBzESmuHDiVw5tQdZh2r+s +ICynKmcjmAC6zouowkVmpwjrfwq155vW9AfVs0PNJ9T6yUCPr7I2HOdEtE7MWitz +rY/E2Uem+yx9GoAqVbOANG+OFyeTBSFA6Y+/R2pS9S61GNGMHYMEgFX9ISjcfL7I +wV/kQNMT5Ga/rZJOm9vBvqNCdNrDLAraP5QUrX7egcYBavd6tCVRsKvNszp3v8Nr +BEQwc0Gtk0ln7kPRlo42gysbbOfMPtYWuYhKq1bAdgD2mmqK4+BBdZ07Rw/JCo6f +nACSu67YQlY1ZOtZE9osY4PD7GiRtfNxhUhUw52hyGPz3l2lNKkehSwstdipYo0m +H7Kep4NN32ljtbfl3ec7GOWzd9/FR7P3jOdehy5G44+xK5vGJi0aKDATEIZbRoex +LRLOtv4cTkQ= +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-key.pem new file mode 100644 index 0000000..6f11ced --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-key.pem @@ -0,0 +1,54 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIJjjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIpUlK4cdzu/UCAggA +MBQGCCqGSIb3DQMHBAju3WkqK++BQgSCCUit3hNjGErKHafSn7CLnhKlNTzvtaAv +PwTStReWMNULMJ6Z1Rhm0jO8x5BBStEHy3A4h1GmWNSyIzOhZqGi3K2SqpBa9+TP +SSYzeNKCsv/06QeQ3GTJJF2GTKLw8I2tZOJnNy5wYprGDuz92AAncj645C8xBYb/ +RgN1YyHh3B2tkPlOVZZU8z8hH9iaDwKiXfY0+EgVDSCj1pHWKEzGzhx4UtyKhCc5 +1J4fyPA+8SzJ0tRAohLHdrm9KIn/tawbbS6Ce8iwLBad6A4k73WgYW4ZawMA+n1X +OIhyCR/dfIlPRPcojyN4c2O5uPmGCDErt6awUY7LyctZPRAUBbk83i69HbRvK/kq +JuyhTIWUbhVpvt6HZxCC0cFBy7tlSeOL3LXlu1JoWAEqCVm8vHQPs3WTwTTrShHP +kauortTdLstddxqPwWKmUcSLcviK+IfD54y3fJGYMr5goLdXCGfb7XZQoXANIYKP +di/jXOn6PTjKdC7/J8G0UZmRmjEvxp5CBPiNqr07YJUfu7IN4KxEKRf/aDyJ1npw +JEaMFiBvFx0Vr5nm7trQ43TdkuHbn7MY6nkPMbzC8a8KcKFGbnU/n6TIyeGYo2o5 +2ICW3QmXjzhrWiDzU+cEbSEs77UAQJNrSxRVuKKuwLEnuy6/pRhlxex6Hp6nNCOd +dTZKDeqHsntRa6zTuOleh+XOMHeSuHjhJdThxEszHPFsYzH/EtE8TaKiBQE9kecy +M+nbxfMqRTYitsl8wTPiuoTgrzDjUJcAAsS/jDNYUA63NCG2BT9Gq9qY48DwfWGM +YPMYj6CfRwsyAPSeC7hV31olnGAp15kBhM2TpxE6KqUnGuxL0ET9LJsHjaRsP+r1 +KMjNmibQSy948LIvHhEtdfg5/Jn5jv6JHmmSBktma4C+MUfQKBinzy6MM1IAaZlZ +hUdL14VnERFh9OGLjZGBOBlk/9FU2Yf4lfAtLgT95GezlYQIOqpG/Pkm04wH71+W +bfW+53gBQqcaSexM5QFsqRspq7yyLX0mElG6z5gOmEJN3rV+DZ2d+84dxKQ5rX++ ++mLYlfQKe1K/1F8HVXH/1ZMeAkzvxk1Odlm6fhwcTHciX3CSESAtJeLSD3PNgSE1 +f0Lep/CteZecOnM63T454jC4V49qXYgQBD32WuOHIbFhHd/lQ5Zj+3T5LgKlE5H3 +5oTUU/+DFgqFrwHlM5f1Ha9G8rjuHucjHyQ7ix7jNjEIoG82It8ESisIOoOwb3bc +Jjkfj3v7f5Axi0wyD94KLFntBCI64uhyTk+JuvagA2KnLQ5uWEFRgqhMXRNg3kbI +STOAopjoB2bnIvQZxQ8hxOT67EjKd7iJJXh2zfBAQ7dvnVKznvdSamTcB/Uh3IQR +RjOZE3ej3lEb4XCM2NCyqZvFgoU+Og4yg+4yainCE+6Jt1jYNvms2iabxC+ZQZ3t +/vCgVDvnULX5FJvphGK/Idua5FFIeSNLOoK9qjfrBNL9kdFVMWCyMyK0cIdsZFRp +2at32a9n8OU1rRYgFn8kaWK4JQqKelm1qVCixcHLUtI/cyp+t7vvjOGRnDrbfoK0 +ae+pt0De0aBsOMKmUetn3CXFXIyQa/FJ3W8X7yl82ctS3ZZmWcND0Lqhoa1JADdj +vbxxGzh1rJPsuPePwIXAVqtbVJD84i+dP0+i1oR/e5jNgRKj0tJcfZnnsvmSIldY +FvxDpIX2h/tDrTKfwQzFHBBuPA00ZuGfftGc4LD7SOVjVb6CF2GMX/0+zmKlPf56 +FvxvGl+GwLPz/BaSGlT/4DApF0HJEZ1AeSvzHGhdgWecbk4s/lMAnv17vH2YWql1 +uJ54FgDAT0ufzAb0aHAl3YO8pYDOOXGqHaqWRMJvtuh15FB52HYvt+Ojo2mzPu4j +lvUcOBRMzgPl8zcs0L/WgE0SggC6DpXGU+rK1/J91qlNRBJ664R6j0iyskPvdzYN +aJ8ZZSJ+yQPralfSD/Sd+RcRviP2draINoyVbFHSH2zvvhcZc0ETL24tNI/tSXpR +Cw86CajiN7T691pC3eZyQLSQJnMSY/0F0i12KU3J+1kq6eeMSoPc5EKItfH5wxjw +RPnJAU84HGIQEAhEn6Ht1XaZcMfo9xyr9WMpmyH4OoTLt1+gFGgSCfbjsusl9aNl +EDhcYmav8OFHE48qvEoYyHD7S3fwsxKFSCJpYTRweBRQaEzpq1z90tVxzhLZFpJe +A7sw/HpiOuty0hDHQ5JaiRBsQ+CiOsVdWZXzaI/H0aoaPbLbpursuTPPPG5OFqvL +WIIDfFYZ9rhy8t/YaAeTyFoLx1VU7m88ZZndyaVXhnqp7iaU14NXlelPeyKJ3ZXc +pd6gZ4l1XAJHbeyiBx+6khtZb6JTLbYpwfbjTqPmDtNw2PVb5rwF0ZSeP6LXKOEM ++WntayDMbWK67yUCBlkPTpY4k+8nV8pJ+th9sR8LlL7d9rZgbSjmxG8XgjC7HHg+ +4I2O7poGQMVgtMeIsGZRIS0cTpm1dpCRfFQPR0DOB6+wjDRPIRNNiTZQYdkpfHQ1 +QSpCskaWG9HzJQGSu+meN4LdaKEoXwNMMz77fCTWhXXkvy6Ujm44EpOOfaHXpg7T +AQagXzyII0xXj+rAFkqmnyygWgxpou6f3MkoWxIC/qYocC4Ci3oWMAZVssWfnhoP +T/ZormTZN3uQCZYtfwTjbjh5efFQc4I9THxkHV6eyhGE7MQO/D/5zjBzkwmNsU6b +GttZyyHto+oKlXMF9dNKxLkQbtVO8ZDIDuNP+sb/m7wj3GG2MNoklp6Cd7lckimv +PqkQP7PQa8h6EeFXmTKqi7vfgsQAEIzTfOLJDvfHhLC54pjbFPR8vY0T5Y2Dwe8w +rMPwFenW1ae6DjeGDHij3+QbQmTYZeu8Hblhs5DNhy7wtZX05IUsioVfJLC9QngN +Y5u7OuMGQLPdcPjWHBuZsl/lMdii1lOB/PrExrEIsybSGPQonDfK6x1pOeyIJsbr +fDnevcamxLpG6BU8U7AqE1QHa/sJGNO/lgsHGLrb5A2id1J+VttSxSG09sML49uw +T+vmgdVbVjsYRvMSjMfwRrVp4NARlXph5FUA2DxAKXvr1reicAleVgQDcokAHhLi +vGZ34XFIZHB+YZvHxd3tZxLcKvAMZQJTPlO6RdD9cx+84DEfevaJilUjyu6Ga4ty +HjA= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-openssl.cnf b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-openssl.cnf new file mode 100644 index 0000000..bdd0364 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-openssl.cnf @@ -0,0 +1,250 @@ +# +# Based on the OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +#CRLDISTPT = [CRL Distribution Point; e.g., http://crl-list.base/w4edom-l4.base.crl] +CRLDISTPT = http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + +# Extra OBJECT IDENTIFIER info: +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used as a login credential +scardLogin=1.3.6.1.4.1.311.20.2.2 +# Used in a smart card login certificate's subject alternative name +msUPN=1.3.6.1.4.1.311.20.2.3 +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used to identify a domain controller +msKDC=1.3.6.1.5.2.3.5 +# Identifies the AD GUID +msADGUID=1.3.6.1.4.1.311.25.1 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = CA-samba.example.com # Where everything is kept +certs = $dir/_none_certs # Where the issued certs are kept +crl_dir = $dir/_none_crl # Where the issued crl are kept +database = $dir/Private/CA-samba.example.com-index.txt # database index file. +unique_subject = yes # Set to 'no' to allow creation of + # several certificates with same subject. +new_certs_dir = $dir/NewCerts # default place for new certs. + +certificate = $dir/Public/CA-samba.example.com-cert.pem # The CA certificate +serial = $dir/Private/CA-samba.example.com-serial.txt # The current serial number +crlnumber = $dir/Private/CA-samba.example.com-crlnumber.txt # the current crl number + # must be commented out to leave a V1 CRL + +#crl = $dir/Public/CA-samba.example.com-crl.pem # The current CRL +crl = $dir/Public/CA-samba.example.com-crl.crl # The current CRL +private_key = $dir/Private/CA-samba.example.com-private-key.pem # The private key +RANDFILE = $dir/Private/CA-samba.example.com.rand # private random number file + +#x509_extensions = # The extensions to add to the cert +x509_extensions = template_x509_extensions + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +crl_extensions = crl_ext + +default_days = 7300 # how long to certify for +default_crl_days= 7300 # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = match +stateOrProvinceName = match +localityName = match +organizationName = match +organizationalUnitName = match +commonName = supplied +emailAddress = supplied + +#################################################################### +[ req ] +default_bits = 4096 +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = SambaState + +localityName = Locality Name (eg, city) +localityName_default = SambaCity + +organizationName = Organization Name (eg, company) +organizationName_default = SambaSelfTesting + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = Domain Controllers + +commonName = Common Name (eg, YOUR name) +commonName_default = addc.addom.samba.example.com +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = ca-samba.example.com@samba.example.com +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +#challengePassword = A challenge password +#challengePassword_min = 4 +#challengePassword_max = 20 +# +#unstructuredName = An optional company name + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +# Extensions for a typical CA +# PKIX recommendation. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. +keyUsage = cRLSign, keyCertSign + +crlDistributionPoints=URI:$CRLDISTPT + +# Some might want this also +nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +subjectAltName=email:copy +# Copy issuer details +issuerAltName=issuer:copy + +[ crl_ext ] +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +#[ usr_cert_mskdc ] +[ template_x509_extensions ] + +# These extensions are added when 'ca' signs a request for a domain controller certificate. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE +crlDistributionPoints=URI:$CRLDISTPT + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +nsCertType = server + +# This is typical in keyUsage for a client certificate. +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "Domain Controller Certificate addc.addom.samba.example.com" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. + +subjectAltName=@dc_subjalt + +# Copy subject details +issuerAltName=issuer:copy + +nsCaRevocationUrl = $CRLDISTPT +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +#Extended Key requirements for our domain controller certs +# serverAuth - says cert can be used to identify an ssl/tls server +# msKDC - says cert can be used to identify a Kerberos Domain Controller. +extendedKeyUsage = clientAuth,serverAuth,msKDC + +[dc_subjalt] +DNS=addc.addom.samba.example.com +otherName=msADGUID;FORMAT:HEX,OCTETSTRING:0123456789ABCDEF diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-private-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-private-key.pem new file mode 100644 index 0000000..eec21e4 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-private-key.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJJwIBAAKCAgEApsSpv3XqTI07/YoPsKK2x6gf5A4+Qe/WEEh3e05MWeG/bccY +e6gBp9XSLCE+0BraWAPoQvFTDqeRuSy553rJ3l7tTJNrzN0X0MfR8Xw9DW/fXVNa +sR+je1tBZQx86lPfu9pBFdpJ47ktu7Wv74y4hHTQGBaOXOTC56GHj+OHiwu7kDDo +4PPrwFBftX9Umhs0Q/2+WoBuD2Ois3lCSoXIB8eCVSOI1E4DL/GVve0VLT4Wzf/H +mwMpNqZdyRoeiaW6ZoMPlqgHnyS5G48CmrhQKYu+Y0X6RcM4I6CYOrRrQpkTNkuE +7yeJOTR5+GcWe5wqA0EVY0bk2y/yPm3+fCAenwJIpLwVQqb4OIbca3xOZ6MxgY62 +MBrrPQglGV9C3DnseR0wCvsWjz0ZFMz1r9fGdc+zlqKym9kDAaPKiB1y7W/Rv1dW +jrkHm7kEEx4LWgZrK0Oi3NW39LrTrp2t/dOKfC+HMvqJiFgArhYrnB1Ygk3lIdrV +bPeoQIvHAtU2MO8/CZum0jGjvyDUop4mxLTDDwtsANEsFrEq6wbZ1ZjDzcsgaK0K +LKEvJ0Fckd5JYu3YOu9oHG3+lMMoaDJgCGXNAp+Xli8Phyc9uQ+FYugrmrT009fB +k5YnIymIsTmZUzogqohEO0okKovgtI3dZjDfpm63/CFDFp4+EiDIejDBPasCAwEA +AQKCAgAloAU0PyRHdS3tu/JiRbO7RAE98MC3G6dOMStT1IyBUt9foyWw8Gy/Mwyi +DDYhuY09glQqlkvI6KGGB8NBqIBW/U/IkRInPFKdNhf1xbP4jh707VNu1taJhEMy +yyh7rcSym0FH7uHw0NyylwFEqJkQuVIhvSUNbEdU/yqYmhsAkfsVQxOnfSDZWMjf +KAUsZ6rZFCyYOpWaPz58A4WjTp+csbSEBOpgC+HINVc1bIH0nSeD/otIO+RWgh5y +usPdBlkRu8wOj4Z4r05cG13ZDnB3jyG7QBSBHNRTpW3zALWaZvLgsxUg5+ib0W0b +UBbQeKE57rsmlN4ZXa3ny+U4l/6QQDSMtrWPNBCMrkt1Q/52gQk1IGeONUAQdLQT +uBx0Vdn5ZvIFRBnkQl2KWOBWTdD2v0qxIHhXlsWX7tGVU7eh3GIAPoFzQZFHpPhA +RObE8fNg/3HMVGDUwXnd4k+6c1t+Ioa17FuLJE4lr5c55Klq2lJ4Oq2Jd6AfoGjv +anA45ChI6lrg2Kt7OhUEHIIHyZmm7eNmBHoGA3r+YJyiQQIGSiNjH+Up54KWa88z +p+ZY1u3VdOiNuKVlRn79q85Th4HyMlx7wuY+t8HAj42Vt03Uy7iDaaTfuPxehMyS +MqcRWR5MhavR5ShTtsIXwvUgWj/YcqaOb9Zfe2Y1RgFURKN3YQKCAQEA0I1hTnGs +KE5l9dGowKm2io6pZr8J2B8ITjp8pdAaY46Ws1tfcTkbbpBUvyrflCIgLIP9KTP3 +6cc4HrK11mf8rPD1pHNWJd7CjPTLQFMYu+h8YlBqKwrgA8owLzUWG4omS0vehCnG +6OIPi8ceUc2u6XW+TGKP4n8GXJrrKaw9hw83u6h9YQCpgfwF4QpwX8LzTMKnI7te +HxUQFlhKX3vci+dP4n29c6yGl57830E7LeQGRfjo/NAV3pAAcHk79cEzOJQCN1Wy +bNU2kcoOA3tGTI8tCfBdwpN11Sz2/tu4ytJE2weP5S7r9xOTq8t+iKQ9+NLhAvJU +8S2mIkyFAi8tWQKCAQEAzLWsJ3qxyaLHv4tOFTqenSj0CbB25OIzDQNLT++L4fYn +YAqL6/G83bRVbdYvfJ3ZdZdnseluGrR8ZcxdqioLCws66+O1vC8GkHI5aBKZt4MD +Um+SzD6ZnARYcTbtRmPUJHxIdny2dbYLe5dDlqTFIV+olWDR+1YMSzXt/VW+jx9I +tHhw8LJAxhMhDt0Gh+CxNFHQYdkdK/OuNTBufT/rxeT3E5t3TbSG29pU/F2Rce1G +CCy0nbFsTMjPusSzwFJILWHdvBAYJceOajvqZhlaTV11u/qrj9gb+nJkH+rKvJnA +pK2YyFWqomnGCZB61Y5LOfjk2b1BfVGCdqpRrBCOowKCAQBun3/NB1jlbGiDEvor +cBpmtrO+z3jeTd+u9zElFxTYWEsxyjb/LOaTKDX7zTcZMVzVoBGKaImJVOY8yljP +6QrLhWkXGSLKJbYW5MZnUWyeR/yqfbNDL5qSCA61C7i1VPtpF05p1msvHrJWV4GK +rMqqBY2yoNlnsC9ksbwpt7ZPTNAoV4BiEuLXEyLfMxVWhmdeASZ9Oqb7X8XPxHd2 +3JGpGEJ0hnQWxp4CERBbMBO/DOQS+6xCZfIjw0ioYHZgrmGIEmJ2jZt+RT6T6JS0 +XhB1DcE7M2fYjTWEpTxDBbOoyg5CDGnUjKYXwiejieaNfmls8hbu5DIQWEF2khY/ +iVzJAoIBAENOiGgCo2oUp3CHMQkx2Oz7hiGZb74Z0Yc5yg1iSa/l61Rco1zUgrCy +llQi1EI49EMBoQqSIa2OIkimRTWp1S+wZZMhr6NMIvBjXhSl6Py5iuIT5URaYM83 +bozq7mDyedH1Oy4aGzPgwy3DsmlZi6dJeHiE+QWWaTxhYvqksp8EPjd4UkoRkdKO +f5QPgBI1Ao6dR9KkPD8zQ9ghMHLmDXNnsQU1XKij7qNiygagDS5UQW52pHwk1eL5 +M7PI8QEPDMQ/JVSsRgRF9MFhKdSgCVzemdNQvA/zkl9qNRl5bWdNdlWu7kkQQaZc ++Mw0QO7udjV9bGFbJKk7n5W8slXMq9kCggEAJ2yzyZKdQZtuXpf6WN6sNqRJ6CHo +k9en+acEg9Y+5lVt2CRblprQxhdUV2KyN7G8GxV0hMwmHtMTeB4j6jhdZrAAZGVW +upqCfY2vSYQ/svCeB0Fs5DMEI4iCS5Drn8gKKi/zWAbox9sb+zaYT/Ot5p2Ki/HH +YIh+p8EE6IFWE3jChabPQieXVOC7tg/qaxWVHTv7Qe2fdZTY3XifTcN7hVghf/bH +Vn+VdU2u/7hE7X3y9YNETNSin5U3F0BSm1tUQimUzU50+9Nl2UGPBI39e+15qRz7 +JHocpq9h9+k3T7qWwJxX74YhcTqdb1pGsKUEmo7r6rPR4L5h5nCF3OgR9g== +-----END RSA PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-req.pem b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-req.pem new file mode 100644 index 0000000..5b356fa --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-S02-req.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIFEjCCAvoCAQAwgcwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTYW1iYVN0YXRl +MRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNVBAoMEFNhbWJhU2VsZlRlc3Rpbmcx +GzAZBgNVBAsMEkRvbWFpbiBDb250cm9sbGVyczElMCMGA1UEAwwcYWRkYy5hZGRv +bS5zYW1iYS5leGFtcGxlLmNvbTE1MDMGCSqGSIb3DQEJARYmY2Etc2FtYmEuZXhh +bXBsZS5jb21Ac2FtYmEuZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCmxKm/depMjTv9ig+worbHqB/kDj5B79YQSHd7TkxZ4b9txxh7 +qAGn1dIsIT7QGtpYA+hC8VMOp5G5LLnnesneXu1Mk2vM3RfQx9HxfD0Nb99dU1qx +H6N7W0FlDHzqU9+72kEV2knjuS27ta/vjLiEdNAYFo5c5MLnoYeP44eLC7uQMOjg +8+vAUF+1f1SaGzRD/b5agG4PY6KzeUJKhcgHx4JVI4jUTgMv8ZW97RUtPhbN/8eb +Ayk2pl3JGh6Jpbpmgw+WqAefJLkbjwKauFApi75jRfpFwzgjoJg6tGtCmRM2S4Tv +J4k5NHn4ZxZ7nCoDQRVjRuTbL/I+bf58IB6fAkikvBVCpvg4htxrfE5nozGBjrYw +Gus9CCUZX0LcOex5HTAK+xaPPRkUzPWv18Z1z7OWorKb2QMBo8qIHXLtb9G/V1aO +uQebuQQTHgtaBmsrQ6Lc1bf0utOuna3904p8L4cy+omIWACuFiucHViCTeUh2tVs +96hAi8cC1TYw7z8Jm6bSMaO/INSinibEtMMPC2wA0SwWsSrrBtnVmMPNyyBorQos +oS8nQVyR3kli7dg672gcbf6UwyhoMmAIZc0Cn5eWLw+HJz25D4Vi6CuatPTT18GT +licjKYixOZlTOiCqiEQ7SiQqi+C0jd1mMN+mbrf8IUMWnj4SIMh6MME9qwIDAQAB +oAAwDQYJKoZIhvcNAQELBQADggIBADLgdZz1gvzpnZPwd5KCxjwKgiotlUGBh6t6 +cLhyomCN02adMr0PPJP/n3r1Zsaq2db/zktP8J5fUYqA9vJZzYukzkKRHbl+rdHS +JVEvHmbsG3729V9cy40kuL0EAM0weBbfQZaeFxfcLxl5v14QOxvldrmYSK5GaLh8 +WSEz4uljrI8ee3q8Cn08xlZ2Dr3MoHI9unEcLJFXkpCwVBALFhw5dG8od3jl8AyS +WeMVbdD9fm4jnHE/RDSPDqUqMCGIYmrB5amGO5rSLDTWxDxrcHFRM7sa359nW2IA +GoZd+r8Vf2AZ8i/KRgH7uIFB2BJm4L0QiVlajy3odW3zhQIVXNh9p58aGzOFQGkq +Gsld4WI3gZZeSvGgGIjoB2+AYRjxTzUn5qSFVev5sFLK3cNdPZo66xltuPBhfXB/ +v/+/TQC80oZ8oZGdgYvBBT1IEg4pwB5Myqeps9J7kbJVmtxR2EGlq/aGN0yE/fy9 +S8ners0iXBJP18suSwbjj2unZQMBYLIgHLkzztxAMGYBlfEljSAvDfFCsK5Rkmya +soxd1qHHMG8Ap+WZagpkK9tv42HwmbYKVeDArGAHr53aC4ripgrSBnzpmkiSyi4p +mb3L5K/ZSOxo3xrS0wERq3p6FalF8/AhctgzWOgMvikVoTUy0xPsG/hulXPyk2UG +rYn+WPQz +-----END CERTIFICATE REQUEST----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-cert.pem b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-cert.pem new file mode 120000 index 0000000..43b4b51 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-cert.pem @@ -0,0 +1 @@ +DC-addc.addom.samba.example.com-S02-cert.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-private-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-private-key.pem new file mode 120000 index 0000000..3170fe7 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/addc.addom.samba.example.com/DC-addc.addom.samba.example.com-private-key.pem @@ -0,0 +1 @@ +DC-addc.addom.samba.example.com-S02-private-key.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-cert.pem b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-cert.pem new file mode 100644 index 0000000..7b1b6a1 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-cert.pem @@ -0,0 +1,190 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 16 23:28:44 2016 GMT + Not After : Mar 11 23:28:44 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Domain Controllers, CN=localdc.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:e6:a4:76:ce:e8:63:fe:57:f9:a3:ae:e0:ad:4d: + e2:15:8e:d8:27:c8:7d:7f:2b:b1:e8:aa:50:8f:94: + f9:c7:71:3f:52:32:91:d1:6d:52:22:5f:cd:8d:cc: + 62:16:7a:8b:58:65:ed:07:f7:ea:24:d3:88:d8:26: + ca:eb:ec:16:a7:84:1c:7e:15:46:64:09:22:46:b9: + dd:5c:07:84:50:a7:4e:31:3f:01:23:d1:f8:36:04: + 1a:bb:d4:e5:b6:d4:1b:5c:16:c9:9e:37:8a:3e:a9: + 7d:30:24:40:b2:b5:44:40:fa:5c:6f:d5:3e:ff:32: + c2:e7:24:0a:e4:e4:aa:9f:ff:4c:ac:be:37:58:22: + 08:16:0e:f6:a7:2f:b5:6c:4f:ac:7b:a4:82:a8:9f: + 38:64:17:6e:72:b6:7c:4c:c5:44:2a:0a:b4:25:0d: + b0:0c:ab:98:4a:f9:1a:1a:c9:a6:59:f4:00:a5:0a: + 6f:0a:d0:a5:34:ca:0f:f4:0e:fb:ba:d7:bb:3e:2c: + 7c:0c:68:6b:26:ff:1c:29:fe:77:f9:30:85:0d:44: + 8c:af:90:8a:70:93:5d:3a:b6:18:8b:a5:85:11:5c: + a3:5d:57:16:dd:c7:c8:00:f1:05:71:c2:6e:07:3c: + 37:69:36:7c:12:c5:9e:1b:69:11:45:44:1e:eb:b9: + b2:96:b1:89:cd:4d:fa:89:eb:92:49:f2:46:35:f3: + 9d:87:3c:be:e4:f8:b7:31:a7:36:4b:81:76:9b:b2: + 04:d5:80:7d:4f:e6:02:ed:24:4c:a0:03:c4:9d:00: + 9f:9d:71:93:0d:a5:b8:37:62:2b:03:c3:bd:24:25: + 2c:c3:43:d4:c8:27:b0:6d:05:d4:c6:c5:d8:5b:09: + 94:e8:27:6b:d9:6d:b7:bc:de:76:bf:d5:9c:36:26: + 04:b9:97:1d:f0:c9:8d:91:93:82:32:0d:b7:16:97: + 41:31:9a:22:0b:2e:ba:99:51:28:6b:f5:04:ba:c9: + 3d:57:0c:72:e8:e1:24:1a:d4:2a:6a:e7:e3:b6:b9: + 94:61:e3:4e:42:81:e5:43:e4:1e:ef:6d:c4:5d:a4: + f9:b4:ec:3a:8a:34:fe:b5:c7:a8:fe:19:8d:cf:7d: + 1b:60:21:ba:25:6f:35:cd:4f:72:28:42:7d:87:08: + aa:da:33:7e:63:e6:5b:5f:e7:01:a8:e3:0b:d3:08: + 5a:a6:df:ea:e7:2b:13:48:a7:83:32:96:c4:ba:d1: + ff:15:66:52:33:86:46:5f:c2:9f:59:4a:00:98:b7: + 1b:a1:87:25:df:ad:68:5b:f7:26:17:2b:eb:84:62: + 9d:c3:bd:99:67:6a:02:5d:70:72:3e:18:92:99:8c: + bd:d9:4f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Domain Controller Certificate localdc.samba.example.com + X509v3 Subject Key Identifier: + E1:DF:73:0B:F1:3E:86:43:A4:B3:E9:8D:44:7D:3C:B2:19:C1:BC:F2 + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + X509v3 Subject Alternative Name: + DNS:localdc.samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, TLS Web Server Authentication, msKDC + Signature Algorithm: sha256WithRSAEncryption + 89:2c:57:98:17:c1:73:a6:10:02:6f:a6:ac:47:1c:37:2d:1d: + a1:3c:c5:29:b6:3a:e6:e8:14:ec:3b:74:ee:da:db:2d:97:3e: + d3:8c:9d:42:7e:b0:46:e9:54:74:4f:34:df:9e:34:7f:9e:8a: + 9d:4d:b2:cf:fb:71:3f:cb:32:e6:45:e7:b4:d3:9e:e8:ca:a5: + cf:16:7b:76:b5:4e:e0:b9:bb:79:b1:82:a7:d3:23:cb:3c:46: + 63:63:96:b3:5b:62:9e:99:dc:02:17:f9:07:63:86:76:06:1a: + 02:1b:9a:df:1d:cd:e7:46:fe:9a:13:87:47:dd:e2:77:58:50: + a2:6c:c9:a0:f8:14:1f:3b:d7:59:9c:89:bd:2e:2d:ce:60:f4: + c6:2c:e3:63:cf:34:84:61:d9:90:2e:90:fc:5b:4f:a2:00:87: + e7:40:e0:fc:d1:24:8b:d0:28:01:d3:53:ac:b1:58:7f:87:29: + 38:56:93:dd:a2:14:4a:9a:94:b9:f8:94:b2:04:47:db:b8:38: + e6:85:2b:cf:d4:72:88:8b:0d:8e:a0:69:f9:9f:10:22:82:9c: + c5:ec:01:e3:07:a1:69:37:94:25:3a:cd:17:29:37:8d:24:d3: + 27:0f:4d:bf:b0:31:36:b8:c6:a8:69:0b:df:28:f8:e2:dc:da: + 95:3e:7f:d7:3f:a5:8f:92:6a:7d:ad:3a:ac:af:73:2b:5f:f1: + b3:22:92:ef:da:71:84:9e:4b:23:7b:69:b7:29:fc:c5:05:84: + 4b:ff:06:92:ee:f5:9b:14:2a:af:be:ef:02:e1:e7:d0:e8:d0: + 29:7c:48:40:f1:95:bb:08:b2:30:c5:81:80:a8:91:5b:2e:08: + 3b:30:44:07:b5:c4:0b:07:74:ca:5d:37:3d:75:f9:bc:6d:21: + a6:e0:91:d8:f9:27:88:05:58:a7:f4:36:eb:ba:40:63:36:15: + 42:98:0b:e2:d1:c9:11:0b:29:81:e1:c7:02:7e:fa:05:65:51: + 7b:d6:1a:33:46:fc:a5:d4:fd:64:e8:c8:11:d4:d1:41:d9:39: + 18:08:a3:ed:15:70:d9:14:f5:ba:c9:bb:3e:96:8d:5d:cc:c3: + 5c:b6:c8:79:02:2e:e2:a1:06:ba:a5:21:1c:bf:16:7f:2d:d9: + 93:07:92:b1:fa:ee:3f:e3:56:35:f3:30:aa:11:54:d3:71:cb: + 29:d4:60:e1:6c:ae:c4:24:e3:00:4f:5f:52:b0:3f:f4:76:f3: + 6d:db:bc:d8:65:c4:37:be:1a:87:9b:65:c4:20:dd:da:a9:4c: + 9f:86:33:2b:49:a6:f7:aa:ce:da:98:3b:e3:5f:ac:b8:1b:45: + 0e:56:59:fb:49:38:0f:b7:d4:49:f8:7b:ac:fa:d8:b8:1d:16: + db:b2:4c:15:d8:e7:eb:6b:38:ff:d2:69:26:a6:f6:50:15:45: + 2f:12:b2:05:d4:bf:6f:53:79:64:9b:d5:8b:a1:08:3e:43:ee: + 08:fe:9b:ea:83:89:8a:6a:53:98:1e:c5:91:4c:7a:99:2b:6d: + 97:dc:96:1b:de:27:c5:af:0f:dd:42:5c:23:7d:bc:6b:5b:ab: + 47:29:98:35:8f:9e:e6:e1:5f:96:6a:bd:cf:3c:47:89:8b:ad: + 21:de:20:da:99:82:c1:0e:9b:7c:38:21:d8:b1:1c:34:c5:4e: + f7:fe:7d:5e:a4:2f:f8:7d:5c:30:2c:9e:e6:5a:4f:d3:15:90: + e6:6f:69:ea:51:93:8f:2c:dd:a7:c3:3c:50:a8:d1:ba:0b:5c: + cc:2e:4e:57:71:21:08:a1:2c:bd:a7:20:4b:ae:5c:02:7a:cd: + 9a:fe:1e:db:ec:ce:3b:12:37:cb:96:20:7b:3b:b1:5a:2e:84: + 03:f9:0b:32:43:c0:4e:e3:ea:79:e7:9a:13:54:e5:a8:1a:17: + c4:79:78:25:63:ab:67:39:39:a0:6c:c4:c5:94:ac:16:92:3d: + f0:1a:1a:9e:ca:7a:84:1b:c1:5a:5f:4c:65:8a:30:a6:5e:6c: + 0e:ae:bf:ac:09:97:0f:83:5c:92:ce:e4:43:de:06:4b:96:f5: + 46:3b:7d:a8:e3:0f:d3:fe:00:c7:d4:79:4e:5f:bd:ec:59:12: + f9:65:23:fa:e7:97:a2:a6:39:3b:a3:1e:da:47:c5:18:5b:8d: + a7:7b:29:1c:5a:7a:06:c6:92:9e:b7:3b:f0:c5:56:e8:cf:84: + cd:dd:61:0f:21:25:f4:1e:2b:40:b6:74:28:8d:41:f6:2c:1d: + ce:b4:39:d1:e1:be:15:78:c9:d7:99:a1:9d:50:43:da:ec:40: + 69:6a:3b:17:af:28:22:09:e0:7d:38:9e:a7:ca:b7:f7:94:8a: + 2a:1b:32:4e:28:6d:18:95:ca:42:67:c8:bb:13:24:31:43:84: + 3e:95:66:08:5c:15:7f:6b:93:cc:8f:b8:76:7a:fd:74:4a:d6: + 6f:64:74:df:72:f7:34:a3:50:f0:db:bf:0a:2b:1b:48:b7:c9: + c0:97:23:27:b1:56:5b:9e:10:12:5a:bf:ff:38:61:da:41:75: + 15:c5:03:c2:20:fd:7f:84:c0:94:8e:11:ed:01:ba:f1:19:b5: + 05:1d:bf:89:ea:c9:38:4e:d2:cf:5b:24:c6:37:a1:8e:60:89: + 5c:52:ff:7d:5e:2d:c9:f8:b1:79:07:4c:2f:18:85:e8:ba:bf: + 3e:da:59:43:df:29:79:7e:00:38:d2:fc:a9:8e:3b:9d +-----BEGIN CERTIFICATE----- +MIIJ6zCCBdOgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI4NDRaFw0zNjAzMTEyMzI4NDRaMIG1MQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEbMBkGA1UE +CwwSRG9tYWluIENvbnRyb2xsZXJzMSIwIAYDVQQDDBlsb2NhbGRjLnNhbWJhLmV4 +YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkBFiZjYS1zYW1iYS5leGFtcGxlLmNvbUBz +YW1iYS5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AOakds7oY/5X+aOu4K1N4hWO2CfIfX8rseiqUI+U+cdxP1IykdFtUiJfzY3MYhZ6 +i1hl7Qf36iTTiNgmyuvsFqeEHH4VRmQJIka53VwHhFCnTjE/ASPR+DYEGrvU5bbU +G1wWyZ43ij6pfTAkQLK1RED6XG/VPv8ywuckCuTkqp//TKy+N1giCBYO9qcvtWxP +rHukgqifOGQXbnK2fEzFRCoKtCUNsAyrmEr5GhrJpln0AKUKbwrQpTTKD/QO+7rX +uz4sfAxoayb/HCn+d/kwhQ1EjK+QinCTXTq2GIulhRFco11XFt3HyADxBXHCbgc8 +N2k2fBLFnhtpEUVEHuu5spaxic1N+onrkknyRjXznYc8vuT4tzGnNkuBdpuyBNWA +fU/mAu0kTKADxJ0An51xkw2luDdiKwPDvSQlLMND1MgnsG0F1MbF2FsJlOgna9lt +t7zedr/VnDYmBLmXHfDJjZGTgjINtxaXQTGaIgsuuplRKGv1BLrJPVcMcujhJBrU +Kmrn47a5lGHjTkKB5UPkHu9txF2k+bTsOoo0/rXHqP4Zjc99G2AhuiVvNc1PcihC +fYcIqtozfmPmW1/nAajjC9MIWqbf6ucrE0ingzKWxLrR/xVmUjOGRl/Cn1lKAJi3 +G6GHJd+taFv3Jhcr64RincO9mWdqAl1wcj4YkpmMvdlPAgMBAAGjggHxMIIB7TAJ +BgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly93d3cuc2FtYmEuZXhh +bXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMBEGCWCG +SAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwRgYJYIZIAYb4QgENBDkWN0RvbWFp +biBDb250cm9sbGVyIENlcnRpZmljYXRlIGxvY2FsZGMuc2FtYmEuZXhhbXBsZS5j +b20wHQYDVR0OBBYEFOHfcwvxPoZDpLPpjUR9PLIZwbzyMB8GA1UdIwQYMBaAFKI+ +Aiqjp005tAhNmcwMdTbqJ8M+MD0GA1UdEQQ2MDSCGWxvY2FsZGMuc2FtYmEuZXhh +bXBsZS5jb22gFwYJKwYBBAGCNxkBoAoECAEjRWeJq83vMDEGA1UdEgQqMCiBJmNh +LXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0GCWCGSAGG+EIB +BARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMvQ0Etc2FtYmEu +ZXhhbXBsZS5jb20tY3JsLmNybDAmBgNVHSUEHzAdBggrBgEFBQcDAgYIKwYBBQUH +AwEGBysGAQUCAwUwDQYJKoZIhvcNAQELBQADggQBAIksV5gXwXOmEAJvpqxHHDct +HaE8xSm2OuboFOw7dO7a2y2XPtOMnUJ+sEbpVHRPNN+eNH+eip1Nss/7cT/LMuZF +57TTnujKpc8We3a1TuC5u3mxgqfTI8s8RmNjlrNbYp6Z3AIX+QdjhnYGGgIbmt8d +zedG/poTh0fd4ndYUKJsyaD4FB8711mcib0uLc5g9MYs42PPNIRh2ZAukPxbT6IA +h+dA4PzRJIvQKAHTU6yxWH+HKThWk92iFEqalLn4lLIER9u4OOaFK8/UcoiLDY6g +afmfECKCnMXsAeMHoWk3lCU6zRcpN40k0ycPTb+wMTa4xqhpC98o+OLc2pU+f9c/ +pY+San2tOqyvcytf8bMiku/acYSeSyN7abcp/MUFhEv/BpLu9ZsUKq++7wLh59Do +0Cl8SEDxlbsIsjDFgYCokVsuCDswRAe1xAsHdMpdNz11+bxtIabgkdj5J4gFWKf0 +Nuu6QGM2FUKYC+LRyRELKYHhxwJ++gVlUXvWGjNG/KXU/WToyBHU0UHZORgIo+0V +cNkU9brJuz6WjV3Mw1y2yHkCLuKhBrqlIRy/Fn8t2ZMHkrH67j/jVjXzMKoRVNNx +yynUYOFsrsQk4wBPX1KwP/R2823bvNhlxDe+GoebZcQg3dqpTJ+GMytJpveqztqY +O+NfrLgbRQ5WWftJOA+31En4e6z62LgdFtuyTBXY5+trOP/SaSam9lAVRS8SsgXU +v29TeWSb1YuhCD5D7gj+m+qDiYpqU5gexZFMepkrbZfclhveJ8WvD91CXCN9vGtb +q0cpmDWPnubhX5Zqvc88R4mLrSHeINqZgsEOm3w4IdixHDTFTvf+fV6kL/h9XDAs +nuZaT9MVkOZvaepRk48s3afDPFCo0boLXMwuTldxIQihLL2nIEuuXAJ6zZr+Htvs +zjsSN8uWIHs7sVouhAP5CzJDwE7j6nnnmhNU5agaF8R5eCVjq2c5OaBsxMWUrBaS +PfAaGp7KeoQbwVpfTGWKMKZebA6uv6wJlw+DXJLO5EPeBkuW9UY7fajjD9P+AMfU +eU5fvexZEvllI/rnl6KmOTujHtpHxRhbjad7KRxaegbGkp63O/DFVujPhM3dYQ8h +JfQeK0C2dCiNQfYsHc60OdHhvhV4ydeZoZ1QQ9rsQGlqOxevKCIJ4H04nqfKt/eU +iiobMk4obRiVykJnyLsTJDFDhD6VZghcFX9rk8yPuHZ6/XRK1m9kdN9y9zSjUPDb +vworG0i3ycCXIyexVlueEBJav/84YdpBdRXFA8Ig/X+EwJSOEe0BuvEZtQUdv4nq +yThO0s9bJMY3oY5giVxS/31eLcn4sXkHTC8Yhei6vz7aWUPfKXl+ADjS/KmOO50= +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-key.pem new file mode 100644 index 0000000..3443a501 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-key.pem @@ -0,0 +1,54 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIJjjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIc8U9D3UAcEQCAggA +MBQGCCqGSIb3DQMHBAiv8rBzGS//TQSCCUieV5YQyWsn3FFhKYI425pOXfnTsSUb +VEe7wO2H7D/S0RFfT5gILYv57TTH8Z9uAeX/wU5msKA4PZt16aMutNl2NWell8hy +IX5R4n6IzSP6IobZKsyFR5u/h683Eli1pBd4BbLJuYu94sxelB4HQdRp0QJIvIvO +TWqTyD7UmqqG/IVhTMQpzcepY/S4SGI6GODJtDLPRgv3x5/Z0/NsxiMKrXMi7HKc +Rzg8jm2mausukN+sSyPcvlEufQjRJgJXtCIX98FMLp0pkOq1rsVUSNg8Qza6tbyE +XhweHWbV9YZCVfmnhUalLt7CIoA7QeOQZbwTNpTo/4mSEA7lv1knvFSdMc9JvR6J +bZQOk5rPzuX2W84UQ3CkIwaRB2iFUv0gJy5Z2xbhWgAR5KZIhGTKupHBYOmD29QU +whgjXq4McdYWKquxELzSW5jXVPNwvREhEuKR1mt6g0NqXCbCeQHw7DWH1OGPz7jM +HXsCGVWpXqeWvRHhdF+NRfHa41hqGS3Onq29UJtgcMpNYpGQYY6Exq6hVVsmddwt +QU4COPfozJzeAlkUEem5AKnuh1JUxo/RieNP99sv1/8g8icc+oPXOIu/6HI3JGYB +4WTVBp1OccEcNlnUYhxcL3ODYXcLUhiLZh2DS+IDLS3Pbp0v1qz/JuzDxiYBnEYt +4Q5NWdhPF/TSS7wQHRl35LAyHHhBIu1kuDhnXjdq87h7ioNiffZ0DgSW4HFUzslk +4UZGFTKaDpepBfIp1qnYGPKCMv+MLaMWU3LOfVGT3ecntkMxUtntNMZ6qGaXhzda +65LD9xYJUrbo+qQSBiTNAhMOy6lHlwIulmML0j1YEcVc2EwgqdfbBeT9v9gh6If4 +85ba1Wvy4W/FN/xo/ECflLAvozjyYND8LMcZ73eJs4ncZkMZAkjfP3sg/qvTAtbf +D6c+SRQbxRJv0ZUb9NN7wx4flsyypscKNqk78mytUN7gGf2xJIOvMS/zH/Zf9EpD +bEY+lOY2llYtXhoEj95tnRPFhKaQeGZdkISsmoU5olLsw/tRkquGdAokh+fl+NtZ +WxgJF8Ft8NT4iXhEBRfgFO5ubGq565c66ayA6R6K00pg/IvS8OXPuxT+/e8EKqUO +R9RyWR5n+W8hWw5+pQWGNvwhLFLJFfCxHw2ucSyNCvtcb6ijV5yvi4cI+UuVnh3s +WW3mMaMOYIcbh/thp8wBs/dpAOGUWX7XBfaGsQ0D+ff0ufcUobhXVZgtC0LhgfrN +ZeHQF4bUXycyaAGWvstNb6Xj2QFVDG98eNDGmYDTD+0XwpPc/6/Ge4BLPAVcBpQw +DMCKUqSkPPWCqfipbQmpBxswhYmzx+DjdfRxHExWeGk1pwyfH4GBhO5fkcpYVtU+ +RyruFu0YNnQ+2Y4eg8+3IyJndxkUHmwsB1DB0P8XvJ0n/NnAnZ0sIpE0x3dOFhb+ +SK0dj8fo2aEHOimrTHc2EJ2ZscpSCVNQ1BsScM36FCWxRWbTr8rBFsdUJ5CMZ2hN +qHBtf38SgNkD3qBUmiPetsYt6qTKY9Rv25D4zL5IR2ZnV99oW6MTDhc49cxYn8Dy +MKlyzV3upykqGBMSKBKbafDI3sO8gB3upUetnogi1TMaNyu4qNzq8oNRfdf+RD1R +Rg4++U14UbYNvWRQnCqjJGUXDnVc8Gp9K8Z6p5eXihsFfpol1OGu0td1e0FRi3AH +INW9UEpfRbmbEPHhYQRNAyRlcQXJ1FBnxUCk6qgfkD0ziJk2VD4oFoaSlqy7l21z +zoH0Vp6PZGZEIs/mAODvtH5jsTEMUE8uuRmPqgnFqbi/gfQ5FJLR6dfCb8MJ2iJM +Hw4791wi7tS1aCYoHneDtxNFeWuuEmw1uMoA+C5euGNv86XAH5AV2OrTIt8SLFPN +mLBLQ3J9Kkitsy1JFz9IdJ5uY3K2CvpOaP+sx3l1Q4YVuSza8r7zRfTC1wPfbsvk +64zZQzA57WvRvpaZU49HbMV9/zDOlQfLtL7TdAbqLYjlVRpO5pHHEqLRR9eGQ2UY +zhfMFfcJahH4lDbgHf6EVjHnEuoW9fU8hLRVzUcQCVDsf36Et+g5G1JMhFnlVzdv +MaKiN9tzKeIqxUSlXMHYm+oIb849pshNo+KRzZ0K+r+wExnpIfCfVOjAvSQU+6y9 +1uIIQlJfk6uPFVriaooyUDrW9/83AgzJDrkpSMTnVmo/MTS8cAe8Ox5cr+mHqJko +cnHzBNI9Q0z59SpJdXucPVyk5MYPUdfyI2ouicm+nKidNvlp36O7UHMw0pJdeqDg +03vhaVif5uN8FNjBLp6xIipX6lor6XCOnkGR/zkis602sTAkE4nemOw9zy3rIBr+ +hYnSY7vMFCVYIERjqSOLE0k0d5RyOsGjSYr8yQMvpTGusla34qVPjrrpJ+OuczK/ +6KJeHV+WUw42g8JSs67j8YJ2ejc9gr9AVSRiES99QL+tlFnOTY28N40OjXqFJjYK +A0x0By1O6h4PMKtYchTuJAoEOB2KOP1Ta+NlL80zM4nWwv7NdO0AR/ATfUfix1GS +NiMC10C7eurYdAfxly3p9NgjQq+vaKsnSy0TbXPCgW8YTegnxKTUWJm+BEiYaE4M +A0c1CySusV+JO1catlXSeCB6ajddi/SKXsW26lJ3Q+8QqhA3EMivCE3Zh2Q5c1yp +gCV7IXtdryPdK16qmirO9LKkm6sCfBdhgBgi+IcyUhqxwHCwxrPqzEs75Sa3U/6k +kV3AqFwhHYtUj2fBNlfJ1efV8fW+WLboJkHbi2LXmL4NBvHTNjK3NprffFrQ/QJU +oYsMQdeWQZD+3p8w1fPb0sXEDL6LQgjAjyDaqOiX8XrQ8nr3n4FpTI38/OIIfS69 +IHtgo5yv0CMfN+C6LAHOE0aDHRoY6+TVVgr1Z/X2VqJQJONii0dQ5ttDHYnUpzu0 +vWsdvVjsyhkLa2yhUB7UyWusZo0HZRSAcf1pNlpp5rCtJad9to7OvOL3qb5GluAK +/5eZE6RzgyGOjtOx0IgQ+l4ThQCTbkoVEtB59IEeP/+Sq2RmFfdGiGgC3Wnrga8b +gkuXXbjZboptSku6N1ZO1r99wd0qIHzrtVCONGLGfVBy7X6nDO2pC9IUOXycMji7 +B5J0toyDWt6UzlLQasmz8Be7NZJCkDd2jlSKorZtdynsXbRkX1H4by9kI8kEcgK7 +ICE= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-openssl.cnf b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-openssl.cnf new file mode 100644 index 0000000..bf4131f --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-openssl.cnf @@ -0,0 +1,250 @@ +# +# Based on the OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +#CRLDISTPT = [CRL Distribution Point; e.g., http://crl-list.base/w4edom-l4.base.crl] +CRLDISTPT = http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + +# Extra OBJECT IDENTIFIER info: +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used as a login credential +scardLogin=1.3.6.1.4.1.311.20.2.2 +# Used in a smart card login certificate's subject alternative name +msUPN=1.3.6.1.4.1.311.20.2.3 +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used to identify a domain controller +msKDC=1.3.6.1.5.2.3.5 +# Identifies the AD GUID +msADGUID=1.3.6.1.4.1.311.25.1 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = CA-samba.example.com # Where everything is kept +certs = $dir/_none_certs # Where the issued certs are kept +crl_dir = $dir/_none_crl # Where the issued crl are kept +database = $dir/Private/CA-samba.example.com-index.txt # database index file. +unique_subject = yes # Set to 'no' to allow creation of + # several certificates with same subject. +new_certs_dir = $dir/NewCerts # default place for new certs. + +certificate = $dir/Public/CA-samba.example.com-cert.pem # The CA certificate +serial = $dir/Private/CA-samba.example.com-serial.txt # The current serial number +crlnumber = $dir/Private/CA-samba.example.com-crlnumber.txt # the current crl number + # must be commented out to leave a V1 CRL + +#crl = $dir/Public/CA-samba.example.com-crl.pem # The current CRL +crl = $dir/Public/CA-samba.example.com-crl.crl # The current CRL +private_key = $dir/Private/CA-samba.example.com-private-key.pem # The private key +RANDFILE = $dir/Private/CA-samba.example.com.rand # private random number file + +#x509_extensions = # The extensions to add to the cert +x509_extensions = template_x509_extensions + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +crl_extensions = crl_ext + +default_days = 7300 # how long to certify for +default_crl_days= 7300 # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = match +stateOrProvinceName = match +localityName = match +organizationName = match +organizationalUnitName = match +commonName = supplied +emailAddress = supplied + +#################################################################### +[ req ] +default_bits = 4096 +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = SambaState + +localityName = Locality Name (eg, city) +localityName_default = SambaCity + +organizationName = Organization Name (eg, company) +organizationName_default = SambaSelfTesting + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = Domain Controllers + +commonName = Common Name (eg, YOUR name) +commonName_default = localdc.samba.example.com +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = ca-samba.example.com@samba.example.com +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +#challengePassword = A challenge password +#challengePassword_min = 4 +#challengePassword_max = 20 +# +#unstructuredName = An optional company name + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +# Extensions for a typical CA +# PKIX recommendation. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. +keyUsage = cRLSign, keyCertSign + +crlDistributionPoints=URI:$CRLDISTPT + +# Some might want this also +nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +subjectAltName=email:copy +# Copy issuer details +issuerAltName=issuer:copy + +[ crl_ext ] +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +#[ usr_cert_mskdc ] +[ template_x509_extensions ] + +# These extensions are added when 'ca' signs a request for a domain controller certificate. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE +crlDistributionPoints=URI:$CRLDISTPT + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +nsCertType = server + +# This is typical in keyUsage for a client certificate. +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "Domain Controller Certificate localdc.samba.example.com" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. + +subjectAltName=@dc_subjalt + +# Copy subject details +issuerAltName=issuer:copy + +nsCaRevocationUrl = $CRLDISTPT +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +#Extended Key requirements for our domain controller certs +# serverAuth - says cert can be used to identify an ssl/tls server +# msKDC - says cert can be used to identify a Kerberos Domain Controller. +extendedKeyUsage = clientAuth,serverAuth,msKDC + +[dc_subjalt] +DNS=localdc.samba.example.com +otherName=msADGUID;FORMAT:HEX,OCTETSTRING:0123456789ABCDEF diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-private-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-private-key.pem new file mode 100644 index 0000000..546b292 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-private-key.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJJwIBAAKCAgEA5qR2zuhj/lf5o67grU3iFY7YJ8h9fyux6KpQj5T5x3E/UjKR +0W1SIl/NjcxiFnqLWGXtB/fqJNOI2CbK6+wWp4QcfhVGZAkiRrndXAeEUKdOMT8B +I9H4NgQau9TlttQbXBbJnjeKPql9MCRAsrVEQPpcb9U+/zLC5yQK5OSqn/9MrL43 +WCIIFg72py+1bE+se6SCqJ84ZBducrZ8TMVEKgq0JQ2wDKuYSvkaGsmmWfQApQpv +CtClNMoP9A77ute7Pix8DGhrJv8cKf53+TCFDUSMr5CKcJNdOrYYi6WFEVyjXVcW +3cfIAPEFccJuBzw3aTZ8EsWeG2kRRUQe67mylrGJzU36ieuSSfJGNfOdhzy+5Pi3 +Mac2S4F2m7IE1YB9T+YC7SRMoAPEnQCfnXGTDaW4N2IrA8O9JCUsw0PUyCewbQXU +xsXYWwmU6Cdr2W23vN52v9WcNiYEuZcd8MmNkZOCMg23FpdBMZoiCy66mVEoa/UE +usk9Vwxy6OEkGtQqaufjtrmUYeNOQoHlQ+Qe723EXaT5tOw6ijT+tceo/hmNz30b +YCG6JW81zU9yKEJ9hwiq2jN+Y+ZbX+cBqOML0whapt/q5ysTSKeDMpbEutH/FWZS +M4ZGX8KfWUoAmLcboYcl361oW/cmFyvrhGKdw72ZZ2oCXXByPhiSmYy92U8CAwEA +AQKCAgBqVMxJW64t5lU69zax70QZ+D8DKFVjObvNridx6pa1MiqlNJcxXBsPqedU +RjO6dUikumjq0Yrq63MdY9UNq0xOcoPIRPqsx+E7hhjdgsGnhVpxLcDSyMyL6pyA +mAhHn8X1ULQm8ygS94S1myEQwqzy3/mZvVBLyxU8BsvW9u0K0mKBCTjustHTiZaB +QWd8xcaZQiDSqIUQ8BSFYkgwBIoGb+TZaFQPo1SUy/8S9oBw3CMn84V6EPL5QWbV +d8rqOuciJNQTzFgKJHbRjXW2Nn5Avae2kQaiG+5RUP5D801D0denAq2SFbbJaFTA +O4kKYOKS6QGOjfj0Xh4ONveiaXxBSPpIJSvbjAV+Nq92NVkZ35jiPqGZzebhzzoD +mU6mMvRoL/FHs9PKNZF1Cd4EP1SdLhiImj+1eajfYvHAlz6kIJxTue0BFkh13uwp +amx48wB7e/W8t8lqixICf1HlCv+EQGN6aka5dHMqJobXhkt9npz53+AYdpc8Sjs9 +QlFplYoOgkaHvzLv9yeZPOT5Xr32weE6KpM+SwvpVxfttbkvqrWoOoEcDARuVqiS +TRzS/ZDiEn+Kcgm7pJ3i2nTAIBzwC4z91HJbeVXNpptkZJEgjXM8XjSArHjDrkl1 +EGKARlkTn576XMGWSkF/bmEBiG0KIhTu+DmwsQvR+564tjV98QKCAQEA+aS7ygjL +aRj5JZKMt3VWZRntK20m04iY0wGDNs+p+nFRJjCDAUhTTOl9++vlJYe8HO9iXzUv +O51tGnzrck9+gUVlFghrw0dJ+mY0+1bSt2aLNUmlfvv1uRpm9Pd3xbQ6e3Kpf/r1 +ew6IpG8I6pvpVJXJ3FQZpSOlTP9dyRxMNzdILGzzPrb+2r0j6Oc/y3+adBiXB3Yg +QPfFJRJZA4k2Wk/qSi9NR/yWHaY0krO68l8l2zn1AKaIoVVqtxVTQ7qUBWNXzVMe +ULtAvO1Bonh+C+zYcNJjSBeYWeJ7pbp/ozDe6M2DuJMv4aW6oV6tGcMF9NOd1pFx +qiC8vIVPZ3rJ9QKCAQEA7IPf9CAaDUScu2/Ry9z1RaISU4BMi/30poc80Zy2hC18 +vP8aiHVlQdkdzdKYGweaYNQpszGeBcHK51y6V11vwCNQRrCoUp9VbICp7ok2O4y8 +w9r+q4GcYthHeMhEnHDo4R/uHKEJCYS012RLlLSXMa0Dfl1sOv8mVuIEaZoRJrAq +Xzxz9KX7MFv5Zb8TvVL6fHEXmdMmmoiZnyNplH+3LMj6duoNaxjtsoixCkuRTXE7 +Cav118q+QWae+yhIonF+HRIa/G0doqHa+P9rl18FUnxfAf91Z70SSJ2oOtuWjd1J +37eG4d7skpAoWWdXNpCqpJnsPLlSlBqKmYrN5CM3swKCAQBAfV/Np0v00HC8Vgln +8zXoVDRCfaYEC0t/ZuqgpDDC87cE6I9PK4HpYoAbLis58MCVsPl2ouSav+ZJa2/f +Tc3eUzDz6iT8g1QHDZQuQZWZrzHTCD1qemhV8w4Zxjv4pMBe15YV65yyt2RxJgXl +pXU3VqKY+ljNolG3fFib9WVy9iL85wBHeTqJA0ddiS+fwE0EJL4PPWLDpb4V/5Fj +KnUSC4b4txN9vzCAZEk8hJWMuyuqYGR8UIkHNGum9ClYW8CVS76I2ioArP7iT2Af +OoVFS1/2dUMUgpPm1G0guPb0D1HmTgDzE4LRBeEagryw5QKK5oflwBje3ColgUKr +9rppAoIBAH9t9gXkHeU0KHXco16BaCziS5ltsNBkPaJTjvMoyjWhBGoX0EXhanL1 +9dblNkqp6AVviiAgBZH4fcf17/gOQZ116VSM7cPGURIqqGP6zZt8EmA756akKIwh +FzD+Rek79F0HBRWrteDI/V5njUlLm4KKQy2cTCnlOtTo5ZO4DLGZjNrPCXKw0wuV +ImQtdQc2Y/sUO7EHUO9F1e8l90apIRoiFsBnDl+7iKX+e9SeLmVZMoPdgJGJjMRT +9ChB5hCPsXEcRinm6GataftqMp/V9Foi5FWBO9JuziENwIwlr5Izvg+pJCUiJLg6 +r2KsCRM/EpGo1N1KxDFDs5VScegPCX0CggEAWCJ0+KmHbA4F+vDjYW1wNE1MBKee +4Q+nnX45oEHDM+J5da2Ov2IhblzVX/vJaVtI2rwSXCkM3x7ByAXwewNa4BA/eGG/ +v2MPs21f9GcLkpLv0xz+pILkeeNk+e0yIYE4jWQGFMlYh7cNLStDSw6XNU/9IKeO +r2gQjAqS/pMGBMS3FOcd2S+/gMjJom2GaWLhGdJAGdmtGh2EbFku5+WDL76pyAaN +BHEGD91PSER5nEGS9ho81IPDrIm0LVcp6xMRD6PWput/0gcC3Zun1ZDo9oJA1AsS +NMnm6c14ASh/1KQUx9XkC1hUmBVhb4UA4EshT4oXffTHpDMlA6yWqlkReg== +-----END RSA PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-req.pem b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-req.pem new file mode 100644 index 0000000..d2647cc --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-S00-req.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIFDzCCAvcCAQAwgckxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTYW1iYVN0YXRl +MRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNVBAoMEFNhbWJhU2VsZlRlc3Rpbmcx +GzAZBgNVBAsMEkRvbWFpbiBDb250cm9sbGVyczEiMCAGA1UEAwwZbG9jYWxkYy5z +YW1iYS5leGFtcGxlLmNvbTE1MDMGCSqGSIb3DQEJARYmY2Etc2FtYmEuZXhhbXBs +ZS5jb21Ac2FtYmEuZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDmpHbO6GP+V/mjruCtTeIVjtgnyH1/K7HoqlCPlPnHcT9SMpHRbVIi +X82NzGIWeotYZe0H9+ok04jYJsrr7BanhBx+FUZkCSJGud1cB4RQp04xPwEj0fg2 +BBq71OW21BtcFsmeN4o+qX0wJECytURA+lxv1T7/MsLnJArk5Kqf/0ysvjdYIggW +DvanL7VsT6x7pIKonzhkF25ytnxMxUQqCrQlDbAMq5hK+RoayaZZ9AClCm8K0KU0 +yg/0Dvu617s+LHwMaGsm/xwp/nf5MIUNRIyvkIpwk106thiLpYURXKNdVxbdx8gA +8QVxwm4HPDdpNnwSxZ4baRFFRB7rubKWsYnNTfqJ65JJ8kY1852HPL7k+LcxpzZL +gXabsgTVgH1P5gLtJEygA8SdAJ+dcZMNpbg3YisDw70kJSzDQ9TIJ7BtBdTGxdhb +CZToJ2vZbbe83na/1Zw2JgS5lx3wyY2Rk4IyDbcWl0ExmiILLrqZUShr9QS6yT1X +DHLo4SQa1Cpq5+O2uZRh405CgeVD5B7vbcRdpPm07DqKNP61x6j+GY3PfRtgIbol +bzXNT3IoQn2HCKraM35j5ltf5wGo4wvTCFqm3+rnKxNIp4MylsS60f8VZlIzhkZf +wp9ZSgCYtxuhhyXfrWhb9yYXK+uEYp3DvZlnagJdcHI+GJKZjL3ZTwIDAQABoAAw +DQYJKoZIhvcNAQELBQADggIBAFRI0PRZO7XlWIpWUC0wc3KjVvTGxieaalJdPC/j +dxT7lBkSTHGjbeLIkqjVAuhONziKT2RP9QxzK2sa9jxIi5zR1byZv500suTez+96 +KkqSnFTgM4nwJdv2S8x0uBPmlREL4K1I0FGZX29wd0bqFhBQqSzVQvQqGSiqSJfU +KkIys1tAIrC7DfNvfhogIrupuN8clluLe0T25qxGeaqXN+EYB7U/O+4FZccpGoeP +dHO2zYeRib0oGTlnk1noRmlqgXPEKfzoWMJ2cUkexlRy1ajW0r1rvcIgc1rPnB8h +6c6YhFGwbYW54/I6tLxJc5pyWCQNH/uYEeFnGs/w85lPKvLM0RXsQ7rfnDRv3LOj +Mex+3whmIs5dAVdQQMy0ngsbPpaR+5Ry8eWAPmwnRXwVaysGgmTysVCzFGqSO3ul +7FgbKEEM1cNe4+Gvl2LEl+aJ5CB1DBslDjXMQVwLMpAU2sthJurhujx3/j598IUp +why48F4056Uf33CncLSEriykIEFXUionXUxtDsCaS13+CfKw+gUJJRsg4ZWqrY6M +b0KHAtzq4g7lFZ+XaXpGdxntqGOrgxfcgWBRhJnp35ILoMFNV2OHjySnF6SWDJvP +AY9IQsUDiMruNjCS9s5zaH7KqmJJ+pgcjVSholozUEI2J3hUpq3KFsE20Cyi+YbO +kTlo +-----END CERTIFICATE REQUEST----- diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-cert.pem b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-cert.pem new file mode 120000 index 0000000..b7549bb --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-cert.pem @@ -0,0 +1 @@ +DC-localdc.samba.example.com-S00-cert.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-private-key.pem b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-private-key.pem new file mode 120000 index 0000000..21601b4 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/DCs/localdc.samba.example.com/DC-localdc.samba.example.com-private-key.pem @@ -0,0 +1 @@ +DC-localdc.samba.example.com-S00-private-key.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/NewCerts/00.pem b/selftest/manage-ca/CA-samba.example.com/NewCerts/00.pem new file mode 100644 index 0000000..7b1b6a1 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/NewCerts/00.pem @@ -0,0 +1,190 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 16 23:28:44 2016 GMT + Not After : Mar 11 23:28:44 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Domain Controllers, CN=localdc.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:e6:a4:76:ce:e8:63:fe:57:f9:a3:ae:e0:ad:4d: + e2:15:8e:d8:27:c8:7d:7f:2b:b1:e8:aa:50:8f:94: + f9:c7:71:3f:52:32:91:d1:6d:52:22:5f:cd:8d:cc: + 62:16:7a:8b:58:65:ed:07:f7:ea:24:d3:88:d8:26: + ca:eb:ec:16:a7:84:1c:7e:15:46:64:09:22:46:b9: + dd:5c:07:84:50:a7:4e:31:3f:01:23:d1:f8:36:04: + 1a:bb:d4:e5:b6:d4:1b:5c:16:c9:9e:37:8a:3e:a9: + 7d:30:24:40:b2:b5:44:40:fa:5c:6f:d5:3e:ff:32: + c2:e7:24:0a:e4:e4:aa:9f:ff:4c:ac:be:37:58:22: + 08:16:0e:f6:a7:2f:b5:6c:4f:ac:7b:a4:82:a8:9f: + 38:64:17:6e:72:b6:7c:4c:c5:44:2a:0a:b4:25:0d: + b0:0c:ab:98:4a:f9:1a:1a:c9:a6:59:f4:00:a5:0a: + 6f:0a:d0:a5:34:ca:0f:f4:0e:fb:ba:d7:bb:3e:2c: + 7c:0c:68:6b:26:ff:1c:29:fe:77:f9:30:85:0d:44: + 8c:af:90:8a:70:93:5d:3a:b6:18:8b:a5:85:11:5c: + a3:5d:57:16:dd:c7:c8:00:f1:05:71:c2:6e:07:3c: + 37:69:36:7c:12:c5:9e:1b:69:11:45:44:1e:eb:b9: + b2:96:b1:89:cd:4d:fa:89:eb:92:49:f2:46:35:f3: + 9d:87:3c:be:e4:f8:b7:31:a7:36:4b:81:76:9b:b2: + 04:d5:80:7d:4f:e6:02:ed:24:4c:a0:03:c4:9d:00: + 9f:9d:71:93:0d:a5:b8:37:62:2b:03:c3:bd:24:25: + 2c:c3:43:d4:c8:27:b0:6d:05:d4:c6:c5:d8:5b:09: + 94:e8:27:6b:d9:6d:b7:bc:de:76:bf:d5:9c:36:26: + 04:b9:97:1d:f0:c9:8d:91:93:82:32:0d:b7:16:97: + 41:31:9a:22:0b:2e:ba:99:51:28:6b:f5:04:ba:c9: + 3d:57:0c:72:e8:e1:24:1a:d4:2a:6a:e7:e3:b6:b9: + 94:61:e3:4e:42:81:e5:43:e4:1e:ef:6d:c4:5d:a4: + f9:b4:ec:3a:8a:34:fe:b5:c7:a8:fe:19:8d:cf:7d: + 1b:60:21:ba:25:6f:35:cd:4f:72:28:42:7d:87:08: + aa:da:33:7e:63:e6:5b:5f:e7:01:a8:e3:0b:d3:08: + 5a:a6:df:ea:e7:2b:13:48:a7:83:32:96:c4:ba:d1: + ff:15:66:52:33:86:46:5f:c2:9f:59:4a:00:98:b7: + 1b:a1:87:25:df:ad:68:5b:f7:26:17:2b:eb:84:62: + 9d:c3:bd:99:67:6a:02:5d:70:72:3e:18:92:99:8c: + bd:d9:4f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Domain Controller Certificate localdc.samba.example.com + X509v3 Subject Key Identifier: + E1:DF:73:0B:F1:3E:86:43:A4:B3:E9:8D:44:7D:3C:B2:19:C1:BC:F2 + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + X509v3 Subject Alternative Name: + DNS:localdc.samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, TLS Web Server Authentication, msKDC + Signature Algorithm: sha256WithRSAEncryption + 89:2c:57:98:17:c1:73:a6:10:02:6f:a6:ac:47:1c:37:2d:1d: + a1:3c:c5:29:b6:3a:e6:e8:14:ec:3b:74:ee:da:db:2d:97:3e: + d3:8c:9d:42:7e:b0:46:e9:54:74:4f:34:df:9e:34:7f:9e:8a: + 9d:4d:b2:cf:fb:71:3f:cb:32:e6:45:e7:b4:d3:9e:e8:ca:a5: + cf:16:7b:76:b5:4e:e0:b9:bb:79:b1:82:a7:d3:23:cb:3c:46: + 63:63:96:b3:5b:62:9e:99:dc:02:17:f9:07:63:86:76:06:1a: + 02:1b:9a:df:1d:cd:e7:46:fe:9a:13:87:47:dd:e2:77:58:50: + a2:6c:c9:a0:f8:14:1f:3b:d7:59:9c:89:bd:2e:2d:ce:60:f4: + c6:2c:e3:63:cf:34:84:61:d9:90:2e:90:fc:5b:4f:a2:00:87: + e7:40:e0:fc:d1:24:8b:d0:28:01:d3:53:ac:b1:58:7f:87:29: + 38:56:93:dd:a2:14:4a:9a:94:b9:f8:94:b2:04:47:db:b8:38: + e6:85:2b:cf:d4:72:88:8b:0d:8e:a0:69:f9:9f:10:22:82:9c: + c5:ec:01:e3:07:a1:69:37:94:25:3a:cd:17:29:37:8d:24:d3: + 27:0f:4d:bf:b0:31:36:b8:c6:a8:69:0b:df:28:f8:e2:dc:da: + 95:3e:7f:d7:3f:a5:8f:92:6a:7d:ad:3a:ac:af:73:2b:5f:f1: + b3:22:92:ef:da:71:84:9e:4b:23:7b:69:b7:29:fc:c5:05:84: + 4b:ff:06:92:ee:f5:9b:14:2a:af:be:ef:02:e1:e7:d0:e8:d0: + 29:7c:48:40:f1:95:bb:08:b2:30:c5:81:80:a8:91:5b:2e:08: + 3b:30:44:07:b5:c4:0b:07:74:ca:5d:37:3d:75:f9:bc:6d:21: + a6:e0:91:d8:f9:27:88:05:58:a7:f4:36:eb:ba:40:63:36:15: + 42:98:0b:e2:d1:c9:11:0b:29:81:e1:c7:02:7e:fa:05:65:51: + 7b:d6:1a:33:46:fc:a5:d4:fd:64:e8:c8:11:d4:d1:41:d9:39: + 18:08:a3:ed:15:70:d9:14:f5:ba:c9:bb:3e:96:8d:5d:cc:c3: + 5c:b6:c8:79:02:2e:e2:a1:06:ba:a5:21:1c:bf:16:7f:2d:d9: + 93:07:92:b1:fa:ee:3f:e3:56:35:f3:30:aa:11:54:d3:71:cb: + 29:d4:60:e1:6c:ae:c4:24:e3:00:4f:5f:52:b0:3f:f4:76:f3: + 6d:db:bc:d8:65:c4:37:be:1a:87:9b:65:c4:20:dd:da:a9:4c: + 9f:86:33:2b:49:a6:f7:aa:ce:da:98:3b:e3:5f:ac:b8:1b:45: + 0e:56:59:fb:49:38:0f:b7:d4:49:f8:7b:ac:fa:d8:b8:1d:16: + db:b2:4c:15:d8:e7:eb:6b:38:ff:d2:69:26:a6:f6:50:15:45: + 2f:12:b2:05:d4:bf:6f:53:79:64:9b:d5:8b:a1:08:3e:43:ee: + 08:fe:9b:ea:83:89:8a:6a:53:98:1e:c5:91:4c:7a:99:2b:6d: + 97:dc:96:1b:de:27:c5:af:0f:dd:42:5c:23:7d:bc:6b:5b:ab: + 47:29:98:35:8f:9e:e6:e1:5f:96:6a:bd:cf:3c:47:89:8b:ad: + 21:de:20:da:99:82:c1:0e:9b:7c:38:21:d8:b1:1c:34:c5:4e: + f7:fe:7d:5e:a4:2f:f8:7d:5c:30:2c:9e:e6:5a:4f:d3:15:90: + e6:6f:69:ea:51:93:8f:2c:dd:a7:c3:3c:50:a8:d1:ba:0b:5c: + cc:2e:4e:57:71:21:08:a1:2c:bd:a7:20:4b:ae:5c:02:7a:cd: + 9a:fe:1e:db:ec:ce:3b:12:37:cb:96:20:7b:3b:b1:5a:2e:84: + 03:f9:0b:32:43:c0:4e:e3:ea:79:e7:9a:13:54:e5:a8:1a:17: + c4:79:78:25:63:ab:67:39:39:a0:6c:c4:c5:94:ac:16:92:3d: + f0:1a:1a:9e:ca:7a:84:1b:c1:5a:5f:4c:65:8a:30:a6:5e:6c: + 0e:ae:bf:ac:09:97:0f:83:5c:92:ce:e4:43:de:06:4b:96:f5: + 46:3b:7d:a8:e3:0f:d3:fe:00:c7:d4:79:4e:5f:bd:ec:59:12: + f9:65:23:fa:e7:97:a2:a6:39:3b:a3:1e:da:47:c5:18:5b:8d: + a7:7b:29:1c:5a:7a:06:c6:92:9e:b7:3b:f0:c5:56:e8:cf:84: + cd:dd:61:0f:21:25:f4:1e:2b:40:b6:74:28:8d:41:f6:2c:1d: + ce:b4:39:d1:e1:be:15:78:c9:d7:99:a1:9d:50:43:da:ec:40: + 69:6a:3b:17:af:28:22:09:e0:7d:38:9e:a7:ca:b7:f7:94:8a: + 2a:1b:32:4e:28:6d:18:95:ca:42:67:c8:bb:13:24:31:43:84: + 3e:95:66:08:5c:15:7f:6b:93:cc:8f:b8:76:7a:fd:74:4a:d6: + 6f:64:74:df:72:f7:34:a3:50:f0:db:bf:0a:2b:1b:48:b7:c9: + c0:97:23:27:b1:56:5b:9e:10:12:5a:bf:ff:38:61:da:41:75: + 15:c5:03:c2:20:fd:7f:84:c0:94:8e:11:ed:01:ba:f1:19:b5: + 05:1d:bf:89:ea:c9:38:4e:d2:cf:5b:24:c6:37:a1:8e:60:89: + 5c:52:ff:7d:5e:2d:c9:f8:b1:79:07:4c:2f:18:85:e8:ba:bf: + 3e:da:59:43:df:29:79:7e:00:38:d2:fc:a9:8e:3b:9d +-----BEGIN CERTIFICATE----- +MIIJ6zCCBdOgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI4NDRaFw0zNjAzMTEyMzI4NDRaMIG1MQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEbMBkGA1UE +CwwSRG9tYWluIENvbnRyb2xsZXJzMSIwIAYDVQQDDBlsb2NhbGRjLnNhbWJhLmV4 +YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkBFiZjYS1zYW1iYS5leGFtcGxlLmNvbUBz +YW1iYS5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AOakds7oY/5X+aOu4K1N4hWO2CfIfX8rseiqUI+U+cdxP1IykdFtUiJfzY3MYhZ6 +i1hl7Qf36iTTiNgmyuvsFqeEHH4VRmQJIka53VwHhFCnTjE/ASPR+DYEGrvU5bbU +G1wWyZ43ij6pfTAkQLK1RED6XG/VPv8ywuckCuTkqp//TKy+N1giCBYO9qcvtWxP +rHukgqifOGQXbnK2fEzFRCoKtCUNsAyrmEr5GhrJpln0AKUKbwrQpTTKD/QO+7rX +uz4sfAxoayb/HCn+d/kwhQ1EjK+QinCTXTq2GIulhRFco11XFt3HyADxBXHCbgc8 +N2k2fBLFnhtpEUVEHuu5spaxic1N+onrkknyRjXznYc8vuT4tzGnNkuBdpuyBNWA +fU/mAu0kTKADxJ0An51xkw2luDdiKwPDvSQlLMND1MgnsG0F1MbF2FsJlOgna9lt +t7zedr/VnDYmBLmXHfDJjZGTgjINtxaXQTGaIgsuuplRKGv1BLrJPVcMcujhJBrU +Kmrn47a5lGHjTkKB5UPkHu9txF2k+bTsOoo0/rXHqP4Zjc99G2AhuiVvNc1PcihC +fYcIqtozfmPmW1/nAajjC9MIWqbf6ucrE0ingzKWxLrR/xVmUjOGRl/Cn1lKAJi3 +G6GHJd+taFv3Jhcr64RincO9mWdqAl1wcj4YkpmMvdlPAgMBAAGjggHxMIIB7TAJ +BgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly93d3cuc2FtYmEuZXhh +bXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMBEGCWCG +SAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwRgYJYIZIAYb4QgENBDkWN0RvbWFp +biBDb250cm9sbGVyIENlcnRpZmljYXRlIGxvY2FsZGMuc2FtYmEuZXhhbXBsZS5j +b20wHQYDVR0OBBYEFOHfcwvxPoZDpLPpjUR9PLIZwbzyMB8GA1UdIwQYMBaAFKI+ +Aiqjp005tAhNmcwMdTbqJ8M+MD0GA1UdEQQ2MDSCGWxvY2FsZGMuc2FtYmEuZXhh +bXBsZS5jb22gFwYJKwYBBAGCNxkBoAoECAEjRWeJq83vMDEGA1UdEgQqMCiBJmNh +LXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0GCWCGSAGG+EIB +BARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMvQ0Etc2FtYmEu +ZXhhbXBsZS5jb20tY3JsLmNybDAmBgNVHSUEHzAdBggrBgEFBQcDAgYIKwYBBQUH +AwEGBysGAQUCAwUwDQYJKoZIhvcNAQELBQADggQBAIksV5gXwXOmEAJvpqxHHDct +HaE8xSm2OuboFOw7dO7a2y2XPtOMnUJ+sEbpVHRPNN+eNH+eip1Nss/7cT/LMuZF +57TTnujKpc8We3a1TuC5u3mxgqfTI8s8RmNjlrNbYp6Z3AIX+QdjhnYGGgIbmt8d +zedG/poTh0fd4ndYUKJsyaD4FB8711mcib0uLc5g9MYs42PPNIRh2ZAukPxbT6IA +h+dA4PzRJIvQKAHTU6yxWH+HKThWk92iFEqalLn4lLIER9u4OOaFK8/UcoiLDY6g +afmfECKCnMXsAeMHoWk3lCU6zRcpN40k0ycPTb+wMTa4xqhpC98o+OLc2pU+f9c/ +pY+San2tOqyvcytf8bMiku/acYSeSyN7abcp/MUFhEv/BpLu9ZsUKq++7wLh59Do +0Cl8SEDxlbsIsjDFgYCokVsuCDswRAe1xAsHdMpdNz11+bxtIabgkdj5J4gFWKf0 +Nuu6QGM2FUKYC+LRyRELKYHhxwJ++gVlUXvWGjNG/KXU/WToyBHU0UHZORgIo+0V +cNkU9brJuz6WjV3Mw1y2yHkCLuKhBrqlIRy/Fn8t2ZMHkrH67j/jVjXzMKoRVNNx +yynUYOFsrsQk4wBPX1KwP/R2823bvNhlxDe+GoebZcQg3dqpTJ+GMytJpveqztqY +O+NfrLgbRQ5WWftJOA+31En4e6z62LgdFtuyTBXY5+trOP/SaSam9lAVRS8SsgXU +v29TeWSb1YuhCD5D7gj+m+qDiYpqU5gexZFMepkrbZfclhveJ8WvD91CXCN9vGtb +q0cpmDWPnubhX5Zqvc88R4mLrSHeINqZgsEOm3w4IdixHDTFTvf+fV6kL/h9XDAs +nuZaT9MVkOZvaepRk48s3afDPFCo0boLXMwuTldxIQihLL2nIEuuXAJ6zZr+Htvs +zjsSN8uWIHs7sVouhAP5CzJDwE7j6nnnmhNU5agaF8R5eCVjq2c5OaBsxMWUrBaS +PfAaGp7KeoQbwVpfTGWKMKZebA6uv6wJlw+DXJLO5EPeBkuW9UY7fajjD9P+AMfU +eU5fvexZEvllI/rnl6KmOTujHtpHxRhbjad7KRxaegbGkp63O/DFVujPhM3dYQ8h +JfQeK0C2dCiNQfYsHc60OdHhvhV4ydeZoZ1QQ9rsQGlqOxevKCIJ4H04nqfKt/eU +iiobMk4obRiVykJnyLsTJDFDhD6VZghcFX9rk8yPuHZ6/XRK1m9kdN9y9zSjUPDb +vworG0i3ycCXIyexVlueEBJav/84YdpBdRXFA8Ig/X+EwJSOEe0BuvEZtQUdv4nq +yThO0s9bJMY3oY5giVxS/31eLcn4sXkHTC8Yhei6vz7aWUPfKXl+ADjS/KmOO50= +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/NewCerts/01.pem b/selftest/manage-ca/CA-samba.example.com/NewCerts/01.pem new file mode 100644 index 0000000..4ab5d5a --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/NewCerts/01.pem @@ -0,0 +1,169 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 16 23:29:04 2016 GMT + Not After : Mar 11 23:29:04 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Users, CN=administrator@samba.example.com/emailAddress=administrator@samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:af:87:9e:1e:7f:c0:ab:da:47:22:74:d0:df:01: + f1:67:6c:ac:c4:b7:d9:18:97:e5:7a:62:76:33:b6: + 52:f2:92:90:75:ac:a3:94:7e:0c:29:75:c9:83:2f: + 19:66:60:84:45:ff:d5:a9:bd:c5:3a:a2:d8:25:cf: + 15:8a:23:3e:09:73:2f:99:1d:24:1f:e6:96:7e:7b: + c4:1e:8d:55:5b:c1:18:69:cd:1d:b4:22:d5:7b:db: + 5e:7c:91:f2:8e:c1:03:30:ee:63:46:5a:54:d5:40: + ac:79:55:00:71:07:8d:3e:0e:ed:ff:93:6c:f1:2d: + 84:c1:51:a3:7c:49:cf:ff:85:7b:c0:64:c1:ba:c8: + 66:7a:ff:17:2a:74:ea:16:6a:1d:97:c0:27:57:10: + be:76:f5:9a:63:56:c7:25:c6:fc:a7:5e:00:a6:1a: + 3d:21:bd:7a:f9:e3:03:60:ce:df:16:06:fc:05:bc: + d1:c8:5d:e7:33:ed:52:8b:60:5b:60:c5:70:13:1d: + c1:b3:08:13:09:3b:05:e8:02:40:12:45:89:af:87: + 1f:6a:8f:62:ce:1e:17:13:34:82:81:86:e9:bb:85: + 5b:75:1d:f4:3a:02:b4:a6:58:23:fe:c3:3a:35:09: + 95:bb:f7:79:bc:e3:97:e6:6d:77:24:aa:2d:51:50: + 37:69 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Client, S/MIME + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Smart Card Login Certificate for administrator@samba.example.com + X509v3 Subject Key Identifier: + 45:DA:4B:8D:05:9C:62:4E:62:C3:D7:5C:5F:D3:D9:85:B4:9B:F2:2C + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + X509v3 Subject Alternative Name: + email:administrator@samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, scardLogin + Signature Algorithm: sha256WithRSAEncryption + a2:bb:e6:97:67:3c:b6:6e:6e:dd:34:99:16:c6:80:91:08:bf: + 91:ba:51:62:5d:76:2f:e5:53:91:3d:99:03:18:a9:84:69:73: + 76:66:c3:eb:56:d7:c5:40:91:15:da:de:b2:76:48:7d:8a:8c: + 80:79:3c:e6:da:0e:a6:c3:53:d6:74:ee:5f:29:b7:03:46:de: + 89:32:14:22:03:30:68:2e:7e:06:d4:ac:9e:82:c0:02:16:7f: + 81:ba:ee:7a:e7:8b:f7:fb:99:7f:8c:eb:78:54:97:4e:28:44: + da:f4:e2:1b:f8:3e:ac:ca:cc:e3:e3:71:90:91:47:9c:78:ed: + 6f:bc:b7:98:12:ea:75:e5:15:f7:26:56:a7:5c:d6:74:a8:13: + 7b:23:35:4e:6a:01:f6:a9:f5:5b:9b:d0:ea:ba:0f:c3:c4:1a: + e0:b9:a3:ed:5d:28:cb:7f:1d:3e:8a:9a:af:4c:88:00:3c:10: + f0:49:85:24:60:e6:cb:d6:9e:00:46:78:4d:90:22:68:4f:10: + 39:84:3b:e2:7c:3d:ed:23:41:19:7e:6f:45:59:89:a9:9f:26: + c1:f9:7d:4d:0a:b4:10:f9:31:7d:cc:87:d0:4b:62:14:70:86: + c8:7d:14:ff:e4:68:e2:de:42:ca:01:c7:aa:2d:5a:a5:72:64: + f1:4c:fa:6e:60:15:22:08:68:e6:c6:6a:75:63:24:b5:54:76: + d1:97:4f:e0:e8:bc:eb:d0:62:84:4a:b4:3a:07:38:5f:b9:a6: + 6a:31:14:47:33:81:bd:d0:a4:a2:da:2b:92:0d:dc:42:c4:0f: + 28:0d:b6:1b:33:b5:88:df:1b:a8:d8:90:9a:11:ce:df:d4:14: + e9:ac:94:94:95:bb:bc:6e:f1:be:85:29:3f:17:ab:41:14:d8: + 20:ba:e0:a2:a3:d3:d4:8b:1e:4b:32:22:8d:0d:c1:e6:39:1a: + ce:cd:f3:1d:f1:82:85:d5:e7:80:34:90:a4:0e:d4:af:32:c8: + 79:4e:25:32:b6:1e:06:3a:26:42:38:47:1a:32:96:71:5b:fe: + 5b:b0:ef:7d:fe:58:ca:eb:b5:c9:4b:2f:12:cb:89:36:22:7c: + a6:39:ab:20:c1:2d:cd:6b:34:e1:cd:bc:ed:45:45:12:4a:65: + 4b:ab:45:f2:6d:7a:9d:f8:b5:52:78:1b:da:2f:e0:ce:f7:e2: + b0:fa:6f:40:3d:dd:e9:39:c3:63:68:ab:77:53:be:3b:dd:9a: + bc:d7:d7:fa:6a:bf:bf:74:f7:11:80:87:f9:d3:45:eb:1e:8e: + d1:a9:a0:2e:66:e7:20:67:1c:4c:22:43:77:85:ff:1a:23:37: + cc:49:de:51:ee:f2:04:2f:a8:98:88:0f:b6:18:53:eb:e2:49: + 15:5e:02:8b:1e:7b:e6:c5:d1:0c:df:84:4e:d9:bd:fe:21:48: + d4:a4:11:01:27:57:51:d6:c1:b2:a1:1c:11:9a:a7:d1:ab:f0: + 99:16:b2:c8:3f:74:25:68:0b:1a:cf:58:0d:cd:cc:1a:6d:8b: + ec:1f:70:82:02:40:97:0f:75:2c:53:87:c1:42:5c:d1:7e:19: + 78:2c:2c:88:73:33:81:63:38:84:07:0f:16:bb:7c:54:59:03: + 94:e7:b8:85:d7:f8:5e:53:35:65:2e:e5:27:65:be:f0:89:65: + f6:ab:3f:6e:a5:bd:c1:1a:9e:31:30:68:6e:50:af:54:4c:33: + f8:73:2f:41:60:4f:4c:85:1b:ad:7d:db:62:42:dc:87:96:b4: + cf:ce:12:50:ed:6c:01:5f:e2:f9:03:f5:f7:4c:6c:8f:2b:5b: + 7a:64:7d:19:e8:20:f2:e9:10:58:f3:71:0e:1e:58:68:f2:59: + 3c:06:53:7a:f3:60:62:5b:c7:b7:83:58:1d:3d:a6:17:db:33: + cc:91:14:af:d6:b9:08:bf:60:af:ac:3e:fe:8b:74:71:20:c7: + e7:31:5e:26:6c:28:52:67:12:1e:c3:9b:89:23:5d:88:ee:b0: + 6b:db:cc:94:8b:9b:1b:40:b7:66:bc:7d:1d:e1:08:00:20:ba: + 41:cd:17:d6:4c:7b:c4:5a:fd:cf:6b:20:e2:b8:86:9c:31:17: + c2:d7:7f:1c:3a:d0:fc:1d:f5:7f:c9:96:04:27:de:b8:ef:8d: + 38:9a:b3:56:60:ac:c2:07:38:64:19:39:9e:73:6f:ba:59:15: + ac:45:42:4d:bb:79:60:7f:ae:c3:8d:63:4a:27:16:0a:ca:92: + 7f:f7:a2:02:76:f5:e6:7c:ec:ba:ea:18:cd:9c:3b:ee:37:2c: + 9d:78:4e:c9:40:6d:94:cc:ce:ca:f4:33:fc:a4:dd:05:62:d6: + 0f:1e:19:63:af:10:c3:ff:02:1a:0a:48:fd:af:f2:a4:0e:64: + dd:90:f4:4f:14:1b:90:1f:9e:29:b0:0b:94:a4:d1:2a:87:b9: + 3a:76:c2:b6:af:c3:d4:84:6e:85:1c:64:73:46:d0:df:72:c0: + 3c:42:91:c4:30:10:11:18:36:bc:e5:17:36:22:5f:c2:3f:ac: + 1d:2e:9d:87:11:be:a7:ac:b2:62:35:74:b9:27:27:95:bc:c1: + 11:44:f8:64:36:60:74:06:a2:e7:e9:76:be:a7:86:5e:18:1e: + bd:dc:b0:aa:ae:92:d6:dd:d6:25:80:d6:c1:be:c1:21:1c:01: + 6f:83:20:ae:b7:54:4f:3d:2d:12:fc:a2:cc:49:fd:59 +-----BEGIN CERTIFICATE----- +MIII/TCCBOWgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI5MDRaFw0zNjAzMTEyMzI5MDRaMIGnMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEOMAwGA1UE +CwwFVXNlcnMxKDAmBgNVBAMMH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5j +b20xLjAsBgkqhkiG9w0BCQEWH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5j +b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvh54ef8Cr2kcidNDf +AfFnbKzEt9kYl+V6YnYztlLykpB1rKOUfgwpdcmDLxlmYIRF/9WpvcU6otglzxWK +Iz4Jcy+ZHSQf5pZ+e8QejVVbwRhpzR20ItV72158kfKOwQMw7mNGWlTVQKx5VQBx +B40+Du3/k2zxLYTBUaN8Sc//hXvAZMG6yGZ6/xcqdOoWah2XwCdXEL529ZpjVscl +xvynXgCmGj0hvXr54wNgzt8WBvwFvNHIXecz7VKLYFtgxXATHcGzCBMJOwXoAkAS +RYmvhx9qj2LOHhcTNIKBhum7hVt1HfQ6ArSmWCP+wzo1CZW793m845fmbXckqi1R +UDdpAgMBAAGjggIRMIICDTAJBgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0 +dHA6Ly93d3cuc2FtYmEuZXhhbXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxl +LmNvbS1jcmwuY3JsMBEGCWCGSAGG+EIBAQQEAwIFoDALBgNVHQ8EBAMCBeAwTwYJ +YIZIAYb4QgENBEIWQFNtYXJ0IENhcmQgTG9naW4gQ2VydGlmaWNhdGUgZm9yIGFk +bWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5jb20wHQYDVR0OBBYEFEXaS40FnGJO +YsPXXF/T2YW0m/IsMB8GA1UdIwQYMBaAFKI+Aiqjp005tAhNmcwMdTbqJ8M+MFsG +A1UdEQRUMFKBH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5jb22gLwYKKwYB +BAGCNxQCA6AhDB9hZG1pbmlzdHJhdG9yQHNhbWJhLmV4YW1wbGUuY29tMDEGA1Ud +EgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0G +CWCGSAGG+EIBBARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMv +Q0Etc2FtYmEuZXhhbXBsZS5jb20tY3JsLmNybDAfBgNVHSUEGDAWBggrBgEFBQcD +AgYKKwYBBAGCNxQCAjANBgkqhkiG9w0BAQsFAAOCBAEAorvml2c8tm5u3TSZFsaA +kQi/kbpRYl12L+VTkT2ZAxiphGlzdmbD61bXxUCRFdresnZIfYqMgHk85toOpsNT +1nTuXym3A0beiTIUIgMwaC5+BtSsnoLAAhZ/gbrueueL9/uZf4zreFSXTihE2vTi +G/g+rMrM4+NxkJFHnHjtb7y3mBLqdeUV9yZWp1zWdKgTeyM1TmoB9qn1W5vQ6roP +w8Qa4Lmj7V0oy38dPoqar0yIADwQ8EmFJGDmy9aeAEZ4TZAiaE8QOYQ74nw97SNB +GX5vRVmJqZ8mwfl9TQq0EPkxfcyH0EtiFHCGyH0U/+Ro4t5CygHHqi1apXJk8Uz6 +bmAVIgho5sZqdWMktVR20ZdP4Oi869BihEq0Ogc4X7mmajEURzOBvdCkotorkg3c +QsQPKA22GzO1iN8bqNiQmhHO39QU6ayUlJW7vG7xvoUpPxerQRTYILrgoqPT1Ise +SzIijQ3B5jkazs3zHfGChdXngDSQpA7UrzLIeU4lMrYeBjomQjhHGjKWcVv+W7Dv +ff5Yyuu1yUsvEsuJNiJ8pjmrIMEtzWs04c287UVFEkplS6tF8m16nfi1Ungb2i/g +zvfisPpvQD3d6TnDY2ird1O+O92avNfX+mq/v3T3EYCH+dNF6x6O0amgLmbnIGcc +TCJDd4X/GiM3zEneUe7yBC+omIgPthhT6+JJFV4Cix575sXRDN+ETtm9/iFI1KQR +ASdXUdbBsqEcEZqn0avwmRayyD90JWgLGs9YDc3MGm2L7B9wggJAlw91LFOHwUJc +0X4ZeCwsiHMzgWM4hAcPFrt8VFkDlOe4hdf4XlM1ZS7lJ2W+8Ill9qs/bqW9wRqe +MTBoblCvVEwz+HMvQWBPTIUbrX3bYkLch5a0z84SUO1sAV/i+QP190xsjytbemR9 +Gegg8ukQWPNxDh5YaPJZPAZTevNgYlvHt4NYHT2mF9szzJEUr9a5CL9gr6w+/ot0 +cSDH5zFeJmwoUmcSHsObiSNdiO6wa9vMlIubG0C3Zrx9HeEIACC6Qc0X1kx7xFr9 +z2sg4riGnDEXwtd/HDrQ/B31f8mWBCfeuO+NOJqzVmCswgc4ZBk5nnNvulkVrEVC +Tbt5YH+uw41jSicWCsqSf/eiAnb15nzsuuoYzZw77jcsnXhOyUBtlMzOyvQz/KTd +BWLWDx4ZY68Qw/8CGgpI/a/ypA5k3ZD0TxQbkB+eKbALlKTRKoe5OnbCtq/D1IRu +hRxkc0bQ33LAPEKRxDAQERg2vOUXNiJfwj+sHS6dhxG+p6yyYjV0uScnlbzBEUT4 +ZDZgdAai5+l2vqeGXhgevdywqq6S1t3WJYDWwb7BIRwBb4MgrrdUTz0tEvyizEn9 +WQ== +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/NewCerts/02.pem b/selftest/manage-ca/CA-samba.example.com/NewCerts/02.pem new file mode 100644 index 0000000..2e2a8b9 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/NewCerts/02.pem @@ -0,0 +1,191 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 16 23:29:25 2016 GMT + Not After : Mar 11 23:29:25 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Domain Controllers, CN=addc.addom.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:a6:c4:a9:bf:75:ea:4c:8d:3b:fd:8a:0f:b0:a2: + b6:c7:a8:1f:e4:0e:3e:41:ef:d6:10:48:77:7b:4e: + 4c:59:e1:bf:6d:c7:18:7b:a8:01:a7:d5:d2:2c:21: + 3e:d0:1a:da:58:03:e8:42:f1:53:0e:a7:91:b9:2c: + b9:e7:7a:c9:de:5e:ed:4c:93:6b:cc:dd:17:d0:c7: + d1:f1:7c:3d:0d:6f:df:5d:53:5a:b1:1f:a3:7b:5b: + 41:65:0c:7c:ea:53:df:bb:da:41:15:da:49:e3:b9: + 2d:bb:b5:af:ef:8c:b8:84:74:d0:18:16:8e:5c:e4: + c2:e7:a1:87:8f:e3:87:8b:0b:bb:90:30:e8:e0:f3: + eb:c0:50:5f:b5:7f:54:9a:1b:34:43:fd:be:5a:80: + 6e:0f:63:a2:b3:79:42:4a:85:c8:07:c7:82:55:23: + 88:d4:4e:03:2f:f1:95:bd:ed:15:2d:3e:16:cd:ff: + c7:9b:03:29:36:a6:5d:c9:1a:1e:89:a5:ba:66:83: + 0f:96:a8:07:9f:24:b9:1b:8f:02:9a:b8:50:29:8b: + be:63:45:fa:45:c3:38:23:a0:98:3a:b4:6b:42:99: + 13:36:4b:84:ef:27:89:39:34:79:f8:67:16:7b:9c: + 2a:03:41:15:63:46:e4:db:2f:f2:3e:6d:fe:7c:20: + 1e:9f:02:48:a4:bc:15:42:a6:f8:38:86:dc:6b:7c: + 4e:67:a3:31:81:8e:b6:30:1a:eb:3d:08:25:19:5f: + 42:dc:39:ec:79:1d:30:0a:fb:16:8f:3d:19:14:cc: + f5:af:d7:c6:75:cf:b3:96:a2:b2:9b:d9:03:01:a3: + ca:88:1d:72:ed:6f:d1:bf:57:56:8e:b9:07:9b:b9: + 04:13:1e:0b:5a:06:6b:2b:43:a2:dc:d5:b7:f4:ba: + d3:ae:9d:ad:fd:d3:8a:7c:2f:87:32:fa:89:88:58: + 00:ae:16:2b:9c:1d:58:82:4d:e5:21:da:d5:6c:f7: + a8:40:8b:c7:02:d5:36:30:ef:3f:09:9b:a6:d2:31: + a3:bf:20:d4:a2:9e:26:c4:b4:c3:0f:0b:6c:00:d1: + 2c:16:b1:2a:eb:06:d9:d5:98:c3:cd:cb:20:68:ad: + 0a:2c:a1:2f:27:41:5c:91:de:49:62:ed:d8:3a:ef: + 68:1c:6d:fe:94:c3:28:68:32:60:08:65:cd:02:9f: + 97:96:2f:0f:87:27:3d:b9:0f:85:62:e8:2b:9a:b4: + f4:d3:d7:c1:93:96:27:23:29:88:b1:39:99:53:3a: + 20:aa:88:44:3b:4a:24:2a:8b:e0:b4:8d:dd:66:30: + df:a6:6e:b7:fc:21:43:16:9e:3e:12:20:c8:7a:30: + c1:3d:ab + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Server + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Domain Controller Certificate addc.addom.samba.example.com + X509v3 Subject Key Identifier: + 3D:BC:70:0C:74:D4:B8:85:49:1D:08:84:C4:1B:27:F2:AF:72:37:D3 + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + X509v3 Subject Alternative Name: + DNS:addc.addom.samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, TLS Web Server Authentication, msKDC + Signature Algorithm: sha256WithRSAEncryption + 9e:8b:bb:0a:7a:dc:c0:94:33:bc:18:a5:e6:4a:1f:ff:8e:21: + b1:8f:33:f0:3e:8b:6c:72:55:c4:47:71:5f:ce:e7:31:ef:5b: + 62:04:b7:57:8f:a8:27:9f:ed:69:d2:ec:a8:0d:e2:76:33:8d: + 41:3a:67:61:5c:53:60:c7:53:ed:d7:99:72:29:1d:ae:d3:ee: + c9:76:1c:6d:18:47:e9:94:dd:2e:97:3f:99:af:b5:f4:a1:7c: + 92:f6:4d:b5:c1:7a:0c:38:ba:d1:b6:19:9a:9f:e2:02:84:d4: + 54:01:38:7b:55:86:4a:ee:3d:85:48:01:da:34:09:69:43:25: + 7e:6e:06:73:e0:b9:7c:b5:9c:4e:9c:b5:52:85:32:62:62:25: + 39:fa:02:4b:51:2e:df:8e:52:17:02:50:f4:99:29:bf:7e:97: + 53:91:12:85:9a:69:62:45:59:c4:5b:3f:af:18:e6:7b:e4:86: + 5d:f1:9e:5a:2b:3e:14:6e:7e:d4:47:24:ef:d9:a8:ec:d9:a6: + cb:b8:4f:1a:86:d9:43:20:41:16:15:5f:81:0d:fe:6b:31:53: + c1:f6:84:4c:f3:03:64:d2:e6:44:3d:7a:60:79:d7:37:6f:33: + de:c0:a8:b9:6e:fe:b2:79:ac:b4:53:92:b8:0a:59:2b:cc:6b: + 37:c4:6f:c6:44:02:f7:7c:c5:c6:a6:6f:c2:ad:de:78:1e:48: + 96:cc:fe:59:2e:53:ce:34:d6:e8:f0:56:43:30:32:90:6f:f9: + 47:76:ab:99:63:e3:e8:a3:f3:83:98:e9:05:2b:ea:f9:f9:9d: + 66:70:c7:2c:00:c2:9e:57:3e:31:43:50:50:c8:db:a8:2d:21: + 4e:6f:39:c2:bd:ef:d8:47:99:27:0d:48:b2:58:f1:be:45:bd: + fe:c4:a2:56:fc:06:02:dc:19:33:85:53:ed:38:59:01:16:bc: + aa:c5:d3:4b:37:54:83:1b:e5:c1:4b:dd:34:6b:e5:d8:35:86: + 95:e6:9f:d2:22:84:b1:e2:4f:a7:2e:4d:e6:9c:eb:db:df:42: + e1:b4:66:e6:58:d3:28:10:34:97:f3:9c:6b:5f:05:2c:47:2c: + e3:75:eb:6f:74:0a:ec:d7:1d:30:80:56:44:12:26:f6:4e:5f: + ff:92:f4:62:02:36:9c:62:eb:39:98:53:68:68:95:fb:94:68: + 69:b8:3c:66:1a:ce:78:c4:cf:c4:6f:21:ac:a8:a6:f4:ab:69: + 2a:2e:00:5d:f7:67:06:b1:4f:97:58:88:55:d8:6e:eb:a5:98: + 50:36:21:70:3d:b0:a4:f5:3b:21:b3:1c:f5:a9:dd:c6:4a:c2: + 89:b8:5a:b3:bc:1f:21:ce:4c:68:5f:98:d8:39:70:d2:7e:a0: + 90:df:ad:a3:13:eb:3c:93:f6:b8:f4:d9:a7:51:b3:0d:ea:ee: + d4:57:aa:db:ca:7c:8a:a0:08:c3:98:9a:3a:b7:ba:2a:50:92: + 26:c2:e3:11:ba:12:60:24:b9:59:df:62:a8:d7:4d:a3:cb:ea: + 46:e8:39:f9:83:14:a8:5c:44:75:71:6b:7f:99:bd:68:58:d9: + 6b:d1:cd:c7:45:95:9e:44:1e:85:35:c0:30:2b:18:aa:eb:2f: + 93:d5:be:66:5d:70:ed:1d:04:f2:c1:1e:b5:ec:45:0c:04:f6: + 9d:88:d3:0c:20:5e:5b:23:df:34:a1:f5:ea:b4:a1:44:c0:da: + d5:ea:89:e8:b5:cb:dc:f8:92:ee:ac:8d:61:ed:bf:74:2b:28: + 79:1f:f4:9a:ff:63:bd:e6:aa:79:1d:2c:26:4a:b2:26:53:57: + ba:88:0e:eb:19:57:c0:10:a0:1e:81:2a:c0:56:2e:c3:2a:81: + bf:c1:5a:e7:48:ce:c1:6a:b9:6c:41:cc:44:a6:b8:70:e2:57: + 0e:6d:41:d6:61:da:bf:ac:20:2c:a7:2a:67:23:98:00:ba:ce: + 8b:a8:c2:45:66:a7:08:eb:7f:0a:b5:e7:9b:d6:f4:07:d5:b3: + 43:cd:27:d4:fa:c9:40:8f:af:b2:36:1c:e7:44:b4:4e:cc:5a: + 2b:73:ad:8f:c4:d9:47:a6:fb:2c:7d:1a:80:2a:55:b3:80:34: + 6f:8e:17:27:93:05:21:40:e9:8f:bf:47:6a:52:f5:2e:b5:18: + d1:8c:1d:83:04:80:55:fd:21:28:dc:7c:be:c8:c1:5f:e4:40: + d3:13:e4:66:bf:ad:92:4e:9b:db:c1:be:a3:42:74:da:c3:2c: + 0a:da:3f:94:14:ad:7e:de:81:c6:01:6a:f7:7a:b4:25:51:b0: + ab:cd:b3:3a:77:bf:c3:6b:04:44:30:73:41:ad:93:49:67:ee: + 43:d1:96:8e:36:83:2b:1b:6c:e7:cc:3e:d6:16:b9:88:4a:ab: + 56:c0:76:00:f6:9a:6a:8a:e3:e0:41:75:9d:3b:47:0f:c9:0a: + 8e:9f:9c:00:92:bb:ae:d8:42:56:35:64:eb:59:13:da:2c:63: + 83:c3:ec:68:91:b5:f3:71:85:48:54:c3:9d:a1:c8:63:f3:de: + 5d:a5:34:a9:1e:85:2c:2c:b5:d8:a9:62:8d:26:1f:b2:9e:a7: + 83:4d:df:69:63:b5:b7:e5:dd:e7:3b:18:e5:b3:77:df:c5:47: + b3:f7:8c:e7:5e:87:2e:46:e3:8f:b1:2b:9b:c6:26:2d:1a:28: + 30:13:10:86:5b:46:87:b1:2d:12:ce:b6:fe:1c:4e:44 +-----BEGIN CERTIFICATE----- +MIIJ9DCCBdygAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI5MjVaFw0zNjAzMTEyMzI5MjVaMIG4MQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEbMBkGA1UE +CwwSRG9tYWluIENvbnRyb2xsZXJzMSUwIwYDVQQDDBxhZGRjLmFkZG9tLnNhbWJh +LmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkBFiZjYS1zYW1iYS5leGFtcGxlLmNv +bUBzYW1iYS5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAKbEqb916kyNO/2KD7CitseoH+QOPkHv1hBId3tOTFnhv23HGHuoAafV0iwh +PtAa2lgD6ELxUw6nkbksued6yd5e7UyTa8zdF9DH0fF8PQ1v311TWrEfo3tbQWUM +fOpT37vaQRXaSeO5Lbu1r++MuIR00BgWjlzkwuehh4/jh4sLu5Aw6ODz68BQX7V/ +VJobNEP9vlqAbg9jorN5QkqFyAfHglUjiNROAy/xlb3tFS0+Fs3/x5sDKTamXcka +HomlumaDD5aoB58kuRuPApq4UCmLvmNF+kXDOCOgmDq0a0KZEzZLhO8niTk0efhn +FnucKgNBFWNG5Nsv8j5t/nwgHp8CSKS8FUKm+DiG3Gt8TmejMYGOtjAa6z0IJRlf +Qtw57HkdMAr7Fo89GRTM9a/XxnXPs5aispvZAwGjyogdcu1v0b9XVo65B5u5BBMe +C1oGaytDotzVt/S6066drf3TinwvhzL6iYhYAK4WK5wdWIJN5SHa1Wz3qECLxwLV +NjDvPwmbptIxo78g1KKeJsS0ww8LbADRLBaxKusG2dWYw83LIGitCiyhLydBXJHe +SWLt2DrvaBxt/pTDKGgyYAhlzQKfl5YvD4cnPbkPhWLoK5q09NPXwZOWJyMpiLE5 +mVM6IKqIRDtKJCqL4LSN3WYw36Zut/whQxaePhIgyHowwT2rAgMBAAGjggH3MIIB +8zAJBgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly93d3cuc2FtYmEu +ZXhhbXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMBEG +CWCGSAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBeAwSQYJYIZIAYb4QgENBDwWOkRv +bWFpbiBDb250cm9sbGVyIENlcnRpZmljYXRlIGFkZGMuYWRkb20uc2FtYmEuZXhh +bXBsZS5jb20wHQYDVR0OBBYEFD28cAx01LiFSR0IhMQbJ/KvcjfTMB8GA1UdIwQY +MBaAFKI+Aiqjp005tAhNmcwMdTbqJ8M+MEAGA1UdEQQ5MDeCHGFkZGMuYWRkb20u +c2FtYmEuZXhhbXBsZS5jb22gFwYJKwYBBAGCNxkBoAoECAEjRWeJq83vMDEGA1Ud +EgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0G +CWCGSAGG+EIBBARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMv +Q0Etc2FtYmEuZXhhbXBsZS5jb20tY3JsLmNybDAmBgNVHSUEHzAdBggrBgEFBQcD +AgYIKwYBBQUHAwEGBysGAQUCAwUwDQYJKoZIhvcNAQELBQADggQBAJ6Luwp63MCU +M7wYpeZKH/+OIbGPM/A+i2xyVcRHcV/O5zHvW2IEt1ePqCef7WnS7KgN4nYzjUE6 +Z2FcU2DHU+3XmXIpHa7T7sl2HG0YR+mU3S6XP5mvtfShfJL2TbXBegw4utG2GZqf +4gKE1FQBOHtVhkruPYVIAdo0CWlDJX5uBnPguXy1nE6ctVKFMmJiJTn6AktRLt+O +UhcCUPSZKb9+l1OREoWaaWJFWcRbP68Y5nvkhl3xnlorPhRuftRHJO/ZqOzZpsu4 +TxqG2UMgQRYVX4EN/msxU8H2hEzzA2TS5kQ9emB51zdvM97AqLlu/rJ5rLRTkrgK +WSvMazfEb8ZEAvd8xcamb8Kt3ngeSJbM/lkuU8401ujwVkMwMpBv+Ud2q5lj4+ij +84OY6QUr6vn5nWZwxywAwp5XPjFDUFDI26gtIU5vOcK979hHmScNSLJY8b5Fvf7E +olb8BgLcGTOFU+04WQEWvKrF00s3VIMb5cFL3TRr5dg1hpXmn9IihLHiT6cuTeac +69vfQuG0ZuZY0ygQNJfznGtfBSxHLON16290CuzXHTCAVkQSJvZOX/+S9GICNpxi +6zmYU2holfuUaGm4PGYaznjEz8RvIayopvSraSouAF33ZwaxT5dYiFXYbuulmFA2 +IXA9sKT1OyGzHPWp3cZKwom4WrO8HyHOTGhfmNg5cNJ+oJDfraMT6zyT9rj02adR +sw3q7tRXqtvKfIqgCMOYmjq3uipQkibC4xG6EmAkuVnfYqjXTaPL6kboOfmDFKhc +RHVxa3+ZvWhY2WvRzcdFlZ5EHoU1wDArGKrrL5PVvmZdcO0dBPLBHrXsRQwE9p2I +0wwgXlsj3zSh9eq0oUTA2tXqiei1y9z4ku6sjWHtv3QrKHkf9Jr/Y73mqnkdLCZK +siZTV7qIDusZV8AQoB6BKsBWLsMqgb/BWudIzsFquWxBzESmuHDiVw5tQdZh2r+s +ICynKmcjmAC6zouowkVmpwjrfwq155vW9AfVs0PNJ9T6yUCPr7I2HOdEtE7MWitz +rY/E2Uem+yx9GoAqVbOANG+OFyeTBSFA6Y+/R2pS9S61GNGMHYMEgFX9ISjcfL7I +wV/kQNMT5Ga/rZJOm9vBvqNCdNrDLAraP5QUrX7egcYBavd6tCVRsKvNszp3v8Nr +BEQwc0Gtk0ln7kPRlo42gysbbOfMPtYWuYhKq1bAdgD2mmqK4+BBdZ07Rw/JCo6f +nACSu67YQlY1ZOtZE9osY4PD7GiRtfNxhUhUw52hyGPz3l2lNKkehSwstdipYo0m +H7Kep4NN32ljtbfl3ec7GOWzd9/FR7P3jOdehy5G44+xK5vGJi0aKDATEIZbRoex +LRLOtv4cTkQ= +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/NewCerts/03.pem b/selftest/manage-ca/CA-samba.example.com/NewCerts/03.pem new file mode 100644 index 0000000..7486a63 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/NewCerts/03.pem @@ -0,0 +1,169 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 16 23:29:41 2016 GMT + Not After : Mar 11 23:29:41 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Users, CN=administrator@addom.samba.example.com/emailAddress=administrator@addom.samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:be:91:64:f2:1b:2b:ed:9b:40:bc:0d:46:23:49: + 77:32:74:fe:cb:9a:46:86:33:1e:56:bd:c8:da:dd: + e6:2a:07:34:61:1c:f0:b8:71:29:24:2b:90:f3:43: + 99:6f:69:f6:ff:8d:b9:b7:3f:f3:36:6a:99:90:90: + d6:95:63:4e:88:5a:d7:41:89:7f:73:13:64:49:c7: + de:42:65:08:5d:ca:04:b2:68:3a:40:7f:6a:05:df: + 56:30:2f:ac:1b:8b:0f:c3:15:3c:38:0f:90:50:44: + 00:bb:59:40:f6:d2:e8:5b:73:03:0d:f6:7d:38:5d: + 2f:99:c3:0d:13:0f:74:d0:9e:ef:1e:92:42:c4:46: + 7c:dc:85:7e:e9:af:91:4e:9d:5f:82:af:58:60:18: + a5:ac:91:6e:dd:cf:a7:32:3c:d2:f4:e9:81:be:80: + 9e:0c:ca:1f:1a:be:98:c4:fe:e6:25:c1:89:fe:16: + 0a:30:90:d3:d4:e5:af:89:24:64:12:d0:4f:19:e2: + 1b:86:fb:06:a9:63:d1:47:10:89:dc:2b:52:24:dc: + 66:a9:56:c2:cb:f4:ec:35:12:f4:ad:5e:fc:ff:86: + e9:b1:f9:1f:b3:ce:44:fb:be:04:af:8d:42:9b:56: + a5:02:7f:c5:cf:5f:23:41:1c:69:ee:33:97:7a:81: + 50:8b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Client, S/MIME + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Smart Card Login Certificate for administrator@addom.samba.example.com + X509v3 Subject Key Identifier: + 30:10:6E:1F:7E:52:33:8C:C8:85:E5:92:74:5D:76:7E:E9:33:5B:36 + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + X509v3 Subject Alternative Name: + email:administrator@addom.samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, scardLogin + Signature Algorithm: sha256WithRSAEncryption + 53:3e:51:d2:5d:2c:69:23:5b:dd:05:1a:23:ff:39:5d:54:63: + e5:da:e1:4b:60:8c:09:7c:4e:8e:da:8a:bb:63:5d:bc:2d:a0: + d4:ce:9e:d2:ce:38:d7:32:67:ba:4a:a6:d1:1d:c4:c7:50:e8: + 9a:9e:44:56:1a:9c:f4:8f:b9:8e:39:84:21:db:0f:60:8a:60: + b4:0f:4f:3c:35:a0:d2:37:3d:88:e8:0a:18:a7:a7:2d:19:e3: + aa:d3:8e:18:8f:35:ef:3e:4a:95:c4:d3:9b:f4:cf:89:c2:70: + b9:8c:5c:ef:8a:9e:7a:56:73:13:eb:8b:b7:d9:e1:88:5b:c4: + 62:47:42:45:8d:7b:2d:cf:71:83:1b:48:9d:84:8f:65:66:97: + 61:fc:f6:30:34:e8:88:2a:34:91:48:dc:7a:b7:65:bc:9c:98: + 00:4c:e7:49:fe:4d:a9:56:ea:87:d6:6c:46:39:f2:98:5b:56: + 14:82:f2:9e:b8:ad:fd:89:36:48:87:4e:5c:ef:3f:e0:35:ff: + 72:5f:5b:e1:c2:fd:d9:6e:40:2b:35:ad:50:08:74:94:87:89: + c4:cd:c7:ab:a7:19:4e:ba:f2:1d:83:0f:b0:cf:9c:e6:df:73: + 36:88:cf:42:9c:a3:72:27:0f:f7:bf:5b:cc:6b:e5:20:03:b5: + 4a:1c:f3:7d:ae:92:43:aa:bb:13:07:a4:3a:77:3d:34:01:00: + f1:89:aa:e8:1b:09:7b:b8:b0:e1:54:03:ff:3d:8d:be:35:b9: + 13:b2:59:58:32:48:93:f8:e7:d7:3d:49:70:01:44:e6:2b:21: + b3:75:49:ae:44:7a:50:15:b8:65:f3:c3:48:96:df:c8:d9:2a: + f7:c5:2a:7e:2c:68:77:af:2d:78:1b:fc:1a:d8:f4:8b:a6:86: + 35:d2:f0:87:e9:d6:30:0a:76:65:f8:71:e9:80:0d:1f:16:86: + 89:92:81:34:d9:be:9b:41:25:ec:65:a9:0a:56:b2:03:91:54: + 02:21:97:99:74:61:8c:4a:2e:f4:d0:b1:8b:f1:e6:26:52:bc: + f6:f2:e0:bd:96:66:22:c3:4e:51:2f:c3:c4:65:65:c7:97:b5: + 1b:29:23:7a:c0:7b:fb:49:33:a0:a9:6a:b7:2f:f3:44:6b:5b: + 0c:2c:0d:75:f2:50:d5:82:ba:9a:ab:e0:89:0a:b6:b5:8a:5e: + 1a:67:ab:d9:a7:21:22:75:61:1e:d7:21:36:15:6a:da:a8:39: + 4d:95:50:2b:e6:ac:c4:f6:38:74:c9:c5:ac:ce:2f:b3:c8:d4: + ad:18:a7:93:d4:1a:be:c2:be:9e:39:e6:a7:b1:0e:93:d0:9e: + cf:b0:ac:53:7d:08:1f:9d:a5:98:2b:4e:f6:80:e4:df:ea:43: + a2:f9:64:bf:84:b2:ff:1c:93:36:60:74:08:4e:5b:d6:24:9a: + f8:ac:c7:81:f9:2a:a9:00:28:44:15:6a:31:b9:b5:08:89:c8: + 31:15:1e:8f:9d:2c:d0:e3:a8:32:2c:68:42:41:19:6c:43:8e: + 69:c0:44:01:ba:1c:c4:ea:f4:ff:c8:57:03:ba:df:3f:5e:a5: + 03:da:75:31:2e:07:67:a7:5c:02:55:c3:6f:8f:11:f5:8c:56: + a1:f7:4b:bb:46:d0:e5:ff:68:c1:77:3d:0d:35:12:f5:40:af: + cd:05:5c:53:74:ff:54:e0:c0:c6:10:5c:e8:33:06:0a:50:47: + 7e:71:3a:36:66:aa:f8:de:97:2a:ae:bf:8d:6d:d4:39:c4:fd: + b3:03:1d:a5:9c:47:39:8c:c0:b3:73:f8:3a:d6:34:ac:49:4f: + b3:87:74:11:20:8f:c0:aa:24:a7:30:20:0c:c0:d9:1c:44:ee: + ae:c8:b8:13:63:e5:f8:5e:8f:b0:5a:46:c5:83:3d:41:62:06: + e4:62:a6:0a:40:cc:8e:59:ad:8a:36:4e:20:e6:f2:32:04:6e: + ee:4e:7d:97:88:dc:ea:74:90:c4:ab:a8:b5:bc:6c:81:b1:64: + 77:a6:93:34:44:e4:60:38:b1:0c:2b:29:3a:4a:f7:17:d7:3a: + c8:42:7e:db:4d:5f:09:92:ae:6c:90:e1:7d:9f:96:9c:1a:82: + bd:45:02:76:29:62:e5:b9:14:53:01:53:c0:5a:d5:34:53:7a: + 25:49:3e:3d:db:19:7e:29:57:80:78:67:ea:21:3e:3d:59:36: + e0:8b:da:75:57:9b:c8:9d:a1:18:18:e2:5c:35:35:9e:62:2c: + f5:0f:c0:8f:55:16:a5:d4:9e:cd:0e:78:87:9d:53:d3:01:e1: + 18:61:36:1c:06:c3:3a:43:f3:8a:13:e6:4e:52:32:fd:46:21: + cd:62:18:1f:ae:f5:f2:1a:ea:7a:01:3b:a1:3f:1d:16:00:91: + 5e:94:78:f4:60:33:54:a9:fc:1c:0a:75:f9:17:aa:dd:12:91: + 66:4b:f0:d1:60:25:d4:06:d1:99:9c:c5:64:01:4b:ba:d9:66: + ba:9c:f7:68:75:fd:11:3a:eb:6e:fb:8f:a6:17:8a:cd:bc:1a: + 59:f9:a9:cd:33:db:7d:71:26:7d:c7:be:de:eb:2e:c0:7e:db: + 29:08:0e:82:63:1e:8c:8f:e6:21:1c:b1:49:13:9e:df:78:3b: + 68:01:17:0f:df:97:96:58:32:48:1e:5c:ff:fa:db:90:b5:05: + 84:68:fd:7c:c0:a5:35:d9:75:1e:ea:cc:25:25:3f:6e +-----BEGIN CERTIFICATE----- +MIIJGzCCBQOgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI5NDFaFw0zNjAzMTEyMzI5NDFaMIGzMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEOMAwGA1UE +CwwFVXNlcnMxLjAsBgNVBAMMJWFkbWluaXN0cmF0b3JAYWRkb20uc2FtYmEuZXhh +bXBsZS5jb20xNDAyBgkqhkiG9w0BCQEWJWFkbWluaXN0cmF0b3JAYWRkb20uc2Ft +YmEuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+ +kWTyGyvtm0C8DUYjSXcydP7LmkaGMx5Wvcja3eYqBzRhHPC4cSkkK5DzQ5lvafb/ +jbm3P/M2apmQkNaVY06IWtdBiX9zE2RJx95CZQhdygSyaDpAf2oF31YwL6wbiw/D +FTw4D5BQRAC7WUD20uhbcwMN9n04XS+Zww0TD3TQnu8ekkLERnzchX7pr5FOnV+C +r1hgGKWskW7dz6cyPNL06YG+gJ4Myh8avpjE/uYlwYn+FgowkNPU5a+JJGQS0E8Z +4huG+wapY9FHEIncK1Ik3GapVsLL9Ow1EvStXvz/humx+R+zzkT7vgSvjUKbVqUC +f8XPXyNBHGnuM5d6gVCLAgMBAAGjggIjMIICHzAJBgNVHRMEAjAAME8GA1UdHwRI +MEYwRKBCoECGPmh0dHA6Ly93d3cuc2FtYmEuZXhhbXBsZS5jb20vY3Jscy9DQS1z +YW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMBEGCWCGSAGG+EIBAQQEAwIFoDALBgNV +HQ8EBAMCBeAwVQYJYIZIAYb4QgENBEgWRlNtYXJ0IENhcmQgTG9naW4gQ2VydGlm +aWNhdGUgZm9yIGFkbWluaXN0cmF0b3JAYWRkb20uc2FtYmEuZXhhbXBsZS5jb20w +HQYDVR0OBBYEFDAQbh9+UjOMyIXlknRddn7pM1s2MB8GA1UdIwQYMBaAFKI+Aiqj +p005tAhNmcwMdTbqJ8M+MGcGA1UdEQRgMF6BJWFkbWluaXN0cmF0b3JAYWRkb20u +c2FtYmEuZXhhbXBsZS5jb22gNQYKKwYBBAGCNxQCA6AnDCVhZG1pbmlzdHJhdG9y +QGFkZG9tLnNhbWJhLmV4YW1wbGUuY29tMDEGA1UdEgQqMCiBJmNhLXNhbWJhLmV4 +YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0GCWCGSAGG+EIBBARAFj5odHRw +Oi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMvQ0Etc2FtYmEuZXhhbXBsZS5j +b20tY3JsLmNybDAfBgNVHSUEGDAWBggrBgEFBQcDAgYKKwYBBAGCNxQCAjANBgkq +hkiG9w0BAQsFAAOCBAEAUz5R0l0saSNb3QUaI/85XVRj5drhS2CMCXxOjtqKu2Nd +vC2g1M6e0s441zJnukqm0R3Ex1Domp5EVhqc9I+5jjmEIdsPYIpgtA9PPDWg0jc9 +iOgKGKenLRnjqtOOGI817z5KlcTTm/TPicJwuYxc74qeelZzE+uLt9nhiFvEYkdC +RY17Lc9xgxtInYSPZWaXYfz2MDToiCo0kUjcerdlvJyYAEznSf5NqVbqh9ZsRjny +mFtWFILynrit/Yk2SIdOXO8/4DX/cl9b4cL92W5AKzWtUAh0lIeJxM3Hq6cZTrry +HYMPsM+c5t9zNojPQpyjcicP979bzGvlIAO1Shzzfa6SQ6q7EwekOnc9NAEA8Ymq +6BsJe7iw4VQD/z2NvjW5E7JZWDJIk/jn1z1JcAFE5ishs3VJrkR6UBW4ZfPDSJbf +yNkq98Uqfixod68teBv8Gtj0i6aGNdLwh+nWMAp2Zfhx6YANHxaGiZKBNNm+m0El +7GWpClayA5FUAiGXmXRhjEou9NCxi/HmJlK89vLgvZZmIsNOUS/DxGVlx5e1Gykj +esB7+0kzoKlqty/zRGtbDCwNdfJQ1YK6mqvgiQq2tYpeGmer2achInVhHtchNhVq +2qg5TZVQK+asxPY4dMnFrM4vs8jUrRink9QavsK+njnmp7EOk9Cez7CsU30IH52l +mCtO9oDk3+pDovlkv4Sy/xyTNmB0CE5b1iSa+KzHgfkqqQAoRBVqMbm1CInIMRUe +j50s0OOoMixoQkEZbEOOacBEAbocxOr0/8hXA7rfP16lA9p1MS4HZ6dcAlXDb48R +9YxWofdLu0bQ5f9owXc9DTUS9UCvzQVcU3T/VODAxhBc6DMGClBHfnE6Nmaq+N6X +Kq6/jW3UOcT9swMdpZxHOYzAs3P4OtY0rElPs4d0ESCPwKokpzAgDMDZHETursi4 +E2Pl+F6PsFpGxYM9QWIG5GKmCkDMjlmtijZOIObyMgRu7k59l4jc6nSQxKuotbxs +gbFkd6aTNETkYDixDCspOkr3F9c6yEJ+201fCZKubJDhfZ+WnBqCvUUCdili5bkU +UwFTwFrVNFN6JUk+PdsZfilXgHhn6iE+PVk24IvadVebyJ2hGBjiXDU1nmIs9Q/A +j1UWpdSezQ54h51T0wHhGGE2HAbDOkPzihPmTlIy/UYhzWIYH6718hrqegE7oT8d +FgCRXpR49GAzVKn8HAp1+Req3RKRZkvw0WAl1AbRmZzFZAFLutlmupz3aHX9ETrr +bvuPpheKzbwaWfmpzTPbfXEmfce+3usuwH7bKQgOgmMejI/mIRyxSROe33g7aAEX +D9+XllgySB5c//rbkLUFhGj9fMClNdl1HurMJSU/bg== +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt new file mode 100644 index 0000000..8a0f05e --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt @@ -0,0 +1 @@ +01 diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt.old b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt.old new file mode 100644 index 0000000..4daddb7 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-crlnumber.txt.old @@ -0,0 +1 @@ +00 diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt new file mode 100644 index 0000000..fb3c34a --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt @@ -0,0 +1,4 @@ +V 360311232844Z 00 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Domain Controllers/CN=localdc.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com +V 360311232904Z 01 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Users/CN=administrator@samba.example.com/emailAddress=administrator@samba.example.com +V 360311232925Z 02 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Domain Controllers/CN=addc.addom.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com +V 360311232941Z 03 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Users/CN=administrator@addom.samba.example.com/emailAddress=administrator@addom.samba.example.com diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr new file mode 100644 index 0000000..8f7e63a --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr @@ -0,0 +1 @@ +unique_subject = yes diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr.old b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr.old new file mode 100644 index 0000000..8f7e63a --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.attr.old @@ -0,0 +1 @@ +unique_subject = yes diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.old b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.old new file mode 100644 index 0000000..9b973d4 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-index.txt.old @@ -0,0 +1,3 @@ +V 360311232844Z 00 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Domain Controllers/CN=localdc.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com +V 360311232904Z 01 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Users/CN=administrator@samba.example.com/emailAddress=administrator@samba.example.com +V 360311232925Z 02 unknown /C=US/ST=SambaState/O=SambaSelfTesting/OU=Domain Controllers/CN=addc.addom.samba.example.com/emailAddress=ca-samba.example.com@samba.example.com diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-openssl.cnf b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-openssl.cnf new file mode 100644 index 0000000..17a5571 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-openssl.cnf @@ -0,0 +1,203 @@ +# +# Based on the OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +#CRLDISTPT = [CRL Distribution Point; e.g., http://crl-list.base/w4edom-l4.base.crl] +CRLDISTPT = http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + +# Extra OBJECT IDENTIFIER info: +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used as a login credential +scardLogin=1.3.6.1.4.1.311.20.2.2 +# Used in a smart card login certificate's subject alternative name +msUPN=1.3.6.1.4.1.311.20.2.3 +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used to identify a domain controller +msKDC=1.3.6.1.5.2.3.5 +# Identifies the AD GUID +msADGUID=1.3.6.1.4.1.311.25.1 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = CA-samba.example.com # Where everything is kept +certs = $dir/_none_certs # Where the issued certs are kept +crl_dir = $dir/_none_crl # Where the issued crl are kept +database = $dir/Private/CA-samba.example.com-index.txt # database index file. +unique_subject = yes # Set to 'no' to allow creation of + # several certificates with same subject. +new_certs_dir = $dir/NewCerts # default place for new certs. + +certificate = $dir/Public/CA-samba.example.com-cert.pem # The CA certificate +serial = $dir/Private/CA-samba.example.com-serial.txt # The current serial number +crlnumber = $dir/Private/CA-samba.example.com-crlnumber.txt # the current crl number + # must be commented out to leave a V1 CRL + +#crl = $dir/Public/CA-samba.example.com-crl.pem # The current CRL +crl = $dir/Public/CA-samba.example.com-crl.crl # The current CRL +private_key = $dir/Private/CA-samba.example.com-private-key.pem # The private key +RANDFILE = $dir/Private/CA-samba.example.com.rand # private random number file + +#x509_extensions = # The extensions to add to the cert +x509_extensions = template_x509_extensions + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +crl_extensions = crl_ext + +default_days = 1 # how long to certify for +default_crl_days= 7300 # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = match +stateOrProvinceName = match +localityName = match +organizationName = match +organizationalUnitName = match +commonName = supplied +emailAddress = supplied + +#################################################################### +[ req ] +default_bits = 8192 +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = SambaState + +localityName = Locality Name (eg, city) +localityName_default = SambaCity + +organizationName = Organization Name (eg, company) +organizationName_default = SambaSelfTesting + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = CA Administration + +commonName = Common Name (eg, YOUR name) +commonName_default = CA of samba.example.com +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = ca-samba.example.com@samba.example.com +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +#challengePassword = A challenge password +#challengePassword_min = 4 +#challengePassword_max = 20 +# +#unstructuredName = An optional company name + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +# Extensions for a typical CA +# PKIX recommendation. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. +keyUsage = cRLSign, keyCertSign + +crlDistributionPoints=URI:$CRLDISTPT + +# Some might want this also +nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +subjectAltName=email:copy +# Copy issuer details +issuerAltName=issuer:copy + +[ crl_ext ] +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +[ template_x509_extensions ] + diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-private-key.pem b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-private-key.pem new file mode 100644 index 0000000..930b870 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-private-key.pem @@ -0,0 +1,102 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIISljBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI8gnWGjK+GVYCAggA +MBQGCCqGSIb3DQMHBAjV6Im8e0V05wSCElCDz2WaJB4sMLy3WQI/JoMnq+DDjyNC +7+9th9jeu0Nzcax9NqQ2pKWav2eIwhjS61AM7Zw4+SIqV6mJmuv1IVohHgxAx+nN +1Poq6bAbgbxk0uwS4nSYXQWOA6xhmjLuZcQcl8bZ6c50Vvc1GLkKiJ7T2x0xr2qt +pkw86WzbBtrUDbg5IHR3AsgTpyg1Lhs/E1ZCJ3Kd5qXpJwoejvjMCeCqroEzEfo0 +TzIRQS3R/hbnsAzwP03p4HyNs7rY8qGY0K+xv6fTHHiiw+0KbJK0w8KLi7ru0pp8 +YPTTSWBLd96ws0nlhY0aVQzDhlbXSXtqMSQNgZYln7CcH2R8dycwcjDhX0JsPAql +tIzvkl2goYU7jNI5QnpGPA9VH2U2ipMaEhiaY4yfDolnRaueo3YdmigFz7I4Tanx +kB3BaF0WrUkIk9oXXH2yIbRm6UAgYhGvNkTcifu6Iv+xfxn2JPulNGWcsJlVsRof +Hrdy3ZzcDp3bYDoA7gVWQgQKoz3ngIhrgH98zSiNCpKvjWXYx+oWYKHtxVFtFwij +Pc6+AUdTTjVfQsfNBkE9B2sjmvif6lnKWaMS349zodVCjWQrjsUITJV9Hbqv/8lw +GrCTFS4R1Wt+ABQDZXZDj4qXQ3Y8NhNI4Z/rkGN9rdaNJuDoyDYzm0tGvoRBP2uV +GJrAWKt6amx0oSI18L1cqm2hoY7wiZSYFqdXbZm5fbhoELfeak0tMPkHEXx1HtCu +cVQjcbHTakHcc1cW5TFRlmWZwar4RC//6YO5PENhMacPuW1ld0qF5AbwH303Gw1/ +k4+sYBe0IxiFQWnIFyfCoZI9swTojuUU/p+wxHjwCoxLoiYDN8EOCkHvgcgu7ddQ +WVHpWyhcNeKcYH71PvyPXjJufbaBouMHrGAodAQXYuRZCwpXvfRG6rqs3yPYkFYn +dBRdUKDIj2KBLg5n2ssy7ENpRcygUwfgK4H7Qn1yHmDMuq9VjgWNSn1ufCQa+M2L +CAOMrzX6uRuzw04K2vvv9xhC/Vrr+ISbOL9CDJyvyD4Xzk09JXV9CL8zTDzlJf6s +DnGhd4F/ejKn8MiOTOYuKugqoFDIw0D3WtbiAHYkXyB1Q13JXjc+N5E74xtGPVUW +IezrC9yEnQWrrtCBFbAtAKehphfZrvseAB4tBSyToio9wXBVKupa/ghoKEuBIQtE +OAsBY5Vd8JwZyaLFLBzkPfDqZE6mNSQuSm/x4HjciToQBYicNoGApRH0qneHXdUU +YUA5QeRp/HRL+yawNPq47HgvmbJh1cpyOsBOGjwqo0Tf0Q6WcqhrZmceHJbpxFeR +ySDEsuqdSp0prk5CCJ6HO3gsrE6DFLmLNNkZACycIndKO/I98ORY4dmR+zGUoMTS +Y5Gqpxhuh2LleiquFv3c/mrXVRA4Vl6F43H8isv+7/avhoSkBdoVi17wCR3pdk9F +naPHRqv6O+VT82S8BqYLR0xk3or+0wzFuaGkh6zPjlYr+DGrTr9qSW34+hJAUsSh +pcmePlS4A08sM2aZ/z4NSBzGrtSAI0KaeZOZMEyHL7MwZGHvQYz4WbekZJMZR33L +51ia/VkA2rMw6fgV/HYA3Zwd3NSTQ9jvwP8oAYmjrIbkApQTZQdbGQIh+8kcA4QE +3seLJAQQ3/reJvkc4jzwbF+A6K53iu23s/FhP89fK93xz+2zxt4bfMb0RQYWSb4u +aMsTHMC+Aenx93KrVYHvBi/O3PRxPUZQaPPQ+GQVerpmqhnrAtPh8xMjtxRpF3mI +Hff9RJTCi9jAQWDYAuuWNo1nFi4q6tQU8vCX2T5o+AsvwIrRDxz9E3ELqwPD1Zl8 +YRSBVgQPpy9xS/eHCgBOa7Lch2/gmew0pE6JgHmGSAZbZGVa7QxIsWvrgvNwuDmQ +pV9xVWttK5dup1un9Z9fiuozO+Iu6a8x0ECCxsUEO2C9bh+Qt1EzjirVy+1WWnKc +fW2XrFHwQMqIMTjM8JOuWgL2R+YjhFFge0h8CGiXk4f6mnuuGfHhP858Mmxuw0rZ +bdwwyBq1eiXPrkxm88yo8FYmLXCQExlyFsLbFZ+kJVhZbxeP9siedP14Tgqy2FC0 +2A+tcmypVLu5Vthu66I3wUvmgi9hucwe/s8qCRQwYciN1wzHH6f+uDz//kQIgA75 +AuNAHJYV3uWCKUESpnDL/9W2O6FvWY/j24QG0AkXsl+peovo8CucGUZxphLfsua6 +4x2WrTLehObG+G54CHdOLTrFQDIDRL9Kvmrw8/TGkXEles+WNnB8HxiUQKokA3ld +fhXy+e/yjaGzwoNY84CV1WXowWJ2vA1Z9gdr1mFpl2uJm1s+RRquuyRI/yXBvGQ4 +x0pPSe8vbQ2OlCzuVMjFpG4dx4oqBwXUR69YigpsVi1A3n23qAPUSjJBflgPLWdG +x/T+NiQ9TVhFKHqkgiL7e5s5VWaYREXjfDeiVowst/7vJdX3RugJTlVfnmPJ/pJZ +JnObpWxm7jmJu72fek0bmNaOMvMf4YVB5G/z2gQ0bpwSbl91kxJvTJ6DG9Kb10h9 +ekfffdFdiZHD5V7BUibmt3aYAZSPRG3Scurrv/kKzkH1/cEMnMDb2ppxsfT+LrLu +92P/7sCxqGJtk6JNiV9MhY3c9gBHsWTIbcJG/wZHzXhwZphoPyFf21I3x11jzQ86 +D3WTC4UQ8ez+PgMvl1ifP0wC0e7ANs8GsDZg9GEI+tBxx4GsAP1dcpr8c+v/wEDF +/a2fXqtymxWUDc4qCcrE5Az/U7k4tMSIvOiH/QVBsYOybcuvHd4E+Yrx7bXapk0V +KIgFQm8kVftR32h7KDx55Vcv5a11dEp4TUF1k1MH36GVxMzfqQnnTnwDs67Q2FCs +YAGt9jF0imAU3KZUwHbJvPYpjNEV9g3pkd4shyB7ZqNXjOFG+rU7F6xOVcf33lBu +yP653eMJjLR7hKrQ1UiWhgosc9zSUhl+Er6EqV0OoNtXzDI0uHsCzJ4BuLeKzOga +wXS8JjzHR9Qb+Nf0OljkNgmfCUBk7BDGuvt6ZQwP4pift9+YKJQ9dTLz0QZxeEoA +Ky9BOkhF4Q9cYACZiSnZGWq5Y+5I+zIPr1LxGfu8gOqhkvne5wAHmC97YbSXaHXI +rHvFhAzbwdsX2Crgvgd+feIP3LU5T7YhGW3nZMbigaDsBOTUQQW0f8tXygc1QjzT +dV/mbpoIDz/39PIYKC0BlQQ2S3clfr8SoRWR0bKEypPd7CZXAH4zAdPjKJih3yV/ +SqWxvMKuZFpSu3BJTcrXvN7nvKBzW17VGI0eSE9+SwrsMHZVUjXUolarSYczdC6v +QKkNV7+Uu04GCNivnE6sYs3M0n5ZSvvBha1/8kUDIi1k6QhvtEauA3WuoMp8/iU2 +mlvT5Kev96glUo1SdCQRLZFh1HXtvKgYiqEZ8FVW3kHMrvDF3Nxh4XDGvuQ6nO8O +w8TfE56kZVot8KTcYkOBDiyVX/qGLYNNvW2WHm+zygHKVQRkxnL5Y1/GOU10Wr2i +7ynFFYyjHwj5vkKsqLytQmuIxig2L8eW2WSx74WyWJPLbeHUSVweHjO9DTh9TgUZ +QEqPRuhTJMXq6VYpMWq9CUYAF/nal1vTab3Q7BbKcDFma89d4m+yv6FTnOnswS5q +r22NvQwl+09grdVYaL14a+BtkkCYH+SL30B54Vws5W7JS+34OSkMzDZtwwuGUqC3 +P61oG3jsGyJt6knWTgnp83GHKo1jsrP6IooatP4BaPf7PmKcftPuzies10G7MGHm +h7gAAYVrAW9lDvKKYc7UC/rgf4kJpkqcM6d3eU+9+ccVfmCIbHN4dEE/+VGKMHAA +qKQS9j5dyoCZH14PXAotyHCmvst08pkKG9Oj7VPG/+rX6tBD3y1LOlMbMKet9Owy +WA0yTBYXHxr22zcJD6k/7AgkBKbdkJPMR+X9IyINQojpvXJZIKZkVhoSCa4d9DYF +2xLKo3W3Mqoi3U7sQ42mQsdaozlql+CBYqd3wq1bkGyyqZ4zgm+D9VI+mZ6hZGt/ +77Qlp2j8JeCdsPDy+igzCpz6fkVaQum5fZlg1II5uYR+4EOvn33LbCT+kcqp+YC8 +m32umo2Eg1In2xgfqCpPTEDIjLSxgvC+NtJ/CmGVo6gYebyFLXZlnDbzAhxaOIDO +p59Tm9K3+wL31FnQOlXtkO9VihN9k5W1qR/MjPH3LaWCFSgMjed3LlOPEFBYmzeV +oz1oBZcJGVA0aEMA/Oh8hqMjVjz3vaIQfCuJ6eTLob7RDfmnhVaCPHMT9sJDCqKU +j4r1P0SRj+SRt+tO3kPD3dz8ejXRUb/lTLTSx3fQK0sB7XWu/LJpP3jGgoES6W/t +Fj6Eai8LXjqr+1rMnc0NKCLlWZakYp8snikOI5b/+t4WsOwhKVFiMbMdtkf5u7J8 +yKLPpkUS/YBxk4Uhv7srkITCzGpE9keV9umQImwPKAtb25DcAXPp5IXuJViHtu6Y +rKYYlmWgjobgCDvP7NFGKv+7hszZpWmSg/AS13QtPUZ9Fn9mM/Af8Swu5pp2HGUp +Zme8CjltYjtAk5ChNL+9C5AlVEZoD0x1ag16Gp09ODzEjQ0JebojJuw1X4+q3syD +BodCMFhwiO2nsnHrr5PALdoAy4YYmQop31HwjhsDShCuSc+8kWnvWRlzyVSI8/vV +jD8TV68QBeKyU8PDhC2Bmogy/xVYAJthgfK9LYD619Xz8+0h0cTFSwK/WAO4C38l +WV9SASyAj0O+JMUWheq/Qh4gP2NRDL2fyMFpf8uflwTjmg3Mu39oqcI3SQYk6ViI +Mq+ClfbU1hYZrakAN8pt8HUM1XbXJRDXnE3hmrTiU+jdNucuunHDjkf9ZaRNgBWW +yV309Ua9O91EEG0iGjkQ9Sy3ChscBolfvMpayzGtQRFDYWDX6UZnV5zI4ir21ikQ +A04zphPlCdOWelU8Qs8GuYX8HeXCzc1hUKffARtY2DQqiQ6lmh4YXHM0ILK/kDYo +ftmcBWpAZEntVRlnrCbPz29cwltn6DHQC6HWKGQyRxafp8fINUOINNMui+W4UR5f +tNn9IederuOpDvgYDMAzEt59BT8QgRggJl+hlXjRxOXANLTOHWqWKejk8+LAAH3+ +DjBFTX84cfrbbLgrK57E9afEN84KM2EJCCGFXYvc5qBPgrS9oYQwIErvpy89k8fW +bR7pU41CrHYZG2am774H80FCfofzzAFoJ2pZdPF2Lo95cLxNENy8RjYfePJR2tcf +vlqNynUvBjabCW6XhtmRK8/fsakfqfaQkZfpHqtA+qAweLh1bcirz3rBeNvwsO3G +JBxUgNkMel2F78Lg/EfMQL/hxeajDV+LilJkeZeRbHNL18M8dzzJaZkBm2oGylc5 +AS5r4r1EvSINjf1uXDA9CMBNydf6n62VPnDKrk1WK2R+pzFeeVvRayx7PVWacP3N +JnKPY+t2eIq5JlNCfIHcL8MDHaau4ck/f2lnUJm1OfqhdfAf6wsf+XuEhfkzqsV/ +gRjrumWsuMs7B15eIZNoyP+x9XPfTXvKXtNpWaUbq2iC/rxgMzqzDN0XvHSr8eTL +I5sg9nlAiezZYcDsGcjpK5EUY3/3zmZtO+OvXg2kA0dQx8QWg51B8MI/f9EprAAp +O4ypSjvH+Hthnq4Cr1dXtJzOJru3wz0N37Hy/EhMrDYP3XJUjkYJqTrxM8dsT7TD +RwvRjbJaZYi1mmIakXbHAhEAcIg/Z7hueIYHrOzYaW6akPdxy0yS252mZ83KtUC9 +oxNzYQdMi43bxbWgcTu5RxGPZ99IYUdKziBJiJlOpWFSzPwKcD0bkHeDAbWZ4Aex +msyzLubI3nPnuszVWgG8cUP1w1HbCC5KAWIOSoRYS6SzcirAZAXuqvoBGGSCiKdJ +kMIXRjSHgTfNPE0zSkuoYognqtPBQB+tCmEYUwmIidzp7iVe3muLJj1qHRcUNx1g +XzbpRMOGRUSgMJJlcba5BRNmFnSEjgnFx+v/NEiMhjacOiDDypi58eYPvgLZ0v8I +UlI0napiKxX1XS9XZE7SI8xXn5zte2de36xAfZTm1gMEYG/sOUndKUUrmsG4ag+u +ttyW6veD/LMXzYX/vP6zBe8l2RkZp15xMPMSTovij4ELLOAsWmAB8MAQ7p2TThOa +gmFx0AnWZ55GAXcM6/2dK54ZQjm12KgRz2uZD6RpHgxDlErzHBVY8VFWPHx4b60M ++BVqk94uAsprvWczcuowZwF41MsJ7wm3a1Jtd104mx1/0GokF6EG+NjpSFvHiDN8 +JVlZ24lBIBv/7Q== +-----END ENCRYPTED PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt new file mode 100644 index 0000000..6496923 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt @@ -0,0 +1 @@ +04 diff --git a/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt.old b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt.old new file mode 100644 index 0000000..75016ea --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Private/CA-samba.example.com-serial.txt.old @@ -0,0 +1 @@ +03 diff --git a/selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-cert.pem b/selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-cert.pem new file mode 100644 index 0000000..d6a1577 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-cert.pem @@ -0,0 +1,62 @@ +-----BEGIN CERTIFICATE----- +MIILPDCCBySgAwIBAgIJAM6BrnFPnFmXMA0GCSqGSIb3DQEBCwUAMIHGMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKU2FtYmFTdGF0ZTESMBAGA1UEBwwJU2FtYmFDaXR5 +MRkwFwYDVQQKDBBTYW1iYVNlbGZUZXN0aW5nMRowGAYDVQQLDBFDQSBBZG1pbmlz +dHJhdGlvbjEgMB4GA1UEAwwXQ0Egb2Ygc2FtYmEuZXhhbXBsZS5jb20xNTAzBgkq +hkiG9w0BCQEWJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29t +MB4XDTE2MDMxNjIzMjgzMVoXDTM2MDMxMTIzMjgzMVowgcYxCzAJBgNVBAYTAlVT +MRMwEQYDVQQIDApTYW1iYVN0YXRlMRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNV +BAoMEFNhbWJhU2VsZlRlc3RpbmcxGjAYBgNVBAsMEUNBIEFkbWluaXN0cmF0aW9u +MSAwHgYDVQQDDBdDQSBvZiBzYW1iYS5leGFtcGxlLmNvbTE1MDMGCSqGSIb3DQEJ +ARYmY2Etc2FtYmEuZXhhbXBsZS5jb21Ac2FtYmEuZXhhbXBsZS5jb20wggQiMA0G +CSqGSIb3DQEBAQUAA4IEDwAwggQKAoIEAQC3qPlXMRW0bS5QonEW4MMRiZlgWRc3 +DLtA1hSg0a0POKXIBTTb26kVWwJkdLdLPf9POdAWa+PtEDcgiTKeNeh3hdCaKQiR +LGtmR2Ncy5jcLyAaJPHL3ZrYCzKPyfhVLtZqrS+5CmJRs1Ar1zEpRPIcT0Qdb6Jp +gu43msIQnULTZPatF4Oi847jb/JIXnTYxto7cuk1I/2VFJ8OD2cYypNbCkthwAga +ftJ0GNsM2Ii0q5aFnrHpCh/UhvQ1XGZfGVgBRrFjQQ75GlSCFXuwLLiyXwpj6c/p +QPTQuWLe+21rnizpxmXBvP6d2LaX2Vsq/XP9iVN/jVigY4swgk61Z6XFkmsVJErB ++JEOrjdcO0kkkqlSY0aqqpoXgtV8lNxTeKrNllRmW/i/Wz174PPdvR6QQFMG0X/W +NOtqwBGZqiafHlu1xrtC/RnzC2S3ygKssP9463bO8IDvhv2I3QnbsuQdKhQSE5rr +VDJcSI1DHe+tGsko4QA2RBFvgO8+877K9qnBXpnVdYrnEk4UlZVk8L7TIngbA7RR +bZ7j1mE28PIzcGN2ps1IY80CbO6V+60YegT2F7smjRAS9YJyfqM0fs4yoRuT5Day +BHN9asy//gEVfebXytzfvZvh0Y+XTlxsXbZ24IsaW1IhsLNvny9BX2Ygrv5wnf7i +zvEGf4rnO4v+d4mn2HrkkYLfIJe/iQAY3c8uABbEZgzrTHqC+oyRE4MQUtjQR+10 +8IOvbVeU716Q3SxyiGlq0Dici84J2izArVuZBGVoS2pytwbNFU7eL5SeirL1Xy/E +3siV+y6Oxr3sigrAmMQbzr0YQT7yDjVaP61ct8krc5N4Z95SciIlvmEIzKkV8kql +Uiom+XWP8aRnZmiuvfGnvEyB67MmggEkG1LGIhsp+ZsnTfo4nU716Djlq5pOZHY2 +VTiOLET7Omo/a+RmHwrog4hRm2BYifyt3RGmzoWF77klbow13ov0UrsTF7Sw6Uft +EnaklsZU9cfFyNLsDjEwRTWQ4QMdq3dI6WSOYN9EWFtxLGY8FypH2QkTOOPsqgXY +/SxZUBqa3r+MrGRJ2NCF6kr1/yanLicVzNSR4tymEFDfF2FJVOtQqbO370JGIrJE +3kq89zUUMH9xNP6IJu+N11Xe63028KlJomWq6my8AUk7a0sk8z75FIa5PvUSYhQ8 +gbTYXM2AyYLTYxkLt+OzLLyvQI1l6KX3PWLaa94lqxkjGQWIt/ViL1OTineiTbYJ +YR2SB4R3S3Y6N3AAT6l7D1/lxThrqzmWAAkbElBTZZrXGybjL3I9q8lzVt98X9HY +LrVClydpw42drOIX5PQ68+s8lYNBA1/uYim3IgTjDPIqsNIkBOjreYnPAgMBAAGj +ggEpMIIBJTAdBgNVHQ4EFgQUoj4CKqOnTTm0CE2ZzAx1Nuonwz4wHwYDVR0jBBgw +FoAUoj4CKqOnTTm0CE2ZzAx1Nuonwz4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMC +AQYwTwYDVR0fBEgwRjBEoEKgQIY+aHR0cDovL3d3dy5zYW1iYS5leGFtcGxlLmNv +bS9jcmxzL0NBLXNhbWJhLmV4YW1wbGUuY29tLWNybC5jcmwwEQYJYIZIAYb4QgEB +BAQDAgEGMDEGA1UdEQQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4 +YW1wbGUuY29tMDEGA1UdEgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJh +LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IEAQCa8zKgFnArq4GM+OJfiK95 +fYuTgbO+PaH19GWCyNkNCrtasxt6BIdxKYW+rC6VxXBRXSvaPLbiRCDhD9hL03IR +daQ+R9JanYzoloN7m5q+mSdJpfsIfdlvqKr4hyti6sfC3jnQC1Tp696KrW1P1Ymi +kOOxksmngZzTYr2q+JhydYsNAdpxeAIAILDZI0F4VzOVPXRy2+Gop+lwWYvtRjjn +Z8HemYJ8jIGUlldMVInd5+XmS4/+kFLB6Ly+JAoqC9PBUfWiwXIFIPOIM5ia4sNH +ZeViTG5Kw7MO/esPs7J8VKB6La4v+CYCT4ngT0ekRLXhRi/Dwa8Ok+hFmRtrikvU +TEqZPOQT3sRqGdlongAZ1kmCkU4n4RhwbMh6WitDKJf7YToMsyrm6LQvGo4Bf1Ns +mqnY93OSTyOblNGYwq45BMQbGhW21uW93SQg938ojuw4366KeGnHCD3zvyfWh6Yh +duAWNQb8TNDqhik0lLNVMyrEPpk0f24XrVC2LBia3Z4hQvep/pI8tg1656XbI6/J +GubM9KW6o0ndZLnMzFFga3JqztzL/Ooqu+yVaA9q89GlN2zv3hafXaC/AChG1b8k +Esx37mA68jVaTh/1hX8T2hz14EV3LUB2N21W228HuUhZ33PEcR10XMJNJsOOwHUn +5I902kznpUs3VTVvbWBsEfhZAD9uns07Z5b0b8UN3fZyNmXeE7gObt10obSFzoPt +yhnTCULNJ0K3cwuQDAC4Y6HQK5hvLBazdvnYT5rZqGneG9ALdQqr9if2gZFeUPQv +a63VZFwfyx5wQlFwLVbaH3tTl1dweJkZYjUC3BL1rngHNNvD1t//ERXqL2ngOe4C +1xNNOBAC2Q4upBYAuH+zoT8KMRCxEh22SPNGrlmN+9MwY+ceP1Dxa97vY9FtSMIB +dYEvoI8TyFhAjC6t4HOUxT4lvpc7Hma+1AlG5x/aSCY2A9ONdLLo5DyXSuLFHgtc +gh0dJygZ85sd90k8hl+73muHHofG6HuzMNaQhN8sFoaiedhIHa5+Lv6FVyd7Y0dy +QVHiPVcf5KG3o0y6OnXdfsGNUsak01fqQhIewVghdTU9liGW8PH1UVWO310q1K46 +U46Hp/JBamvvW5B2ZSg8Dj4arS7/TxxNqbIPAtNxtN7Hwg1dubGWMatCv2A8Cx29 +oWIeUG2HKY4XvbdOnpWvCGx+sUqBiK6Sf5zvJF+UigmZPKrZgbrFWSC1tf0RYn9d +IyH4JGo4uP5OCxBWFvtj2d51qJJvdnlegKkPd9E0vzIZRHJsSoAx54MmqRZQkPzV +56iQXA4iTfhv2sF7Uer379OV//ML5xIjsV+IkJepTUtAgimqkKKRktCPfFT6mOtw +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-crl.pem b/selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-crl.pem new file mode 100644 index 0000000..73b10cb --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Public/CA-samba.example.com-crl.pem @@ -0,0 +1,32 @@ +-----BEGIN X509 CRL----- +MIIFdTCCAV0CAQEwDQYJKoZIhvcNAQELBQAwgcYxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApTYW1iYVN0YXRlMRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNVBAoMEFNh +bWJhU2VsZlRlc3RpbmcxGjAYBgNVBAsMEUNBIEFkbWluaXN0cmF0aW9uMSAwHgYD +VQQDDBdDQSBvZiBzYW1iYS5leGFtcGxlLmNvbTE1MDMGCSqGSIb3DQEJARYmY2Et +c2FtYmEuZXhhbXBsZS5jb21Ac2FtYmEuZXhhbXBsZS5jb20XDTE2MDMxNjIzMjgz +NFoXDTM2MDMxMTIzMjgzNFqgYjBgMDEGA1UdEgQqMCiBJmNhLXNhbWJhLmV4YW1w +bGUuY29tQHNhbWJhLmV4YW1wbGUuY29tMB8GA1UdIwQYMBaAFKI+Aiqjp005tAhN +mcwMdTbqJ8M+MAoGA1UdFAQDAgEAMA0GCSqGSIb3DQEBCwUAA4IEAQA13bwPRi4+ +CaG7MSTVA4Z4JZIU1CQagBJCah0XPXl+xIs/aWCxS3jdFnCUNLOxrKk5Onrsv0z7 +YWQJHsH2Lu0I38SPyWhftmhrqn74QQyfbGMGblDufbfJsHNyeME2z0ZtCoHUgaz2 +kMatR7ys6uvOY4Moghr/xNK2QYSzCFsetF/5ua2h547GK+VMqb4wH14WIx0ljVO0 +knpqT+uX5b+3KX2QcUFDIzRJZWBj0gDWzNxL5PSbZbcxtpUpUIgbFHD8HGRAu3R3 +MCJE3mKuKyaRKqLaF/qOWnskkHnIV3gObeKIgWFNLiyQKUAvu0m3QO7b5zqUeOep +JMy/3dwixIoDU5QU1O7TAvJQhVscjt0baQaklqlI7jKwdd1xk6brIXKqLa55ALd2 +RIs7I01X/ZyukrY+NbvQOGh/Weqnxe2IM91DkVQGYNxaa52Fqlrop3U4qdZRgtuL +Ye8RP3IPcVEoH/t/fW6IBTEN1uG9vVvyUUW2H4lI44yeNt2Pd+6qXXFyKZ9pfctx +7zCOdo9/ikSzCddLFKL6bgJ4vxNuSt+4csq79BytK+69SrsGP/R87154uqA8nMPm +TXpFhL3YBqOklphc1JVCccTp/824vkrgrEOSB7uIZOtdTpTuRabo6R5yv2pjC5GR +om3sI8c7xKeUUsfxDF2jt4vJHlKgYEx8YgbAdKq3As0fkpsY0IcMSNR1KMq8H4ia +0eNWy1YmkvcZzZTL1GBtL1XNPHkvmuBHV2rglBg7PAklr/9WX7IM6AZh2WKP0Spe +ih1C7YlVzCgQgOaGEe28jegtgkr3I84j34GJmK5WO5fa7/au8wzUDEyGTJE1wZxv +k1s4TKiNuCSiH26qVUKfwpzrqhiW/ElAeKsXxjg/V7anhPbQsd+sz4RNFi9RldlY +tdXkPmKBTvupJkVa3ZUxl8gyXNW8t8bSpW2kYFOorxnEkvhwIxMhwSC9pyEyNFXa +sxsMZ/BcvFBcJYORhxMYVNksCriyWRuYsNORC8s9wnygbQ2n3TuoloZ9rR8mc6XK +3EgLwhOyENWToRurBdN7Vq6BuNtnl5P/Rd2WBTy62EcXkrnJCCUK4ouP3o0MRt/V +LdQiCVf9nnHdkiWMQMH4pkgrEJb70IvS/MAAee3SFuMNa72zgD9Pgk4NX6upqt8s +3+wo0gqmg1gJ9RQUyk/TuYMgdBVg68B6G1C8RifxffhZMj/rOm1xdXXwRfmDyrHZ +aaNZv3VHTEIJjSCHMkDV7SD9d36gdX0F1lLP5HIu0QTWJeyE/fFTD+hQMY5Ryk+c +nzW2ZYuTp14xWD3NTQzq/NS+BPpOcAtL3hSpyvP4UkIFGZc7OUPPBBwR2xTVLQfZ +YqKrAHJKgPXZ +-----END X509 CRL----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-cert.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-cert.pem new file mode 100644 index 0000000..7486a63 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-cert.pem @@ -0,0 +1,169 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 16 23:29:41 2016 GMT + Not After : Mar 11 23:29:41 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Users, CN=administrator@addom.samba.example.com/emailAddress=administrator@addom.samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:be:91:64:f2:1b:2b:ed:9b:40:bc:0d:46:23:49: + 77:32:74:fe:cb:9a:46:86:33:1e:56:bd:c8:da:dd: + e6:2a:07:34:61:1c:f0:b8:71:29:24:2b:90:f3:43: + 99:6f:69:f6:ff:8d:b9:b7:3f:f3:36:6a:99:90:90: + d6:95:63:4e:88:5a:d7:41:89:7f:73:13:64:49:c7: + de:42:65:08:5d:ca:04:b2:68:3a:40:7f:6a:05:df: + 56:30:2f:ac:1b:8b:0f:c3:15:3c:38:0f:90:50:44: + 00:bb:59:40:f6:d2:e8:5b:73:03:0d:f6:7d:38:5d: + 2f:99:c3:0d:13:0f:74:d0:9e:ef:1e:92:42:c4:46: + 7c:dc:85:7e:e9:af:91:4e:9d:5f:82:af:58:60:18: + a5:ac:91:6e:dd:cf:a7:32:3c:d2:f4:e9:81:be:80: + 9e:0c:ca:1f:1a:be:98:c4:fe:e6:25:c1:89:fe:16: + 0a:30:90:d3:d4:e5:af:89:24:64:12:d0:4f:19:e2: + 1b:86:fb:06:a9:63:d1:47:10:89:dc:2b:52:24:dc: + 66:a9:56:c2:cb:f4:ec:35:12:f4:ad:5e:fc:ff:86: + e9:b1:f9:1f:b3:ce:44:fb:be:04:af:8d:42:9b:56: + a5:02:7f:c5:cf:5f:23:41:1c:69:ee:33:97:7a:81: + 50:8b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Client, S/MIME + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Smart Card Login Certificate for administrator@addom.samba.example.com + X509v3 Subject Key Identifier: + 30:10:6E:1F:7E:52:33:8C:C8:85:E5:92:74:5D:76:7E:E9:33:5B:36 + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + X509v3 Subject Alternative Name: + email:administrator@addom.samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, scardLogin + Signature Algorithm: sha256WithRSAEncryption + 53:3e:51:d2:5d:2c:69:23:5b:dd:05:1a:23:ff:39:5d:54:63: + e5:da:e1:4b:60:8c:09:7c:4e:8e:da:8a:bb:63:5d:bc:2d:a0: + d4:ce:9e:d2:ce:38:d7:32:67:ba:4a:a6:d1:1d:c4:c7:50:e8: + 9a:9e:44:56:1a:9c:f4:8f:b9:8e:39:84:21:db:0f:60:8a:60: + b4:0f:4f:3c:35:a0:d2:37:3d:88:e8:0a:18:a7:a7:2d:19:e3: + aa:d3:8e:18:8f:35:ef:3e:4a:95:c4:d3:9b:f4:cf:89:c2:70: + b9:8c:5c:ef:8a:9e:7a:56:73:13:eb:8b:b7:d9:e1:88:5b:c4: + 62:47:42:45:8d:7b:2d:cf:71:83:1b:48:9d:84:8f:65:66:97: + 61:fc:f6:30:34:e8:88:2a:34:91:48:dc:7a:b7:65:bc:9c:98: + 00:4c:e7:49:fe:4d:a9:56:ea:87:d6:6c:46:39:f2:98:5b:56: + 14:82:f2:9e:b8:ad:fd:89:36:48:87:4e:5c:ef:3f:e0:35:ff: + 72:5f:5b:e1:c2:fd:d9:6e:40:2b:35:ad:50:08:74:94:87:89: + c4:cd:c7:ab:a7:19:4e:ba:f2:1d:83:0f:b0:cf:9c:e6:df:73: + 36:88:cf:42:9c:a3:72:27:0f:f7:bf:5b:cc:6b:e5:20:03:b5: + 4a:1c:f3:7d:ae:92:43:aa:bb:13:07:a4:3a:77:3d:34:01:00: + f1:89:aa:e8:1b:09:7b:b8:b0:e1:54:03:ff:3d:8d:be:35:b9: + 13:b2:59:58:32:48:93:f8:e7:d7:3d:49:70:01:44:e6:2b:21: + b3:75:49:ae:44:7a:50:15:b8:65:f3:c3:48:96:df:c8:d9:2a: + f7:c5:2a:7e:2c:68:77:af:2d:78:1b:fc:1a:d8:f4:8b:a6:86: + 35:d2:f0:87:e9:d6:30:0a:76:65:f8:71:e9:80:0d:1f:16:86: + 89:92:81:34:d9:be:9b:41:25:ec:65:a9:0a:56:b2:03:91:54: + 02:21:97:99:74:61:8c:4a:2e:f4:d0:b1:8b:f1:e6:26:52:bc: + f6:f2:e0:bd:96:66:22:c3:4e:51:2f:c3:c4:65:65:c7:97:b5: + 1b:29:23:7a:c0:7b:fb:49:33:a0:a9:6a:b7:2f:f3:44:6b:5b: + 0c:2c:0d:75:f2:50:d5:82:ba:9a:ab:e0:89:0a:b6:b5:8a:5e: + 1a:67:ab:d9:a7:21:22:75:61:1e:d7:21:36:15:6a:da:a8:39: + 4d:95:50:2b:e6:ac:c4:f6:38:74:c9:c5:ac:ce:2f:b3:c8:d4: + ad:18:a7:93:d4:1a:be:c2:be:9e:39:e6:a7:b1:0e:93:d0:9e: + cf:b0:ac:53:7d:08:1f:9d:a5:98:2b:4e:f6:80:e4:df:ea:43: + a2:f9:64:bf:84:b2:ff:1c:93:36:60:74:08:4e:5b:d6:24:9a: + f8:ac:c7:81:f9:2a:a9:00:28:44:15:6a:31:b9:b5:08:89:c8: + 31:15:1e:8f:9d:2c:d0:e3:a8:32:2c:68:42:41:19:6c:43:8e: + 69:c0:44:01:ba:1c:c4:ea:f4:ff:c8:57:03:ba:df:3f:5e:a5: + 03:da:75:31:2e:07:67:a7:5c:02:55:c3:6f:8f:11:f5:8c:56: + a1:f7:4b:bb:46:d0:e5:ff:68:c1:77:3d:0d:35:12:f5:40:af: + cd:05:5c:53:74:ff:54:e0:c0:c6:10:5c:e8:33:06:0a:50:47: + 7e:71:3a:36:66:aa:f8:de:97:2a:ae:bf:8d:6d:d4:39:c4:fd: + b3:03:1d:a5:9c:47:39:8c:c0:b3:73:f8:3a:d6:34:ac:49:4f: + b3:87:74:11:20:8f:c0:aa:24:a7:30:20:0c:c0:d9:1c:44:ee: + ae:c8:b8:13:63:e5:f8:5e:8f:b0:5a:46:c5:83:3d:41:62:06: + e4:62:a6:0a:40:cc:8e:59:ad:8a:36:4e:20:e6:f2:32:04:6e: + ee:4e:7d:97:88:dc:ea:74:90:c4:ab:a8:b5:bc:6c:81:b1:64: + 77:a6:93:34:44:e4:60:38:b1:0c:2b:29:3a:4a:f7:17:d7:3a: + c8:42:7e:db:4d:5f:09:92:ae:6c:90:e1:7d:9f:96:9c:1a:82: + bd:45:02:76:29:62:e5:b9:14:53:01:53:c0:5a:d5:34:53:7a: + 25:49:3e:3d:db:19:7e:29:57:80:78:67:ea:21:3e:3d:59:36: + e0:8b:da:75:57:9b:c8:9d:a1:18:18:e2:5c:35:35:9e:62:2c: + f5:0f:c0:8f:55:16:a5:d4:9e:cd:0e:78:87:9d:53:d3:01:e1: + 18:61:36:1c:06:c3:3a:43:f3:8a:13:e6:4e:52:32:fd:46:21: + cd:62:18:1f:ae:f5:f2:1a:ea:7a:01:3b:a1:3f:1d:16:00:91: + 5e:94:78:f4:60:33:54:a9:fc:1c:0a:75:f9:17:aa:dd:12:91: + 66:4b:f0:d1:60:25:d4:06:d1:99:9c:c5:64:01:4b:ba:d9:66: + ba:9c:f7:68:75:fd:11:3a:eb:6e:fb:8f:a6:17:8a:cd:bc:1a: + 59:f9:a9:cd:33:db:7d:71:26:7d:c7:be:de:eb:2e:c0:7e:db: + 29:08:0e:82:63:1e:8c:8f:e6:21:1c:b1:49:13:9e:df:78:3b: + 68:01:17:0f:df:97:96:58:32:48:1e:5c:ff:fa:db:90:b5:05: + 84:68:fd:7c:c0:a5:35:d9:75:1e:ea:cc:25:25:3f:6e +-----BEGIN CERTIFICATE----- +MIIJGzCCBQOgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI5NDFaFw0zNjAzMTEyMzI5NDFaMIGzMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEOMAwGA1UE +CwwFVXNlcnMxLjAsBgNVBAMMJWFkbWluaXN0cmF0b3JAYWRkb20uc2FtYmEuZXhh +bXBsZS5jb20xNDAyBgkqhkiG9w0BCQEWJWFkbWluaXN0cmF0b3JAYWRkb20uc2Ft +YmEuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+ +kWTyGyvtm0C8DUYjSXcydP7LmkaGMx5Wvcja3eYqBzRhHPC4cSkkK5DzQ5lvafb/ +jbm3P/M2apmQkNaVY06IWtdBiX9zE2RJx95CZQhdygSyaDpAf2oF31YwL6wbiw/D +FTw4D5BQRAC7WUD20uhbcwMN9n04XS+Zww0TD3TQnu8ekkLERnzchX7pr5FOnV+C +r1hgGKWskW7dz6cyPNL06YG+gJ4Myh8avpjE/uYlwYn+FgowkNPU5a+JJGQS0E8Z +4huG+wapY9FHEIncK1Ik3GapVsLL9Ow1EvStXvz/humx+R+zzkT7vgSvjUKbVqUC +f8XPXyNBHGnuM5d6gVCLAgMBAAGjggIjMIICHzAJBgNVHRMEAjAAME8GA1UdHwRI +MEYwRKBCoECGPmh0dHA6Ly93d3cuc2FtYmEuZXhhbXBsZS5jb20vY3Jscy9DQS1z +YW1iYS5leGFtcGxlLmNvbS1jcmwuY3JsMBEGCWCGSAGG+EIBAQQEAwIFoDALBgNV +HQ8EBAMCBeAwVQYJYIZIAYb4QgENBEgWRlNtYXJ0IENhcmQgTG9naW4gQ2VydGlm +aWNhdGUgZm9yIGFkbWluaXN0cmF0b3JAYWRkb20uc2FtYmEuZXhhbXBsZS5jb20w +HQYDVR0OBBYEFDAQbh9+UjOMyIXlknRddn7pM1s2MB8GA1UdIwQYMBaAFKI+Aiqj +p005tAhNmcwMdTbqJ8M+MGcGA1UdEQRgMF6BJWFkbWluaXN0cmF0b3JAYWRkb20u +c2FtYmEuZXhhbXBsZS5jb22gNQYKKwYBBAGCNxQCA6AnDCVhZG1pbmlzdHJhdG9y +QGFkZG9tLnNhbWJhLmV4YW1wbGUuY29tMDEGA1UdEgQqMCiBJmNhLXNhbWJhLmV4 +YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0GCWCGSAGG+EIBBARAFj5odHRw +Oi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMvQ0Etc2FtYmEuZXhhbXBsZS5j +b20tY3JsLmNybDAfBgNVHSUEGDAWBggrBgEFBQcDAgYKKwYBBAGCNxQCAjANBgkq +hkiG9w0BAQsFAAOCBAEAUz5R0l0saSNb3QUaI/85XVRj5drhS2CMCXxOjtqKu2Nd +vC2g1M6e0s441zJnukqm0R3Ex1Domp5EVhqc9I+5jjmEIdsPYIpgtA9PPDWg0jc9 +iOgKGKenLRnjqtOOGI817z5KlcTTm/TPicJwuYxc74qeelZzE+uLt9nhiFvEYkdC +RY17Lc9xgxtInYSPZWaXYfz2MDToiCo0kUjcerdlvJyYAEznSf5NqVbqh9ZsRjny +mFtWFILynrit/Yk2SIdOXO8/4DX/cl9b4cL92W5AKzWtUAh0lIeJxM3Hq6cZTrry +HYMPsM+c5t9zNojPQpyjcicP979bzGvlIAO1Shzzfa6SQ6q7EwekOnc9NAEA8Ymq +6BsJe7iw4VQD/z2NvjW5E7JZWDJIk/jn1z1JcAFE5ishs3VJrkR6UBW4ZfPDSJbf +yNkq98Uqfixod68teBv8Gtj0i6aGNdLwh+nWMAp2Zfhx6YANHxaGiZKBNNm+m0El +7GWpClayA5FUAiGXmXRhjEou9NCxi/HmJlK89vLgvZZmIsNOUS/DxGVlx5e1Gykj +esB7+0kzoKlqty/zRGtbDCwNdfJQ1YK6mqvgiQq2tYpeGmer2achInVhHtchNhVq +2qg5TZVQK+asxPY4dMnFrM4vs8jUrRink9QavsK+njnmp7EOk9Cez7CsU30IH52l +mCtO9oDk3+pDovlkv4Sy/xyTNmB0CE5b1iSa+KzHgfkqqQAoRBVqMbm1CInIMRUe +j50s0OOoMixoQkEZbEOOacBEAbocxOr0/8hXA7rfP16lA9p1MS4HZ6dcAlXDb48R +9YxWofdLu0bQ5f9owXc9DTUS9UCvzQVcU3T/VODAxhBc6DMGClBHfnE6Nmaq+N6X +Kq6/jW3UOcT9swMdpZxHOYzAs3P4OtY0rElPs4d0ESCPwKokpzAgDMDZHETursi4 +E2Pl+F6PsFpGxYM9QWIG5GKmCkDMjlmtijZOIObyMgRu7k59l4jc6nSQxKuotbxs +gbFkd6aTNETkYDixDCspOkr3F9c6yEJ+201fCZKubJDhfZ+WnBqCvUUCdili5bkU +UwFTwFrVNFN6JUk+PdsZfilXgHhn6iE+PVk24IvadVebyJ2hGBjiXDU1nmIs9Q/A +j1UWpdSezQ54h51T0wHhGGE2HAbDOkPzihPmTlIy/UYhzWIYH6718hrqegE7oT8d +FgCRXpR49GAzVKn8HAp1+Req3RKRZkvw0WAl1AbRmZzFZAFLutlmupz3aHX9ETrr +bvuPpheKzbwaWfmpzTPbfXEmfce+3usuwH7bKQgOgmMejI/mIRyxSROe33g7aAEX +D9+XllgySB5c//rbkLUFhGj9fMClNdl1HurMJSU/bg== +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-key.pem new file mode 100644 index 0000000..0d33211 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-key.pem @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI06+E0Qn55PYCAggA +MBQGCCqGSIb3DQMHBAgRIdE1BfEflgSCBMgjWcKNk0gmS+OepxYA2tMjMir2YwFb +ht/PFx0llj4Zt2U2TgvSFhm7JcsNPXqqqElIvEeNrY5BTB6Jbkd5pt1EpKcBlgHQ +cPtjslAxo5C5FgvLuzaFd1tRhHm7UWygTRcI+79zRmypOm0v57ZdS6Z218sJc0gk +re7tBT+lF+S5uCRAUmWBgdVjEFjW+1r0dhVJWYftB8JoE4zW+B0wEz6PIv0cTt7K +cnjHVMFKWPJStAbJ98RWchF0KWeu+cuWAWt/rJ2QrM+q1bBP4Mgn6XfRnKbcJofk +BG5v4oo8B/TSe3woBMtf2BheaeXDa96D7lxF7gELTkdodNfJd9s66GLSRKCk6amk +eJKO8fLZbXpiT0/TGeFvrihWa/ZpVG4I94KDn2a+U8Agq+B1WA6MqCt6txK6GFIN +okCRyRUYb6TFDI2JA+jeEX+0tStVGp+qNyk4PT4tZOG2BJ2dq5F6+KF0VzE8I7V0 +zIFWQvvwO8N+osvmJgQgxI6JOq0ubiHEEiSrd4lKVO7NJ223I9GXao/z+0l5ywYn +SL0LEsw2adblRDgzBnsLCqWEeC3Oczg790AaNkqWPolGKBEpOXlCPCjILJfG/7Ii +GGvuAQaXOOM3fnxb2oTOpFMn6BQDmX77hiCKGTB4VCgTIhwBOpwLDeDxjyUjCp2C +PPtped8Dne+kK9iGuHyu45sXrVtxfigfKh9+ncCsFVQfpmcYXDiUhn/RUP4qezco +jkKeC+S4lM9mG/KzWeDUtMlYkEqFA6yxs05VzpxR3h7sizV0YAE2evSxn3w4aYWY +GGKtVG4h30f7YbxI1N9+2iBTToAejF5gF5/WDPn8N+voohQCIQ6iAZ48vUDuQGme +mzi73xu774u7M/BnmgtTr1ZG9gvT+F6q6rnJFAqj3k8j+mv2w4XCqytZJ4OGTijo +j/s/eZDWmo4t/WXUMjePDzXl96hjBq4bZOpqNwKDLsqbVwQrhFzXTkGLhGQAyKb4 +wZywUkYfTdWa9f+A2NmWqry9Ef5KcOJTSHt6FeY5kwcY56iZT+cD4V2pgxTqQBGt +YUy/j0V35l41OTKZ6x5P3ZSk45w6RPY3/BqcnfvhSFxON3jFivg1DKIcB8WaWjss +40vP+TthOR2X4FQ/OHKwjs+tC6JpwDuSNCVwj9VBGSgjeXK/aV9BG1A0m4R7qxTV +aT4tjSSfPfkOf16hTW2ncHTr9rvY3XcYm8eC5E/IEQ7gxpG/JI0+xK2tel0bochs +aSBP+qGP85Sib3pcnepG6Zhkx4KgTvhbWRAfNS5rB1jLGSpeWQkMZmun91tTuVLK +fRyfQZ2gkr2ixX/zlPb1bhIXHUBgnoUyUHwZ2lNCDp/dm+nGYqXeeg9lZfD3dYpQ +Yd1zdR7Faj8aOsC9T4DRUDzgUIUCdvd2wdmnXF1YB43VgXjsAkfZkEVve1ltv4iG +OAtp0n9aUz+4yS4kBLWEQfNsK7Tz5zjN2BJmm5qQWARxVbR/shhYKqXuY9HbmB95 +sGc1d37pK+n4HvXqQ701zEuvtwyP/P4gg7HjBI2pauuKfT+eVK+xpTBx4W8imY7j +8IhJ4IBBUWzoMoADD132fVW7f3vpp1XGjvbq5fgDlU6beVsWS9KXBD2Wsl7FDkJ5 +49U= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-openssl.cnf b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-openssl.cnf new file mode 100644 index 0000000..da136b8c --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-openssl.cnf @@ -0,0 +1,242 @@ +# +# Based on the OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +#CRLDISTPT = [CRL Distribution Point; e.g., http://crl-list.base/w4edom-l4.base.crl] +CRLDISTPT = http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + +# Extra OBJECT IDENTIFIER info: +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used as a login credential +scardLogin=1.3.6.1.4.1.311.20.2.2 +# Used in a smart card login certificate's subject alternative name +msUPN=1.3.6.1.4.1.311.20.2.3 +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used to identify a domain controller +msKDC=1.3.6.1.5.2.3.5 +# Identifies the AD GUID +msADGUID=1.3.6.1.4.1.311.25.1 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = CA-samba.example.com # Where everything is kept +certs = $dir/_none_certs # Where the issued certs are kept +crl_dir = $dir/_none_crl # Where the issued crl are kept +database = $dir/Private/CA-samba.example.com-index.txt # database index file. +unique_subject = yes # Set to 'no' to allow creation of + # several certificates with same subject. +new_certs_dir = $dir/NewCerts # default place for new certs. + +certificate = $dir/Public/CA-samba.example.com-cert.pem # The CA certificate +serial = $dir/Private/CA-samba.example.com-serial.txt # The current serial number +crlnumber = $dir/Private/CA-samba.example.com-crlnumber.txt # the current crl number + # must be commented out to leave a V1 CRL + +#crl = $dir/Public/CA-samba.example.com-crl.pem # The current CRL +crl = $dir/Public/CA-samba.example.com-crl.crl # The current CRL +private_key = $dir/Private/CA-samba.example.com-private-key.pem # The private key +RANDFILE = $dir/Private/CA-samba.example.com.rand # private random number file + +#x509_extensions = # The extensions to add to the cert +x509_extensions = template_x509_extensions + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +crl_extensions = crl_ext + +default_days = 7300 # how long to certify for +default_crl_days= 7300 # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = match +stateOrProvinceName = match +localityName = match +organizationName = match +organizationalUnitName = match +commonName = supplied +emailAddress = supplied + +#################################################################### +[ req ] +default_bits = 2048 +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = SambaState + +localityName = Locality Name (eg, city) +localityName_default = SambaCity + +organizationName = Organization Name (eg, company) +organizationName_default = SambaSelfTesting + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = Users + +commonName = Common Name (eg, YOUR name) +commonName_default = administrator@addom.samba.example.com +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = administrator@addom.samba.example.com +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +#challengePassword = A challenge password +#challengePassword_min = 4 +#challengePassword_max = 20 +# +#unstructuredName = An optional company name + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +# Extensions for a typical CA +# PKIX recommendation. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. +keyUsage = cRLSign, keyCertSign + +crlDistributionPoints=URI:$CRLDISTPT + +# Some might want this also +nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +subjectAltName=email:copy +# Copy issuer details +issuerAltName=issuer:copy + +[ crl_ext ] +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +#[ usr_cert_scarduser ] +[ template_x509_extensions ] + +# These extensions are added when 'ca' signs a request for a certificate that will be used to login from a smart card + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE +crlDistributionPoints=URI:$CRLDISTPT + +# For normal client use this is typical +nsCertType = client, email + +# This is typical in keyUsage for a client certificate. +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "Smart Card Login Certificate for administrator@addom.samba.example.com" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. + +subjectAltName=email:copy,otherName:msUPN;UTF8:administrator@addom.samba.example.com + +# Copy subject details +issuerAltName=issuer:copy + +nsCaRevocationUrl = $CRLDISTPT +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +#Extended Key requirements for client certs +extendedKeyUsage = clientAuth,scardLogin + diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-private-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-private-key.pem new file mode 100644 index 0000000..1510760 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-private-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAvpFk8hsr7ZtAvA1GI0l3MnT+y5pGhjMeVr3I2t3mKgc0YRzw +uHEpJCuQ80OZb2n2/425tz/zNmqZkJDWlWNOiFrXQYl/cxNkScfeQmUIXcoEsmg6 +QH9qBd9WMC+sG4sPwxU8OA+QUEQAu1lA9tLoW3MDDfZ9OF0vmcMNEw900J7vHpJC +xEZ83IV+6a+RTp1fgq9YYBilrJFu3c+nMjzS9OmBvoCeDMofGr6YxP7mJcGJ/hYK +MJDT1OWviSRkEtBPGeIbhvsGqWPRRxCJ3CtSJNxmqVbCy/TsNRL0rV78/4bpsfkf +s85E+74Er41Cm1alAn/Fz18jQRxp7jOXeoFQiwIDAQABAoIBADkGUvmrrdJ1IcLk +CffnNPbxUYllifMAevSj5+WufwBWlZL10QawPgpnywEwWkqfn9zK8SbnyQSgk4FS +BhQ/2jEtVbpzxaKOy/TUDSs7BmziVdN5Iu1H81b8hNL4gPzg+P98bD+uUJXkM3/c +bnctl4A+A0z7VG84W1Ucq93nQyJl18E64i57JMb3tI+423FM3sJBk2FUj64Mwg8r +0p88gccSieB3GusffHazlJDKrlHdFyClLBnW3OQHegv42JOKZErIMHwlaV8fhF21 +GAARx/pDgnvIYUaGhLrf2pCyIkOZIdUedA84rLwAZT9akOtxpNCAxlVUn4xcpAC1 +EAKzGbECgYEA99Hzh3vDNGINYJjqsw01E71DelNTeUmBOuJKqdOG0YLHiG0tERcx +9KLv+7Uo/qtuRzpkMHao7+zC4spQBk1yYkjVtPkXhWdgVUOztkkza72jlwtVu0eK +VYfB7eubOMnSsPtVeYyyM6DFKBRUxo0VKsvvjD/84WdCGsgy+jDRDUkCgYEAxNur +XMStYOnxdebOGFs5U8jc+/HNNuaCpSkk98uQ0/VfWp8TXA508FYnT6/BcoH+3hHy +7W/7aMv//0IWgNQk8m1w33svDdq7jRJXrIpyb7QaX2OW8IfTfIMKVXOgxPvD/4IK +lvmvf8T7K0W7rDYdcfy9bsDb0RQcH0Z3cp4lUzMCgYEAmLjmX6RB1FJo9BLI8Lc+ +8n88ynH3i1NlNKioYqhc+VijJsxBbbrhqmWPh4tJTEjRmUu+2q8FxXYfVCxhzMCF +sVQ5f2HSwP/IOkOSyM+rxMYFvtvZZaTc94DGXp1H92NJWJBLSLEQUQjO97gv1nyz +gsBTTBdS/IXqEx81a0ISUyECgYA80saClj4fmIjDbfm1qtHuojwtGAvY76XkE+9Z +JKtt4f2BSW843TqiW2wwAdTaZXHy+Ua+t//M5GMHYksDqQh1Yv0h/7SNKk0SjF1M +cUZkXxha6rFjRgRBD1ftCRneYw+u7WYKOcFQz/Lu7s/KqLm2U2nQQ4RneDgsLaCQ +aG6N4wKBgArI0d3MlNFXLU7bT+q/2BaZ5VBwaF/6DlI4m1hDT8dKtOTja+y6vAm/ +aH82uJyoom8R/w2H/ICe3NuwYgTo/7Vy6xMt1TnskGOc0yjTZBMMU1nN8zrxlgD1 +1Xr8TzGOf//mK4H54B/POSq6WZ0PSXDVGToVWMdif+2Rq16+CcKp +-----END RSA PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-req.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-req.pem new file mode 100644 index 0000000..fbaf0fc --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-S03-req.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDDTCCAfUCAQAwgccxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTYW1iYVN0YXRl +MRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNVBAoMEFNhbWJhU2VsZlRlc3Rpbmcx +DjAMBgNVBAsMBVVzZXJzMS4wLAYDVQQDDCVhZG1pbmlzdHJhdG9yQGFkZG9tLnNh +bWJhLmV4YW1wbGUuY29tMTQwMgYJKoZIhvcNAQkBFiVhZG1pbmlzdHJhdG9yQGFk +ZG9tLnNhbWJhLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvpFk8hsr7ZtAvA1GI0l3MnT+y5pGhjMeVr3I2t3mKgc0YRzwuHEpJCuQ +80OZb2n2/425tz/zNmqZkJDWlWNOiFrXQYl/cxNkScfeQmUIXcoEsmg6QH9qBd9W +MC+sG4sPwxU8OA+QUEQAu1lA9tLoW3MDDfZ9OF0vmcMNEw900J7vHpJCxEZ83IV+ +6a+RTp1fgq9YYBilrJFu3c+nMjzS9OmBvoCeDMofGr6YxP7mJcGJ/hYKMJDT1OWv +iSRkEtBPGeIbhvsGqWPRRxCJ3CtSJNxmqVbCy/TsNRL0rV78/4bpsfkfs85E+74E +r41Cm1alAn/Fz18jQRxp7jOXeoFQiwIDAQABoAAwDQYJKoZIhvcNAQELBQADggEB +ALQr9rGYIkhd/AXeVoFHs/66rwaq3GccdnJpi023/5LhOlRmMa2BWTuQm3jW/3Oc +HgQOx9G0GTDpaBtAjOCGDCygw/k23oekVTQtDPiGigMnpuY2vnrjAeUFJo3us5pA +9eVPzKTzJf5ftc/aoVC39t/1Uks103M8t5vJCcexBTYQONe56XC1krY50PHZNI/u +stjOmleHZclLBU/BplId43nRlvvdkXihPiEbdV4XvhHRs/6w52DkQst6NH6jzeWk +anYEP2Oo1ROX5v201414ZaWm7oDxtNuL8NzDt+DUGISwC/9ZcqadzlaoI9XVhOb2 +AfbQMY1Q/3OeR8uRROpnHjE= +-----END CERTIFICATE REQUEST----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-cert.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-cert.pem new file mode 120000 index 0000000..a2eb210 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-cert.pem @@ -0,0 +1 @@ +USER-administrator@addom.samba.example.com-S03-cert.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-private-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-private-key.pem new file mode 120000 index 0000000..afbf12e --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@addom.samba.example.com/USER-administrator@addom.samba.example.com-private-key.pem @@ -0,0 +1 @@ +USER-administrator@addom.samba.example.com-S03-private-key.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-cert.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-cert.pem new file mode 100644 index 0000000..4ab5d5a --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-cert.pem @@ -0,0 +1,169 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=SambaState, L=SambaCity, O=SambaSelfTesting, OU=CA Administration, CN=CA of samba.example.com/emailAddress=ca-samba.example.com@samba.example.com + Validity + Not Before: Mar 16 23:29:04 2016 GMT + Not After : Mar 11 23:29:04 2036 GMT + Subject: C=US, ST=SambaState, O=SambaSelfTesting, OU=Users, CN=administrator@samba.example.com/emailAddress=administrator@samba.example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:af:87:9e:1e:7f:c0:ab:da:47:22:74:d0:df:01: + f1:67:6c:ac:c4:b7:d9:18:97:e5:7a:62:76:33:b6: + 52:f2:92:90:75:ac:a3:94:7e:0c:29:75:c9:83:2f: + 19:66:60:84:45:ff:d5:a9:bd:c5:3a:a2:d8:25:cf: + 15:8a:23:3e:09:73:2f:99:1d:24:1f:e6:96:7e:7b: + c4:1e:8d:55:5b:c1:18:69:cd:1d:b4:22:d5:7b:db: + 5e:7c:91:f2:8e:c1:03:30:ee:63:46:5a:54:d5:40: + ac:79:55:00:71:07:8d:3e:0e:ed:ff:93:6c:f1:2d: + 84:c1:51:a3:7c:49:cf:ff:85:7b:c0:64:c1:ba:c8: + 66:7a:ff:17:2a:74:ea:16:6a:1d:97:c0:27:57:10: + be:76:f5:9a:63:56:c7:25:c6:fc:a7:5e:00:a6:1a: + 3d:21:bd:7a:f9:e3:03:60:ce:df:16:06:fc:05:bc: + d1:c8:5d:e7:33:ed:52:8b:60:5b:60:c5:70:13:1d: + c1:b3:08:13:09:3b:05:e8:02:40:12:45:89:af:87: + 1f:6a:8f:62:ce:1e:17:13:34:82:81:86:e9:bb:85: + 5b:75:1d:f4:3a:02:b4:a6:58:23:fe:c3:3a:35:09: + 95:bb:f7:79:bc:e3:97:e6:6d:77:24:aa:2d:51:50: + 37:69 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + + Netscape Cert Type: + SSL Client, S/MIME + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment + Netscape Comment: + Smart Card Login Certificate for administrator@samba.example.com + X509v3 Subject Key Identifier: + 45:DA:4B:8D:05:9C:62:4E:62:C3:D7:5C:5F:D3:D9:85:B4:9B:F2:2C + X509v3 Authority Key Identifier: + keyid:A2:3E:02:2A:A3:A7:4D:39:B4:08:4D:99:CC:0C:75:36:EA:27:C3:3E + + X509v3 Subject Alternative Name: + email:administrator@samba.example.com, othername: + X509v3 Issuer Alternative Name: + email:ca-samba.example.com@samba.example.com + Netscape CA Revocation Url: + http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + X509v3 Extended Key Usage: + TLS Web Client Authentication, scardLogin + Signature Algorithm: sha256WithRSAEncryption + a2:bb:e6:97:67:3c:b6:6e:6e:dd:34:99:16:c6:80:91:08:bf: + 91:ba:51:62:5d:76:2f:e5:53:91:3d:99:03:18:a9:84:69:73: + 76:66:c3:eb:56:d7:c5:40:91:15:da:de:b2:76:48:7d:8a:8c: + 80:79:3c:e6:da:0e:a6:c3:53:d6:74:ee:5f:29:b7:03:46:de: + 89:32:14:22:03:30:68:2e:7e:06:d4:ac:9e:82:c0:02:16:7f: + 81:ba:ee:7a:e7:8b:f7:fb:99:7f:8c:eb:78:54:97:4e:28:44: + da:f4:e2:1b:f8:3e:ac:ca:cc:e3:e3:71:90:91:47:9c:78:ed: + 6f:bc:b7:98:12:ea:75:e5:15:f7:26:56:a7:5c:d6:74:a8:13: + 7b:23:35:4e:6a:01:f6:a9:f5:5b:9b:d0:ea:ba:0f:c3:c4:1a: + e0:b9:a3:ed:5d:28:cb:7f:1d:3e:8a:9a:af:4c:88:00:3c:10: + f0:49:85:24:60:e6:cb:d6:9e:00:46:78:4d:90:22:68:4f:10: + 39:84:3b:e2:7c:3d:ed:23:41:19:7e:6f:45:59:89:a9:9f:26: + c1:f9:7d:4d:0a:b4:10:f9:31:7d:cc:87:d0:4b:62:14:70:86: + c8:7d:14:ff:e4:68:e2:de:42:ca:01:c7:aa:2d:5a:a5:72:64: + f1:4c:fa:6e:60:15:22:08:68:e6:c6:6a:75:63:24:b5:54:76: + d1:97:4f:e0:e8:bc:eb:d0:62:84:4a:b4:3a:07:38:5f:b9:a6: + 6a:31:14:47:33:81:bd:d0:a4:a2:da:2b:92:0d:dc:42:c4:0f: + 28:0d:b6:1b:33:b5:88:df:1b:a8:d8:90:9a:11:ce:df:d4:14: + e9:ac:94:94:95:bb:bc:6e:f1:be:85:29:3f:17:ab:41:14:d8: + 20:ba:e0:a2:a3:d3:d4:8b:1e:4b:32:22:8d:0d:c1:e6:39:1a: + ce:cd:f3:1d:f1:82:85:d5:e7:80:34:90:a4:0e:d4:af:32:c8: + 79:4e:25:32:b6:1e:06:3a:26:42:38:47:1a:32:96:71:5b:fe: + 5b:b0:ef:7d:fe:58:ca:eb:b5:c9:4b:2f:12:cb:89:36:22:7c: + a6:39:ab:20:c1:2d:cd:6b:34:e1:cd:bc:ed:45:45:12:4a:65: + 4b:ab:45:f2:6d:7a:9d:f8:b5:52:78:1b:da:2f:e0:ce:f7:e2: + b0:fa:6f:40:3d:dd:e9:39:c3:63:68:ab:77:53:be:3b:dd:9a: + bc:d7:d7:fa:6a:bf:bf:74:f7:11:80:87:f9:d3:45:eb:1e:8e: + d1:a9:a0:2e:66:e7:20:67:1c:4c:22:43:77:85:ff:1a:23:37: + cc:49:de:51:ee:f2:04:2f:a8:98:88:0f:b6:18:53:eb:e2:49: + 15:5e:02:8b:1e:7b:e6:c5:d1:0c:df:84:4e:d9:bd:fe:21:48: + d4:a4:11:01:27:57:51:d6:c1:b2:a1:1c:11:9a:a7:d1:ab:f0: + 99:16:b2:c8:3f:74:25:68:0b:1a:cf:58:0d:cd:cc:1a:6d:8b: + ec:1f:70:82:02:40:97:0f:75:2c:53:87:c1:42:5c:d1:7e:19: + 78:2c:2c:88:73:33:81:63:38:84:07:0f:16:bb:7c:54:59:03: + 94:e7:b8:85:d7:f8:5e:53:35:65:2e:e5:27:65:be:f0:89:65: + f6:ab:3f:6e:a5:bd:c1:1a:9e:31:30:68:6e:50:af:54:4c:33: + f8:73:2f:41:60:4f:4c:85:1b:ad:7d:db:62:42:dc:87:96:b4: + cf:ce:12:50:ed:6c:01:5f:e2:f9:03:f5:f7:4c:6c:8f:2b:5b: + 7a:64:7d:19:e8:20:f2:e9:10:58:f3:71:0e:1e:58:68:f2:59: + 3c:06:53:7a:f3:60:62:5b:c7:b7:83:58:1d:3d:a6:17:db:33: + cc:91:14:af:d6:b9:08:bf:60:af:ac:3e:fe:8b:74:71:20:c7: + e7:31:5e:26:6c:28:52:67:12:1e:c3:9b:89:23:5d:88:ee:b0: + 6b:db:cc:94:8b:9b:1b:40:b7:66:bc:7d:1d:e1:08:00:20:ba: + 41:cd:17:d6:4c:7b:c4:5a:fd:cf:6b:20:e2:b8:86:9c:31:17: + c2:d7:7f:1c:3a:d0:fc:1d:f5:7f:c9:96:04:27:de:b8:ef:8d: + 38:9a:b3:56:60:ac:c2:07:38:64:19:39:9e:73:6f:ba:59:15: + ac:45:42:4d:bb:79:60:7f:ae:c3:8d:63:4a:27:16:0a:ca:92: + 7f:f7:a2:02:76:f5:e6:7c:ec:ba:ea:18:cd:9c:3b:ee:37:2c: + 9d:78:4e:c9:40:6d:94:cc:ce:ca:f4:33:fc:a4:dd:05:62:d6: + 0f:1e:19:63:af:10:c3:ff:02:1a:0a:48:fd:af:f2:a4:0e:64: + dd:90:f4:4f:14:1b:90:1f:9e:29:b0:0b:94:a4:d1:2a:87:b9: + 3a:76:c2:b6:af:c3:d4:84:6e:85:1c:64:73:46:d0:df:72:c0: + 3c:42:91:c4:30:10:11:18:36:bc:e5:17:36:22:5f:c2:3f:ac: + 1d:2e:9d:87:11:be:a7:ac:b2:62:35:74:b9:27:27:95:bc:c1: + 11:44:f8:64:36:60:74:06:a2:e7:e9:76:be:a7:86:5e:18:1e: + bd:dc:b0:aa:ae:92:d6:dd:d6:25:80:d6:c1:be:c1:21:1c:01: + 6f:83:20:ae:b7:54:4f:3d:2d:12:fc:a2:cc:49:fd:59 +-----BEGIN CERTIFICATE----- +MIII/TCCBOWgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBxjELMAkGA1UEBhMCVVMx +EzARBgNVBAgMClNhbWJhU3RhdGUxEjAQBgNVBAcMCVNhbWJhQ2l0eTEZMBcGA1UE +CgwQU2FtYmFTZWxmVGVzdGluZzEaMBgGA1UECwwRQ0EgQWRtaW5pc3RyYXRpb24x +IDAeBgNVBAMMF0NBIG9mIHNhbWJhLmV4YW1wbGUuY29tMTUwMwYJKoZIhvcNAQkB +FiZjYS1zYW1iYS5leGFtcGxlLmNvbUBzYW1iYS5leGFtcGxlLmNvbTAeFw0xNjAz +MTYyMzI5MDRaFw0zNjAzMTEyMzI5MDRaMIGnMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKU2FtYmFTdGF0ZTEZMBcGA1UECgwQU2FtYmFTZWxmVGVzdGluZzEOMAwGA1UE +CwwFVXNlcnMxKDAmBgNVBAMMH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5j +b20xLjAsBgkqhkiG9w0BCQEWH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5j +b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvh54ef8Cr2kcidNDf +AfFnbKzEt9kYl+V6YnYztlLykpB1rKOUfgwpdcmDLxlmYIRF/9WpvcU6otglzxWK +Iz4Jcy+ZHSQf5pZ+e8QejVVbwRhpzR20ItV72158kfKOwQMw7mNGWlTVQKx5VQBx +B40+Du3/k2zxLYTBUaN8Sc//hXvAZMG6yGZ6/xcqdOoWah2XwCdXEL529ZpjVscl +xvynXgCmGj0hvXr54wNgzt8WBvwFvNHIXecz7VKLYFtgxXATHcGzCBMJOwXoAkAS +RYmvhx9qj2LOHhcTNIKBhum7hVt1HfQ6ArSmWCP+wzo1CZW793m845fmbXckqi1R +UDdpAgMBAAGjggIRMIICDTAJBgNVHRMEAjAAME8GA1UdHwRIMEYwRKBCoECGPmh0 +dHA6Ly93d3cuc2FtYmEuZXhhbXBsZS5jb20vY3Jscy9DQS1zYW1iYS5leGFtcGxl +LmNvbS1jcmwuY3JsMBEGCWCGSAGG+EIBAQQEAwIFoDALBgNVHQ8EBAMCBeAwTwYJ +YIZIAYb4QgENBEIWQFNtYXJ0IENhcmQgTG9naW4gQ2VydGlmaWNhdGUgZm9yIGFk +bWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5jb20wHQYDVR0OBBYEFEXaS40FnGJO +YsPXXF/T2YW0m/IsMB8GA1UdIwQYMBaAFKI+Aiqjp005tAhNmcwMdTbqJ8M+MFsG +A1UdEQRUMFKBH2FkbWluaXN0cmF0b3JAc2FtYmEuZXhhbXBsZS5jb22gLwYKKwYB +BAGCNxQCA6AhDB9hZG1pbmlzdHJhdG9yQHNhbWJhLmV4YW1wbGUuY29tMDEGA1Ud +EgQqMCiBJmNhLXNhbWJhLmV4YW1wbGUuY29tQHNhbWJhLmV4YW1wbGUuY29tME0G +CWCGSAGG+EIBBARAFj5odHRwOi8vd3d3LnNhbWJhLmV4YW1wbGUuY29tL2NybHMv +Q0Etc2FtYmEuZXhhbXBsZS5jb20tY3JsLmNybDAfBgNVHSUEGDAWBggrBgEFBQcD +AgYKKwYBBAGCNxQCAjANBgkqhkiG9w0BAQsFAAOCBAEAorvml2c8tm5u3TSZFsaA +kQi/kbpRYl12L+VTkT2ZAxiphGlzdmbD61bXxUCRFdresnZIfYqMgHk85toOpsNT +1nTuXym3A0beiTIUIgMwaC5+BtSsnoLAAhZ/gbrueueL9/uZf4zreFSXTihE2vTi +G/g+rMrM4+NxkJFHnHjtb7y3mBLqdeUV9yZWp1zWdKgTeyM1TmoB9qn1W5vQ6roP +w8Qa4Lmj7V0oy38dPoqar0yIADwQ8EmFJGDmy9aeAEZ4TZAiaE8QOYQ74nw97SNB +GX5vRVmJqZ8mwfl9TQq0EPkxfcyH0EtiFHCGyH0U/+Ro4t5CygHHqi1apXJk8Uz6 +bmAVIgho5sZqdWMktVR20ZdP4Oi869BihEq0Ogc4X7mmajEURzOBvdCkotorkg3c +QsQPKA22GzO1iN8bqNiQmhHO39QU6ayUlJW7vG7xvoUpPxerQRTYILrgoqPT1Ise +SzIijQ3B5jkazs3zHfGChdXngDSQpA7UrzLIeU4lMrYeBjomQjhHGjKWcVv+W7Dv +ff5Yyuu1yUsvEsuJNiJ8pjmrIMEtzWs04c287UVFEkplS6tF8m16nfi1Ungb2i/g +zvfisPpvQD3d6TnDY2ird1O+O92avNfX+mq/v3T3EYCH+dNF6x6O0amgLmbnIGcc +TCJDd4X/GiM3zEneUe7yBC+omIgPthhT6+JJFV4Cix575sXRDN+ETtm9/iFI1KQR +ASdXUdbBsqEcEZqn0avwmRayyD90JWgLGs9YDc3MGm2L7B9wggJAlw91LFOHwUJc +0X4ZeCwsiHMzgWM4hAcPFrt8VFkDlOe4hdf4XlM1ZS7lJ2W+8Ill9qs/bqW9wRqe +MTBoblCvVEwz+HMvQWBPTIUbrX3bYkLch5a0z84SUO1sAV/i+QP190xsjytbemR9 +Gegg8ukQWPNxDh5YaPJZPAZTevNgYlvHt4NYHT2mF9szzJEUr9a5CL9gr6w+/ot0 +cSDH5zFeJmwoUmcSHsObiSNdiO6wa9vMlIubG0C3Zrx9HeEIACC6Qc0X1kx7xFr9 +z2sg4riGnDEXwtd/HDrQ/B31f8mWBCfeuO+NOJqzVmCswgc4ZBk5nnNvulkVrEVC +Tbt5YH+uw41jSicWCsqSf/eiAnb15nzsuuoYzZw77jcsnXhOyUBtlMzOyvQz/KTd +BWLWDx4ZY68Qw/8CGgpI/a/ypA5k3ZD0TxQbkB+eKbALlKTRKoe5OnbCtq/D1IRu +hRxkc0bQ33LAPEKRxDAQERg2vOUXNiJfwj+sHS6dhxG+p6yyYjV0uScnlbzBEUT4 +ZDZgdAai5+l2vqeGXhgevdywqq6S1t3WJYDWwb7BIRwBb4MgrrdUTz0tEvyizEn9 +WQ== +-----END CERTIFICATE----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-key.pem new file mode 100644 index 0000000..652e3bd --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-key.pem @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI7Afo/WihRO4CAggA +MBQGCCqGSIb3DQMHBAiyzMez8ikVKgSCBMikJkx4Qhm0cLRQXJfIPsHX0YQfinoJ +qLGWMQ5KWTpwFZHoeqarmCVLJwReF75E8nD5tJdKt5J+lN0gBQMbppAzlSOJvMne +1E5sDoBHY3jYUViF3p+ZZt4YoDxaGFYxcGL9M6Uo/Yb1791riMisQjgn7inpRe0i +JuHngJH9Dblg0+vGM3JkMKdizWHSW4RyeYXa8d3rh62Y5RD7exUHKkz3pPucSsyy +dnkhvbhdXSYzPxcUarrjx3pNMzWhamLWP3V6UwupCB8dygLm4QV+Fc3Jw7wR3Efj +cewWjmXHuHzAGfDhr1r6yeWaAQCYezSp18UwMRv9AWgiTAayxDI+IroBigvU3PfA +KE0RlWBnvoy2ggNEsCvk2QXYpQiIJMTS9u1oi2aOdvXaaVxuKBPJGgzAFGSnM44k +gE1Pe+snVxzRuzHCNXnWoCxSa9xAvRt/dnQ9n1p2m3lwlt+kP0kO4ieMhT+SnBNh +QY/WRfJ8E5ldYyfJ0y2eRd1hCu+42tj72rAuQkhPEUJzWuU6N1xzChXPwXVnhIh4 +HS4bpd9uL1wA5sNw2zfXdanagmSrXC5EFVdj4rJzHWzkalg0GTMhYd4QsbqI5d8O +lO5ECnZUJwIcYa5Hy7OVDymRh3BxPMDGYqiO1+6QHUrqRm/XiSDUSaBfLat9ckHY +0JT5nbBMg0TJ3VIhUbsZaQ4fwZNr9zgeS+yoFuLcPYPCHBz2fDNq6MFb0BqbHcYY +qmf++nxF/jW21UKTryBeiLdkq1TjExOEXdmjSL4vwmUjyx+ycM4w8GvdU4xkdkQl +1jNlx20WSocZ0hzreCMXglUb1q7tzZvaVJrSS9TX2PV38Fcz6jpmOeKtnkRBMUis +Ge20QO7D8zCJM0jL+mNAnuZCA7zHc8aenbR6hK8i3Kd8G0XhWLNVWI5KfFtgrRaW +UCM8mSdEIvWZfPrdvxo/kYEXBBA8i+3oO0nSUTyHpqmsIH3nYvaWnVmibnKMigO3 ++3d+6Db5R117EbXDdRWm85jiN7PQ1SdNVxtKN4Wu188r/KfchXAeBQcBy9Kh1vVY +qYTqP4Mp7dbm864iiZQZwTLJeq346+xUze5NY7nFHWl0ps7ujk+i9WA9I+M2TAj9 +Zmywy4Xvjwpj7PO5zA9O5TRxnnBbz7VrTcxBLK+6T/2yZZceJ29Bv7wy61eK9LNk +AYy+MFXlY64L6HauTk9Ne/VnNnTvYYqrqPNy6CehQc0+LKvmYLCHUZabhWi7P1rj +gUkkypfBH0j8k1lDnjnYu5bml32GK7eBix9C+5kNDadnvCEVDiYFT59SDyKCUHMZ +19EKywqkWVPu5ez+60zSEJACpvIqDxlamusN3O9tQZD/t2c2lJiBeBPszXgj8Gin +++tuCwkz/3KNy+u3SCZg9SUk5+XVZDOQOMh9EmUT5oqoPUTm9pblU2B8lRZaw/wl +B97E4q4TUOtXZXHJdCkU8Sxr8/l8fOFYqIeiFx8PhSHaFgpEKgs89G9AefIb+l1u +Z36bqMs0y4rIiSHR++0ZO5NJIi33zhPHvifmPzBTDXRn9cWdfqwetq1ts9ZD27oE +4UhJyRU0gprmtpQWoVnd6ghiM1zk7lZmRQEDDXy4+puztzgZNLKJbSeXbufe49nX +DcU= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-openssl.cnf b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-openssl.cnf new file mode 100644 index 0000000..db72360 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-openssl.cnf @@ -0,0 +1,242 @@ +# +# Based on the OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +#CRLDISTPT = [CRL Distribution Point; e.g., http://crl-list.base/w4edom-l4.base.crl] +CRLDISTPT = http://www.samba.example.com/crls/CA-samba.example.com-crl.crl + +# Extra OBJECT IDENTIFIER info: +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used as a login credential +scardLogin=1.3.6.1.4.1.311.20.2.2 +# Used in a smart card login certificate's subject alternative name +msUPN=1.3.6.1.4.1.311.20.2.3 +# Ordinarily, certificates must have this oid as an enhanced key usage in order for Windows to allow them to be used to identify a domain controller +msKDC=1.3.6.1.5.2.3.5 +# Identifies the AD GUID +msADGUID=1.3.6.1.4.1.311.25.1 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = CA-samba.example.com # Where everything is kept +certs = $dir/_none_certs # Where the issued certs are kept +crl_dir = $dir/_none_crl # Where the issued crl are kept +database = $dir/Private/CA-samba.example.com-index.txt # database index file. +unique_subject = yes # Set to 'no' to allow creation of + # several certificates with same subject. +new_certs_dir = $dir/NewCerts # default place for new certs. + +certificate = $dir/Public/CA-samba.example.com-cert.pem # The CA certificate +serial = $dir/Private/CA-samba.example.com-serial.txt # The current serial number +crlnumber = $dir/Private/CA-samba.example.com-crlnumber.txt # the current crl number + # must be commented out to leave a V1 CRL + +#crl = $dir/Public/CA-samba.example.com-crl.pem # The current CRL +crl = $dir/Public/CA-samba.example.com-crl.crl # The current CRL +private_key = $dir/Private/CA-samba.example.com-private-key.pem # The private key +RANDFILE = $dir/Private/CA-samba.example.com.rand # private random number file + +#x509_extensions = # The extensions to add to the cert +x509_extensions = template_x509_extensions + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +crl_extensions = crl_ext + +default_days = 7300 # how long to certify for +default_crl_days= 7300 # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = match +stateOrProvinceName = match +localityName = match +organizationName = match +organizationalUnitName = match +commonName = supplied +emailAddress = supplied + +#################################################################### +[ req ] +default_bits = 2048 +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = SambaState + +localityName = Locality Name (eg, city) +localityName_default = SambaCity + +organizationName = Organization Name (eg, company) +organizationName_default = SambaSelfTesting + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = Users + +commonName = Common Name (eg, YOUR name) +commonName_default = administrator@samba.example.com +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = administrator@samba.example.com +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +#challengePassword = A challenge password +#challengePassword_min = 4 +#challengePassword_max = 20 +# +#unstructuredName = An optional company name + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +# Extensions for a typical CA +# PKIX recommendation. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. +keyUsage = cRLSign, keyCertSign + +crlDistributionPoints=URI:$CRLDISTPT + +# Some might want this also +nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +subjectAltName=email:copy +# Copy issuer details +issuerAltName=issuer:copy + +[ crl_ext ] +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +#[ usr_cert_scarduser ] +[ template_x509_extensions ] + +# These extensions are added when 'ca' signs a request for a certificate that will be used to login from a smart card + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE +crlDistributionPoints=URI:$CRLDISTPT + +# For normal client use this is typical +nsCertType = client, email + +# This is typical in keyUsage for a client certificate. +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "Smart Card Login Certificate for administrator@samba.example.com" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. + +subjectAltName=email:copy,otherName:msUPN;UTF8:administrator@samba.example.com + +# Copy subject details +issuerAltName=issuer:copy + +nsCaRevocationUrl = $CRLDISTPT +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +#Extended Key requirements for client certs +extendedKeyUsage = clientAuth,scardLogin + diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-private-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-private-key.pem new file mode 100644 index 0000000..cc8f150 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-private-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAr4eeHn/Aq9pHInTQ3wHxZ2ysxLfZGJflemJ2M7ZS8pKQdayj +lH4MKXXJgy8ZZmCERf/Vqb3FOqLYJc8ViiM+CXMvmR0kH+aWfnvEHo1VW8EYac0d +tCLVe9tefJHyjsEDMO5jRlpU1UCseVUAcQeNPg7t/5Ns8S2EwVGjfEnP/4V7wGTB +ushmev8XKnTqFmodl8AnVxC+dvWaY1bHJcb8p14Apho9Ib16+eMDYM7fFgb8BbzR +yF3nM+1Si2BbYMVwEx3BswgTCTsF6AJAEkWJr4cfao9izh4XEzSCgYbpu4VbdR30 +OgK0plgj/sM6NQmVu/d5vOOX5m13JKotUVA3aQIDAQABAoIBAQCEj7E0a1rA7ooG +VZ5grQD5ELOxpP7Jef2OXcnS6ADgvRtoI0cun7rjnNbgwbM3A/EhRELCfFT1IYKH +m0szFcaGMH1j7wQXK3fAcgv83tP2BXBAhu3F2wDLFzLWdQpwEQgt7fr/aLzkiIE4 +6J76va9HjNLkzxvZUH0P2m3TMZNp7s2NLjxNQwivNXSgKXcT9fPX7IaBd063W41I +iYQZ7M8Q3C1vk34uC9V1LxjFxOAe42G/ITkjt3CJbg0CjMXG3P3TKIXG94ufpFQO +mkEzUSGxTCkwlqHKcxsa+7f72TocuhLuwpFBSeRmiIsa5ZHxJiC6XOkz2CAboNkI +UMSVjoxZAoGBAOlOGjiF7ChheDLhtj3/VcxfyHkcNoUFAtKuoT/FD8JMQiEUTifr +V7eA8pfAQubVVRNLmZEA40gsJsTPbCRQymwcYDFRATlTd6nZ1s53z99E/v/1QjIa +ZpQXRD+Nt1xmID/MuX34qpIA6ZEE2zTFoMo1STeNf4eC9mESW9DkA05rAoGBAMCa +wrvLa5whtXbhdoWfCMYKtSQuGTEKslb4Ec97sKIdZXloGnH0eyiwnynCDhX2wPJt +gnQtVxNXb9+MFxh+6bnX5rMyB+myXszpPNBCbLO0FU3+vfIEmOoULqU1Xn7Eu97m +LGoR6G9cN7p8RuX7zp5ROKGfDg77oW8XhVah2x57AoGAY1BmBQ2tW/sx6ab/pyCc +a2WSt0t1QebCLuE7ryO586H2vJIiOwgJzQnNOyAS2qSRlKcn9fwExGJXFoydok/p ++1+Q6y1qcfbAB8O9lyKVkJuUWW0UArQOWpgU62DuXxzyOXZyt9c09PYCd0Mz9SDz +s2A/jLBlS1BKhUQFZcTKS4UCgYBaT7cD66x3t26pYar7mMi6ZAbwAhWZ41QgZ42i +ZnM6cOJF/UR5LpQZTkgzgmSsc9mhUywaYbA0x4kTn1KtD8V0eQIaAFmpgRPmrW7w +kFT8JnLe8ZYLR5CUIgaFPPMkKgeVywQEcIU2wlz3OpLcACiwH5GYZ0ZmTCM0Pikt +qBNgxQKBgEVgpIHZi2xdfvwtCrEfomnlImj94HySKIFenCRoc/d34+KO4jKho1zN +dqbSDqz/lB/7GWFjRszTMZMVJkl8TbE050UEe8EDPt93BSeGHNCUXUesZQVddGhn +iH8OLIkoW3xIlNgflwi4+7gLjWrAHHPwEG3Iys83DVCA5D/4C02m +-----END RSA PRIVATE KEY----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-req.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-req.pem new file mode 100644 index 0000000..72cd979 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-S01-req.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDATCCAekCAQAwgbsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTYW1iYVN0YXRl +MRIwEAYDVQQHDAlTYW1iYUNpdHkxGTAXBgNVBAoMEFNhbWJhU2VsZlRlc3Rpbmcx +DjAMBgNVBAsMBVVzZXJzMSgwJgYDVQQDDB9hZG1pbmlzdHJhdG9yQHNhbWJhLmV4 +YW1wbGUuY29tMS4wLAYJKoZIhvcNAQkBFh9hZG1pbmlzdHJhdG9yQHNhbWJhLmV4 +YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr4eeHn/A +q9pHInTQ3wHxZ2ysxLfZGJflemJ2M7ZS8pKQdayjlH4MKXXJgy8ZZmCERf/Vqb3F +OqLYJc8ViiM+CXMvmR0kH+aWfnvEHo1VW8EYac0dtCLVe9tefJHyjsEDMO5jRlpU +1UCseVUAcQeNPg7t/5Ns8S2EwVGjfEnP/4V7wGTBushmev8XKnTqFmodl8AnVxC+ +dvWaY1bHJcb8p14Apho9Ib16+eMDYM7fFgb8BbzRyF3nM+1Si2BbYMVwEx3BswgT +CTsF6AJAEkWJr4cfao9izh4XEzSCgYbpu4VbdR30OgK0plgj/sM6NQmVu/d5vOOX +5m13JKotUVA3aQIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAGrgBV0TkeQ3fHEJ +vTabQG/aKSgzkkzaiBdY5GBX3FGtmKl0E9DNImc3bcw4QBC8GDObGoqct31QpHnT +H51MN/Vix3YAUsKbGtvopGygn22sLtm21Iy1lOS2QsEikPxrDedmKjGzsyi8fWFF +fWOEW1+mhS7L6oiNDm18MbAaYN6wdgkPVW0Uc+P/ftRZ1y2T2mli+99IgNQQW9Rb +7ZrHBTyCq9IK73UniVCA3yEN2ibHxaZQsvl3DpUfkKdPV1FOsvj33nTMtcubY7/P +c4n3w2M0HVSu6Ch+cJj0dy3FzYU76eInzT6B+hs2lGCIm6H4pUH8Vjx9dNMjcC4d +vctx/Mw= +-----END CERTIFICATE REQUEST----- diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-cert.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-cert.pem new file mode 120000 index 0000000..3b134b6 --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-cert.pem @@ -0,0 +1 @@ +USER-administrator@samba.example.com-S01-cert.pem \ No newline at end of file diff --git a/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-private-key.pem b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-private-key.pem new file mode 120000 index 0000000..964892e --- /dev/null +++ b/selftest/manage-ca/CA-samba.example.com/Users/administrator@samba.example.com/USER-administrator@samba.example.com-private-key.pem @@ -0,0 +1 @@ +USER-administrator@samba.example.com-S01-private-key.pem \ No newline at end of file -- 1.9.1 From 7248221d4d1166db245e8851ac5d9438b35abbe5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 01:06:05 +0100 Subject: [PATCH 097/323] selftest: mark commands in manage-CA-samba.example.com.sh as DONE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 2a96885ac706ae3e7c6fd7aaff0215f3f171bc27) --- selftest/manage-ca/manage-CA-samba.example.com.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/selftest/manage-ca/manage-CA-samba.example.com.sh b/selftest/manage-ca/manage-CA-samba.example.com.sh index 86956aa..187ea4b 100644 --- a/selftest/manage-ca/manage-CA-samba.example.com.sh +++ b/selftest/manage-ca/manage-CA-samba.example.com.sh @@ -9,10 +9,10 @@ set -x # All passwords are "1234" # -./manage-ca.sh manage-CA-samba.example.com.cnf init_ca - -./manage-ca.sh manage-CA-samba.example.com.cnf create_dc localdc.samba.example.com 0123456789ABCDEF -./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@samba.example.com - -./manage-ca.sh manage-CA-samba.example.com.cnf create_dc addc.addom.samba.example.com 0123456789ABCDEF -./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@addom.samba.example.com +# DONE # ./manage-ca.sh manage-CA-samba.example.com.cnf init_ca +# DONE # +# DONE # ./manage-ca.sh manage-CA-samba.example.com.cnf create_dc localdc.samba.example.com 0123456789ABCDEF +# DONE # ./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@samba.example.com +# DONE # +# DONE # ./manage-ca.sh manage-CA-samba.example.com.cnf create_dc addc.addom.samba.example.com 0123456789ABCDEF +# DONE # ./manage-ca.sh manage-CA-samba.example.com.cnf create_user administrator@addom.samba.example.com -- 1.9.1 From 7039e358b597e750bc2b3abd8b7cf21fb2ba2a76 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 21:21:25 +0100 Subject: [PATCH 098/323] selftest: add Samba::prepare_keyblobs() helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This copies the certificates from the samba.example.com CA if they exist. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit a6447fd6d010b525d235b894d5be62c807922cb5) --- selftest/target/Samba.pm | 105 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm index f1c4055..6ca1036 100644 --- a/selftest/target/Samba.pm +++ b/selftest/target/Samba.pm @@ -71,6 +71,111 @@ sub nss_wrapper_winbind_so_path($) { return $ret; } +sub copy_file_content($$) +{ + my ($in, $out) = @_; + open(IN, "${in}") or die("failed to open in[${in}] for reading: $!"); + open(OUT, ">${out}") or die("failed to open out[${out}] for writing: $!"); + while() { + print OUT $_; + } + close(OUT); + close(IN); +} + +sub prepare_keyblobs($) +{ + my ($ctx) = @_; + + my $cadir = "$ENV{SRCDIR_ABS}/selftest/manage-ca/CA-samba.example.com"; + my $cacert = "$cadir/Public/CA-samba.example.com-cert.pem"; + my $cacrl_pem = "$cadir/Public/CA-samba.example.com-crl.pem"; + my $dcdnsname = "$ctx->{hostname}.$ctx->{dnsname}"; + my $dcdir = "$cadir/DCs/$dcdnsname"; + my $dccert = "$dcdir/DC-$dcdnsname-cert.pem"; + my $dckey_private = "$dcdir/DC-$dcdnsname-private-key.pem"; + my $userprincipalname = "administrator\@$ctx->{dnsname}"; + my $userdir = "$cadir/Users/$userprincipalname"; + my $usercert = "$userdir/USER-$userprincipalname-cert.pem"; + my $userkey_private = "$userdir/USER-$userprincipalname-private-key.pem"; + + my $tlsdir = "$ctx->{tlsdir}"; + my $pkinitdir = "$ctx->{prefix_abs}/pkinit"; + #TLS and PKINIT crypto blobs + my $dhfile = "$tlsdir/dhparms.pem"; + my $cafile = "$tlsdir/ca.pem"; + my $crlfile = "$tlsdir/crl.pem"; + my $certfile = "$tlsdir/cert.pem"; + my $keyfile = "$tlsdir/key.pem"; + my $usercertfile = "$pkinitdir/USER-$userprincipalname-cert.pem"; + my $userkeyfile = "$pkinitdir/USER-$userprincipalname-private-key.pem"; + + mkdir($tlsdir, 0700); + mkdir($pkinitdir, 0700); + my $oldumask = umask; + umask 0077; + + # This is specified here to avoid draining entropy on every run + # generate by + # openssl dhparam -out dhparms.pem -text -2 8192 + open(DHFILE, ">$dhfile"); + print DHFILE < Date: Sat, 9 Jan 2016 21:21:25 +0100 Subject: [PATCH 099/323] selftest: use Samba::prepare_keyblobs() and use the certs from the new CA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit c321a59f267d1a997eff6f864a79437ef759adeb) --- selftest/target/Samba4.pm | 218 +--------------------------------------------- 1 file changed, 3 insertions(+), 215 deletions(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index d25e495..3e41dc1 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -272,219 +272,6 @@ sub mk_openldap($$) return ($slapd_conf_d, $pidfile); } -sub mk_keyblobs($$) -{ - my ($self, $tlsdir) = @_; - - #TLS and PKINIT crypto blobs - my $dhfile = "$tlsdir/dhparms.pem"; - my $cafile = "$tlsdir/ca.pem"; - my $certfile = "$tlsdir/cert.pem"; - my $reqkdc = "$tlsdir/req-kdc.der"; - my $kdccertfile = "$tlsdir/kdc.pem"; - my $keyfile = "$tlsdir/key.pem"; - my $adminkeyfile = "$tlsdir/adminkey.pem"; - my $reqadmin = "$tlsdir/req-admin.der"; - my $admincertfile = "$tlsdir/admincert.pem"; - my $admincertupnfile = "$tlsdir/admincertupn.pem"; - - mkdir($tlsdir, 0700); - my $oldumask = umask; - umask 0077; - - #This is specified here to avoid draining entropy on every run - open(DHFILE, ">$dhfile"); - print DHFILE <$keyfile"); - print KEYFILE <$adminkeyfile"); - - print ADMINKEYFILE <$cafile"); - print CAFILE <$certfile"); - print CERTFILE <$kdccertfile"); - print KDCCERTFILE <$admincertfile"); - print ADMINCERTFILE <$admincertupnfile"); - print ADMINCERTUPNFILE <{smb_conf}$?"); return undef; } + + Samba::prepare_keyblobs($ctx); + print CONFFILE " [global] netbios name = $ctx->{netbiosname} @@ -782,8 +572,6 @@ sub provision_raw_step1($$) "; close(CONFFILE); - $self->mk_keyblobs($ctx->{tlsdir}); - #Default the KDC IP to the server's IP if (not defined($ctx->{kdc_ipv4})) { $ctx->{kdc_ipv4} = $ctx->{ipv4}; -- 1.9.1 From ccd430d9a9026d4658cb5b9845fcf2569f653a19 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 21:21:25 +0100 Subject: [PATCH 100/323] selftest: set tls crlfile if it exist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit b2c0f71db026353060ad47fd0a85241a3df8c703) --- selftest/target/Samba4.pm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 3e41dc1..0c9dcaf 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -516,6 +516,8 @@ sub provision_raw_step1($$) } Samba::prepare_keyblobs($ctx); + my $crlfile = "$ctx->{tlsdir}/crl.pem"; + $crlfile = "" unless -e ${crlfile}; print CONFFILE " [global] @@ -535,6 +537,7 @@ sub provision_raw_step1($$) winbind separator = / interfaces = $ctx->{interfaces} tls dh params file = $ctx->{tlsdir}/dhparms.pem + tls crlfile = ${crlfile} panic action = $RealBin/gdb_backtrace \%d wins support = yes server role = $ctx->{server_role} -- 1.9.1 From a7a1fda4ec6bd122235643d8745f8108671e26dd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Jan 2016 21:21:25 +0100 Subject: [PATCH 101/323] selftest: setup information of new samba.example.com CA in the client environment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit b00c38afc6203f1e1f566db31a63cedba632dfab) --- selftest/selftest.pl | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/selftest/selftest.pl b/selftest/selftest.pl index db70246..fa2f4cd 100755 --- a/selftest/selftest.pl +++ b/selftest/selftest.pl @@ -27,6 +27,7 @@ use Cwd qw(abs_path); use lib "$RealBin"; use Subunit; use SocketWrapper; +use target::Samba; eval { require Time::HiRes; @@ -524,6 +525,42 @@ sub write_clientconf($$$) mkdir("$clientdir/ncalrpcdir", 0755); umask $mask; + my $cadir = "$ENV{SRCDIR_ABS}/selftest/manage-ca/CA-samba.example.com"; + my $cacert = "$cadir/Public/CA-samba.example.com-cert.pem"; + my $cacrl_pem = "$cadir/Public/CA-samba.example.com-crl.pem"; + my $ca_users_dir = "$cadir/Users"; + + if ( -d "$clientdir/pkinit" ) { + unlink <$clientdir/pkinit/*>; + } else { + mkdir("$clientdir/pkinit", 0700); + } + + # each user has a USER-${USER_PRINCIPAL_NAME}-cert.pem and + # USER-${USER_PRINCIPAL_NAME}-private-key.pem symlink + # We make a copy here and make the certificated easily + # accessable in the client environment. + my $mask = umask; + umask 0077; + opendir USERS, "${ca_users_dir}" or die "Could not open dir '${ca_users_dir}': $!"; + for my $d (readdir USERS) { + my $user_dir = "${ca_users_dir}/${d}"; + next if ${d} =~ /^\./; + next if (! -d "${user_dir}"); + opendir USER, "${user_dir}" or die "Could not open dir '${user_dir}': $!"; + for my $l (readdir USER) { + my $user_link = "${user_dir}/${l}"; + next if ${l} =~ /^\./; + next if (! -l "${user_link}"); + + my $dest = "${clientdir}/pkinit/${l}"; + Samba::copy_file_content(${user_link}, ${dest}); + } + closedir USER; + } + closedir USERS; + umask $mask; + open(CF, ">$conffile"); print CF "[global]\n"; print CF "\tnetbios name = client\n"; @@ -555,6 +592,8 @@ sub write_clientconf($$$) #We don't want to run 'speed' tests for very long torture:timelimit = 1 winbind separator = / + tls cafile = ${cacert} + tls crlfile = ${cacrl_pem} "; close(CF); } -- 1.9.1 From 98d066b5ccd54d5a78441a6b7b18b13993708005 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 07:10:06 +0100 Subject: [PATCH 102/323] s3:selftest: rpc.samr.passwords.validate should run with [seal] in order to be realistic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 2c36501640207604a5c66fb582c2d5981619147e) --- source3/selftest/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index e2d9c38..03345c6 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -354,8 +354,8 @@ for t in tests: plansmbtorture4testsuite(t, "ad_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD', 'over ncacn_np ') plansmbtorture4testsuite(t, "ad_dc", 'ncacn_ip_tcp:$SERVER_IP -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') elif t == "rpc.samr.passwords.validate": - plansmbtorture4testsuite(t, "nt4_dc", 'ncacn_ip_tcp:$SERVER_IP -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') - plansmbtorture4testsuite(t, "ad_dc", 'ncacn_ip_tcp:$SERVER_IP -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') + plansmbtorture4testsuite(t, "nt4_dc", 'ncacn_ip_tcp:$SERVER_IP[seal] -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') + plansmbtorture4testsuite(t, "ad_dc", 'ncacn_ip_tcp:$SERVER_IP[seal] -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ') elif t == "smb2.durable-open" or t == "smb2.durable-v2-open" or t == "smb2.replay": plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD') plansmbtorture4testsuite(t, "ad_dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD') -- 1.9.1 From c4ad1a263032876b6eec7ffa74d4f16f6649e778 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Dec 2015 09:13:46 +0100 Subject: [PATCH 103/323] s3:test_rpcclient_samlogon.sh: test samlogon with schannel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit f9a1915238dc7a573c58dd8c7bac3637689af265) --- source3/script/tests/test_rpcclient_samlogon.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source3/script/tests/test_rpcclient_samlogon.sh b/source3/script/tests/test_rpcclient_samlogon.sh index 01af7f8..a41ae44 100755 --- a/source3/script/tests/test_rpcclient_samlogon.sh +++ b/source3/script/tests/test_rpcclient_samlogon.sh @@ -12,16 +12,21 @@ PASSWORD="$2" shift 2 ADDARGS="$*" -rpcclient_samlogon() +rpcclient_samlogon_schannel_seal() { - $VALGRIND $BINDIR/rpcclient -U% -c "samlogon $USERNAME $PASSWORD;samlogon $USERNAME $PASSWORD" $@ + $VALGRIND $BINDIR/rpcclient -U% -c "schannel;samlogon $USERNAME $PASSWORD;samlogon $USERNAME $PASSWORD" $@ } +rpcclient_samlogon_schannel_sign() +{ + $VALGRIND $BINDIR/rpcclient -U% -c "schannelsign;samlogon $USERNAME $PASSWORD;samlogon $USERNAME $PASSWORD" $@ +} incdir=`dirname $0`/../../../testprogs/blackbox . $incdir/subunit.sh testit "rpcclient dsenumdomtrusts" $VALGRIND $BINDIR/rpcclient $ADDARGS -U% -c "dsenumdomtrusts" || failed=`expr $failed + 1` testit "rpcclient getdcsitecoverage" $VALGRIND $BINDIR/rpcclient $ADDARGS -U% -c "getdcsitecoverage" || failed=`expr $failed + 1` -testit "rpcclient samlogon" rpcclient_samlogon $ADDARGS || failed=`expr $failed +1` +testit "rpcclient samlogon schannel seal" rpcclient_samlogon_schannel_seal $ADDARGS || failed=`expr $failed +1` +testit "rpcclient samlogon schannel sign" rpcclient_samlogon_schannel_sign $ADDARGS || failed=`expr $failed +1` testok $0 $failed -- 1.9.1 From dd239747a6dfdc11f7144c4dbfd6db33b8d84643 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Dec 2015 12:10:12 +0100 Subject: [PATCH 104/323] s4:torture/netlogon: add/use test_SetupCredentialsPipe() helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This create a schannel connection to netlogon, this makes the tests more realistic. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 1a7d8b8602a687ff6eef45f15f597694e94e14b1) --- source4/torture/rpc/forest_trust.c | 12 +++-- source4/torture/rpc/lsa.c | 14 ++++-- source4/torture/rpc/netlogon.c | 98 +++++++++++++++++++++++++++++++------- source4/torture/rpc/netlogon.h | 7 +++ source4/torture/rpc/remote_pac.c | 34 ++++++++----- 5 files changed, 132 insertions(+), 33 deletions(-) diff --git a/source4/torture/rpc/forest_trust.c b/source4/torture/rpc/forest_trust.c index ccb19ed..aae745f 100644 --- a/source4/torture/rpc/forest_trust.c +++ b/source4/torture/rpc/forest_trust.c @@ -516,7 +516,8 @@ static bool test_validate_trust(struct torture_context *tctx, NTSTATUS status; struct cli_credentials *credentials; struct dcerpc_binding *b; - struct dcerpc_pipe *p; + struct dcerpc_pipe *p1 = NULL; + struct dcerpc_pipe *p = NULL; struct netr_GetForestTrustInformation fr; struct lsa_ForestTrustInformation *forest_trust_info; @@ -547,7 +548,7 @@ static bool test_validate_trust(struct torture_context *tctx, trusted_dom_name, CRED_SPECIFIED); cli_credentials_set_secure_channel_type(credentials, SEC_CHAN_DOMAIN); - status = dcerpc_pipe_connect_b(tctx, &p, b, + status = dcerpc_pipe_connect_b(tctx, &p1, b, &ndr_table_netlogon, credentials, tctx->ev, tctx->lp_ctx); @@ -559,11 +560,16 @@ static bool test_validate_trust(struct torture_context *tctx, return false; } - if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES, + if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES, credentials, &creds)) { torture_comment(tctx, "test_SetupCredentials3 failed.\n"); return false; } + if (!test_SetupCredentialsPipe(p1, tctx, credentials, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + torture_comment(tctx, "test_SetupCredentialsPipe failed.\n"); + return false; + } netlogon_creds_client_authenticator(creds, &a); diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index d2180db..2bc9649 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -4137,7 +4137,8 @@ static bool check_dom_trust_pw(struct dcerpc_pipe *p, struct netr_Authenticator req_auth; struct netr_Authenticator rep_auth; struct netr_ServerPasswordSet2 s; - struct dcerpc_pipe *p2; + struct dcerpc_pipe *p1 = NULL; + struct dcerpc_pipe *p2 = NULL; NTSTATUS status; bool ok; int rc; @@ -4237,18 +4238,25 @@ static bool check_dom_trust_pw(struct dcerpc_pipe *p, status = dcerpc_parse_binding(tctx, binding, &b2); torture_assert_ntstatus_ok(tctx, status, "Bad binding string"); - status = dcerpc_pipe_connect_b(tctx, &p2, b2, + status = dcerpc_pipe_connect_b(tctx, &p1, b2, &ndr_table_netlogon, cli_credentials_init_anon(tctx), tctx->ev, tctx->lp_ctx); torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b"); - ok = check_pw_with_ServerAuthenticate3(p2, tctx, + ok = check_pw_with_ServerAuthenticate3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, server_name, incoming_creds, &creds); torture_assert_int_equal(tctx, ok, expected_result, "check_pw_with_ServerAuthenticate3"); + if (expected_result == true) { + ok = test_SetupCredentialsPipe(p1, tctx, incoming_creds, creds, + DCERPC_SIGN | DCERPC_SEAL, &p2); + torture_assert_int_equal(tctx, ok, true, + "test_SetupCredentialsPipe"); + } + TALLOC_FREE(p1); if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) { #ifdef SAMBA4_USES_HEIMDAL diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index 9f8e8f1..a9e64cf 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -359,6 +359,35 @@ bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx, return true; } +bool test_SetupCredentialsPipe(const struct dcerpc_pipe *p1, + struct torture_context *tctx, + struct cli_credentials *machine_credentials, + struct netlogon_creds_CredentialState *creds, + uint32_t additional_flags, + struct dcerpc_pipe **_p2) +{ + NTSTATUS status; + struct dcerpc_binding *b2 = NULL; + struct dcerpc_pipe *p2 = NULL; + + b2 = dcerpc_binding_dup(tctx, p1->binding); + torture_assert(tctx, b2 != NULL, "dcerpc_binding_dup"); + dcerpc_binding_set_flags(b2, + DCERPC_SCHANNEL | additional_flags, + DCERPC_AUTH_OPTIONS); + + cli_credentials_set_netlogon_creds(machine_credentials, creds); + status = dcerpc_pipe_connect_b(tctx, &p2, b2, + &ndr_table_netlogon, + machine_credentials, + tctx->ev, tctx->lp_ctx); + cli_credentials_set_netlogon_creds(machine_credentials, NULL); + torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b schannel"); + + *_p2 = p2; + return true; +} + /* try a change password for our machine account */ @@ -436,7 +465,7 @@ static bool test_SetPassword(struct torture_context *tctx, try a change password for our machine account */ static bool test_SetPassword_flags(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *machine_credentials, uint32_t negotiate_flags) { @@ -445,14 +474,20 @@ static bool test_SetPassword_flags(struct torture_context *tctx, struct netlogon_creds_CredentialState *creds; struct netr_Authenticator credential, return_authenticator; struct samr_Password new_password; - struct dcerpc_binding_handle *b = p->binding_handle; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; - if (!test_SetupCredentials2(p, tctx, negotiate_flags, + if (!test_SetupCredentials2(p1, tctx, negotiate_flags, machine_credentials, cli_credentials_get_secure_channel_type(machine_credentials), &creds)) { return false; } + if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME); @@ -532,7 +567,7 @@ static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len) try a change password for our machine account */ static bool test_SetPassword2_with_flags(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *machine_credentials, uint32_t flags) { @@ -544,11 +579,19 @@ static bool test_SetPassword2_with_flags(struct torture_context *tctx, struct samr_Password nt_hash; struct netr_Authenticator credential, return_authenticator; struct netr_CryptPassword new_password; - struct dcerpc_binding_handle *b = p->binding_handle; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; - if (!test_SetupCredentials2(p, tctx, flags, machine_credentials, cli_credentials_get_secure_channel_type(machine_credentials), &creds)) { + if (!test_SetupCredentials2(p1, tctx, flags, machine_credentials, + cli_credentials_get_secure_channel_type(machine_credentials), + &creds)) { return false; } + if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME); @@ -2507,7 +2550,7 @@ static bool test_LogonControl2Ex(struct torture_context *tctx, } static bool test_netr_GetForestTrustInformation(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *machine_credentials) { struct netr_GetForestTrustInformation r; @@ -2515,12 +2558,18 @@ static bool test_netr_GetForestTrustInformation(struct torture_context *tctx, struct netr_Authenticator a; struct netr_Authenticator return_authenticator; struct lsa_ForestTrustInformation *forest_trust_info; - struct dcerpc_binding_handle *b = p->binding_handle; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; - if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, + if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, machine_credentials, &creds)) { return false; } + if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; netlogon_creds_client_authenticator(creds, &a); @@ -3343,7 +3392,7 @@ static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx, } static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *machine_credentials, uint32_t negotiate_flags) { @@ -3356,14 +3405,20 @@ static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx, struct netr_TrustInfo *trust_info; struct netlogon_creds_CredentialState *creds; - struct dcerpc_binding_handle *b = p->binding_handle; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; struct samr_Password nt_hash; - if (!test_SetupCredentials3(p, tctx, negotiate_flags, + if (!test_SetupCredentials3(p1, tctx, negotiate_flags, machine_credentials, &creds)) { return false; } + if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; netlogon_creds_client_authenticator(creds, &a); @@ -3413,7 +3468,7 @@ static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx, } static bool test_GetDomainInfo(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *machine_credentials) { struct netr_LogonGetDomainInfo r; @@ -3436,14 +3491,20 @@ static bool test_GetDomainInfo(struct torture_context *tctx, char **spns = NULL; int num_spns = 0; char *temp_str; - struct dcerpc_binding_handle *b = p->binding_handle; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n"); - if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, + if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, machine_credentials, &creds)) { return false; } + if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; /* We won't double-check this when we are over 'local' transports */ if (dcerpc_server_name(p)) { @@ -3868,7 +3929,7 @@ static bool test_GetDomainInfo(struct torture_context *tctx, } static bool test_GetDomainInfo_async(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *machine_credentials) { NTSTATUS status; @@ -3882,6 +3943,7 @@ static bool test_GetDomainInfo_async(struct torture_context *tctx, int i; union netr_WorkstationInfo query; union netr_DomainInfo info; + struct dcerpc_pipe *p = NULL; torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT); @@ -3889,6 +3951,10 @@ static bool test_GetDomainInfo_async(struct torture_context *tctx, machine_credentials, &creds)) { return false; } + if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } ZERO_STRUCT(r); r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); diff --git a/source4/torture/rpc/netlogon.h b/source4/torture/rpc/netlogon.h index f2f2a6f..a4ab8f0 100644 --- a/source4/torture/rpc/netlogon.h +++ b/source4/torture/rpc/netlogon.h @@ -28,3 +28,10 @@ bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx, uint32_t negotiate_flags, struct cli_credentials *machine_credentials, struct netlogon_creds_CredentialState **creds_out); + +bool test_SetupCredentialsPipe(const struct dcerpc_pipe *p1, + struct torture_context *tctx, + struct cli_credentials *machine_credentials, + struct netlogon_creds_CredentialState *creds, + uint32_t additional_flags, + struct dcerpc_pipe **_p2); diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index 196d9f8f..dd44796 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -118,7 +118,7 @@ static NTSTATUS test_generate_session_info_pac(struct auth4_context *auth_ctx, /* Also happens to be a really good one-step verfication of our Kerberos stack */ static bool test_PACVerify(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *credentials, enum netr_SchannelType secure_channel_type, const char *test_machine_name, @@ -151,7 +151,8 @@ static bool test_PACVerify(struct torture_context *tctx, struct auth_session_info *session_info; struct pac_data *pac_data; - struct dcerpc_binding_handle *b = p->binding_handle; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; TALLOC_CTX *tmp_ctx = talloc_new(tctx); torture_assert(tctx, tmp_ctx != NULL, "talloc_new() failed"); @@ -175,11 +176,16 @@ static bool test_PACVerify(struct torture_context *tctx, credentials); torture_assert(tctx, server_creds, "Failed to copy of credentials"); - if (!test_SetupCredentials2(p, tctx, negotiate_flags, + if (!test_SetupCredentials2(p1, tctx, negotiate_flags, server_creds, secure_channel_type, &creds)) { return false; } + if (!test_SetupCredentialsPipe(p1, tctx, server_creds, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; auth_context = talloc_zero(tmp_ctx, struct auth4_context); torture_assert(tctx, auth_context != NULL, "talloc_new() failed"); @@ -525,14 +531,15 @@ static bool test_PACVerify_workstation_des(struct torture_context *tctx, /* Check various ways to get the PAC, in particular check the group membership and other details between the PAC from a normal kinit, S2U4Self and a SamLogon */ static bool test_S2U4Self(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p1, struct cli_credentials *credentials, enum netr_SchannelType secure_channel_type, const char *test_machine_name, uint32_t negotiate_flags) { NTSTATUS status; - struct dcerpc_binding_handle *b = p->binding_handle; + struct dcerpc_pipe *p = NULL; + struct dcerpc_binding_handle *b = NULL; struct netr_LogonSamLogon r; @@ -584,6 +591,17 @@ static bool test_S2U4Self(struct torture_context *tctx, credentials); torture_assert(tctx, server_creds, "Failed to copy of credentials"); + if (!test_SetupCredentials2(p1, tctx, negotiate_flags, + server_creds, secure_channel_type, + &creds)) { + return false; + } + if (!test_SetupCredentialsPipe(p1, tctx, server_creds, creds, + DCERPC_SIGN | DCERPC_SEAL, &p)) { + return false; + } + b = p->binding_handle; + auth_context = talloc_zero(tmp_ctx, struct auth4_context); torture_assert(tctx, auth_context != NULL, "talloc_new() failed"); @@ -744,12 +762,6 @@ static bool test_S2U4Self(struct torture_context *tctx, r.out.validation = &validation; r.out.authoritative = &authoritative; - if (!test_SetupCredentials2(p, tctx, negotiate_flags, - server_creds, secure_channel_type, - &creds)) { - return false; - } - ZERO_STRUCT(auth2); netlogon_creds_client_authenticator(creds, &auth); -- 1.9.1 From 414affcc00276ad1698fa58108df4008bae69749 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 17:24:03 +0100 Subject: [PATCH 105/323] s4:torture/rpc/samr: use DCERPC_SEAL in setup_schannel_netlogon_pipe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 26e5ef68188d2e44d42f75ed6aabf2557c9ce5ce) --- source4/torture/rpc/samr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 293b672..0c786c1 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -3257,7 +3257,8 @@ static bool setup_schannel_netlogon_pipe(struct torture_context *tctx, * with INTERNAL_ERROR */ status = dcerpc_binding_set_flags(b, - DCERPC_SCHANNEL | DCERPC_SIGN | + DCERPC_SCHANNEL | + DCERPC_SIGN | DCERPC_SEAL | DCERPC_SCHANNEL_AUTO, DCERPC_AUTH_OPTIONS); torture_assert_ntstatus_ok(tctx, status, "set flags"); -- 1.9.1 From 52d80145fbddd799a5f220f86b27d2fc0cbd0fa7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 Mar 2016 01:56:07 +0100 Subject: [PATCH 106/323] s4:torture/rpc/samlogon: use DCERPC_SEAL for netr_LogonSamLogonEx and validation level 6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 050a1d0653716fd7c166d35a7236a014bf1d1516) --- source4/torture/rpc/samlogon.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/torture/rpc/samlogon.c b/source4/torture/rpc/samlogon.c index 9000fe9..4465698 100644 --- a/source4/torture/rpc/samlogon.c +++ b/source4/torture/rpc/samlogon.c @@ -1755,7 +1755,8 @@ bool torture_rpc_samlogon(struct torture_context *torture) * with INTERNAL_ERROR */ status = dcerpc_binding_set_flags(b, - DCERPC_SCHANNEL | DCERPC_SIGN | + DCERPC_SCHANNEL | + DCERPC_SIGN | DCERPC_SEAL | DCERPC_SCHANNEL_128, DCERPC_AUTH_OPTIONS); torture_assert_ntstatus_ok(torture, status, "set flags"); -- 1.9.1 From 332351c9d4677f6436d11697ad23c68737557fd4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Mar 2016 18:09:26 +0100 Subject: [PATCH 107/323] s4:torture/rpc: correctly use torture_skip() for test_ManyGetDCName() without NCACN_NP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 50581689d924032de1765ec884dbd160652888be) --- source4/torture/rpc/netlogon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index a9e64cf..01bba97 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -4028,7 +4028,7 @@ static bool test_ManyGetDCName(struct torture_context *tctx, int i; if (p->conn->transport.transport != NCACN_NP) { - return true; + torture_skip(tctx, "test_ManyGetDCName works only with NCACN_NP"); } torture_comment(tctx, "Torturing GetDCName\n"); -- 1.9.1 From 468c05eef2933df2b3c076b4ab5142dbe7f0d458 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Mar 2016 02:55:30 +0100 Subject: [PATCH 108/323] s4:torture/rpc/schannel: don't use validation level 6 without privacy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 733ccd13209c20f8e76ae7b47e1741791c1cd6ba) --- source4/torture/rpc/schannel.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c index a72dd31..57a97f3 100644 --- a/source4/torture/rpc/schannel.c +++ b/source4/torture/rpc/schannel.c @@ -62,6 +62,7 @@ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx, struct netr_SamBaseInfo *base = NULL; const char *crypto_alg = ""; bool can_do_validation_6 = true; + enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE; if (lpcfg_client_lanman_auth(tctx->lp_ctx)) { flags |= CLI_CRED_LANMAN_AUTH; @@ -131,16 +132,26 @@ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx, } } - r.in.validation_level = 6; + dcerpc_binding_handle_auth_info(b, NULL, &auth_level); + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { + r.in.validation_level = 6; - torture_comment(tctx, - "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n", - ninfo.identity_info.account_name.string, crypto_alg, - r.in.validation_level); + torture_comment(tctx, + "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n", + ninfo.identity_info.account_name.string, crypto_alg, + r.in.validation_level); + + torture_assert_ntstatus_ok(tctx, + dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r), + "LogonSamLogonEx failed"); + } else { + torture_comment(tctx, + "Skip auth_level[%u] Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n", + auth_level, ninfo.identity_info.account_name.string, crypto_alg, + r.in.validation_level); + r.out.result = NT_STATUS_INVALID_INFO_CLASS; + } - torture_assert_ntstatus_ok(tctx, - dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r), - "LogonSamLogonEx failed"); if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) { can_do_validation_6 = false; } else { -- 1.9.1 From a1c8cfa2247da74cf4a2c08bd9d953c3f41c23a0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2015 13:01:47 +0200 Subject: [PATCH 109/323] auth/gensec: make sure gensec_security_by_auth_type() returns NULL for AUTH_TYPE_NONE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ops->auth_type == 0, means the backend doesn't support DCERPC. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit cc3dea5a8104eef2cfd1f8c05e25da186c334320) --- auth/gensec/gensec_start.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c index bb9cd18..4c43519 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -234,7 +234,13 @@ _PUBLIC_ const struct gensec_security_ops *gensec_security_by_auth_type( int i; const struct gensec_security_ops **backends; const struct gensec_security_ops *backend; - TALLOC_CTX *mem_ctx = talloc_new(gensec_security); + TALLOC_CTX *mem_ctx; + + if (auth_type == DCERPC_AUTH_TYPE_NONE) { + return NULL; + } + + mem_ctx = talloc_new(gensec_security); if (!mem_ctx) { return NULL; } -- 1.9.1 From 05a9bbbead0c6247dfa2ced6228ebff7b64b22bb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 15:08:43 +0100 Subject: [PATCH 110/323] auth/gensec: split out a gensec_verify_dcerpc_auth_level() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We only need this logic once. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 57946ac7c19c4e9bd8893c3acb9daf7c4bd02159) --- auth/gensec/gensec.c | 103 +++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/auth/gensec/gensec.c b/auth/gensec/gensec.c index 9fd5f25..e3b1352 100644 --- a/auth/gensec/gensec.c +++ b/auth/gensec/gensec.c @@ -217,6 +217,50 @@ _PUBLIC_ size_t gensec_max_update_size(struct gensec_security *gensec_security) return gensec_security->max_update_size; } +static NTSTATUS gensec_verify_dcerpc_auth_level(struct gensec_security *gensec_security) +{ + if (gensec_security->dcerpc_auth_level == 0) { + return NT_STATUS_OK; + } + + /* + * Because callers using the + * gensec_start_mech_by_auth_type() never call + * gensec_want_feature(), it isn't sensible for them + * to have to call gensec_have_feature() manually, and + * these are not points of negotiation, but are + * asserted by the client + */ + switch (gensec_security->dcerpc_auth_level) { + case DCERPC_AUTH_LEVEL_INTEGRITY: + if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + DEBUG(0,("Did not manage to negotiate mandetory feature " + "SIGN for dcerpc auth_level %u\n", + gensec_security->dcerpc_auth_level)); + return NT_STATUS_ACCESS_DENIED; + } + break; + case DCERPC_AUTH_LEVEL_PRIVACY: + if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + DEBUG(0,("Did not manage to negotiate mandetory feature " + "SIGN for dcerpc auth_level %u\n", + gensec_security->dcerpc_auth_level)); + return NT_STATUS_ACCESS_DENIED; + } + if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { + DEBUG(0,("Did not manage to negotiate mandetory feature " + "SEAL for dcerpc auth_level %u\n", + gensec_security->dcerpc_auth_level)); + return NT_STATUS_ACCESS_DENIED; + } + break; + default: + break; + } + + return NT_STATUS_OK; +} + _PUBLIC_ NTSTATUS gensec_update_ev(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, struct tevent_context *ev, @@ -261,31 +305,9 @@ _PUBLIC_ NTSTATUS gensec_update_ev(struct gensec_security *gensec_security, * these are not points of negotiation, but are * asserted by the client */ - switch (gensec_security->dcerpc_auth_level) { - case DCERPC_AUTH_LEVEL_INTEGRITY: - if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - DEBUG(0,("Did not manage to negotiate mandetory feature " - "SIGN for dcerpc auth_level %u\n", - gensec_security->dcerpc_auth_level)); - return NT_STATUS_ACCESS_DENIED; - } - break; - case DCERPC_AUTH_LEVEL_PRIVACY: - if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { - DEBUG(0,("Did not manage to negotiate mandetory feature " - "SIGN for dcerpc auth_level %u\n", - gensec_security->dcerpc_auth_level)); - return NT_STATUS_ACCESS_DENIED; - } - if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { - DEBUG(0,("Did not manage to negotiate mandetory feature " - "SEAL for dcerpc auth_level %u\n", - gensec_security->dcerpc_auth_level)); - return NT_STATUS_ACCESS_DENIED; - } - break; - default: - break; + status = gensec_verify_dcerpc_auth_level(gensec_security); + if (!NT_STATUS_IS_OK(status)) { + return status; } return NT_STATUS_OK; @@ -458,34 +480,9 @@ static void gensec_update_subreq_done(struct tevent_req *subreq) * these are not points of negotiation, but are * asserted by the client */ - switch (state->gensec_security->dcerpc_auth_level) { - case DCERPC_AUTH_LEVEL_INTEGRITY: - if (!gensec_have_feature(state->gensec_security, GENSEC_FEATURE_SIGN)) { - DEBUG(0,("Did not manage to negotiate mandetory feature " - "SIGN for dcerpc auth_level %u\n", - state->gensec_security->dcerpc_auth_level)); - tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); - return; - } - break; - case DCERPC_AUTH_LEVEL_PRIVACY: - if (!gensec_have_feature(state->gensec_security, GENSEC_FEATURE_SIGN)) { - DEBUG(0,("Did not manage to negotiate mandetory feature " - "SIGN for dcerpc auth_level %u\n", - state->gensec_security->dcerpc_auth_level)); - tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); - return; - } - if (!gensec_have_feature(state->gensec_security, GENSEC_FEATURE_SEAL)) { - DEBUG(0,("Did not manage to negotiate mandetory feature " - "SEAL for dcerpc auth_level %u\n", - state->gensec_security->dcerpc_auth_level)); - tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); - return; - } - break; - default: - break; + status = gensec_verify_dcerpc_auth_level(state->gensec_security); + if (tevent_req_nterror(req, status)) { + return; } tevent_req_done(req); -- 1.9.1 From 645a840dd1d57cbc96ca8afc0021bfc1b0c5dd39 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 111/323] s4:rpc_server: require access to the machine account credentials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even a standalone server should be selfjoined. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner (cherry picked from commit 31f07d05629bc05ef99edc86ad2a3e95ec8599f1) --- source4/rpc_server/dcesrv_auth.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 374c2e0..52fe26f 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -39,7 +39,7 @@ */ bool dcesrv_auth_bind(struct dcesrv_call_state *call) { - struct cli_credentials *server_credentials; + struct cli_credentials *server_credentials = NULL; struct ncacn_packet *pkt = &call->pkt; struct dcesrv_connection *dce_conn = call->conn; struct dcesrv_auth *auth = &dce_conn->auth_state; @@ -69,9 +69,9 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) cli_credentials_set_conf(server_credentials, call->conn->dce_ctx->lp_ctx); status = cli_credentials_set_machine_account(server_credentials, call->conn->dce_ctx->lp_ctx); if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status))); - talloc_free(server_credentials); - server_credentials = NULL; + DEBUG(1, ("Failed to obtain server credentials: %s\n", + nt_errstr(status))); + return false; } status = samba_server_gensec_start(dce_conn, call->event_ctx, -- 1.9.1 From cd419c3f458286c03c72cd26c7ae994ef6d83a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Sat, 26 Sep 2015 02:18:44 +0200 Subject: [PATCH 112/323] s4-smb_server: check for return code of cli_credentials_set_machine_account(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We keep anonymous server_credentials structure in order to let the rpc.spoolss.notify start it's test server. Pair-Programmed-With: Stefan Metzmacher BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Signed-off-by: Stefan Metzmacher (cherry picked from commit fe93a09889a854d7c93f9b349d5794bdbb9403ba) --- source4/smb_server/smb/negprot.c | 6 ++++-- source4/smb_server/smb2/negprot.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c index cdfa2b4..dfcc1a2 100644 --- a/source4/smb_server/smb/negprot.c +++ b/source4/smb_server/smb/negprot.c @@ -387,8 +387,10 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice) nt_status = cli_credentials_set_machine_account(server_credentials, req->smb_conn->lp_ctx); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(nt_status))); - talloc_free(server_credentials); - server_credentials = NULL; + /* + * We keep the server_credentials as anonymous + * this is required for the spoolss.notify test + */ } nt_status = samba_server_gensec_start(req, diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index b48b170..e654392 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -49,8 +49,10 @@ static NTSTATUS smb2srv_negprot_secblob(struct smb2srv_request *req, DATA_BLOB * nt_status = cli_credentials_set_machine_account(server_credentials, req->smb_conn->lp_ctx); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(nt_status))); - talloc_free(server_credentials); - server_credentials = NULL; + /* + * We keep the server_credentials as anonymous + * this is required for the spoolss.notify test + */ } req->smb_conn->negotiate.server_credentials = talloc_steal(req->smb_conn, server_credentials); -- 1.9.1 From 30a42c7573578d8e4166e2555885df2d6e60f588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Sat, 26 Sep 2015 02:20:50 +0200 Subject: [PATCH 113/323] s3-auth: check for return code of cli_credentials_set_machine_account(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Günther Deschner Reviewed-by: Stefan Metzmacher Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Thu Mar 17 20:43:19 CET 2016 on sn-devel-144 (cherry picked from commit c06058a99be4cf3ad3431dc263d4595ffc226fcf) --- source3/auth/auth_samba4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/auth/auth_samba4.c b/source3/auth/auth_samba4.c index e68c702..8ea05c6 100644 --- a/source3/auth/auth_samba4.c +++ b/source3/auth/auth_samba4.c @@ -252,8 +252,8 @@ static NTSTATUS prepare_gensec(const struct auth_context *auth_context, status = cli_credentials_set_machine_account(server_credentials, lp_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status))); - talloc_free(server_credentials); - server_credentials = NULL; + TALLOC_FREE(frame); + return status; } status = samba_server_gensec_start(mem_ctx, -- 1.9.1 From 7b272ee5c3af2367c99c5acafbe18d19dff94b6a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 15 Mar 2016 21:00:30 +0100 Subject: [PATCH 114/323] libsmb: Fix CID 1356312 Explicit null dereferenced BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit f50c3fb1c58700522f1b742539dab9bd9ae7fd39) --- source3/libsmb/cliconnect.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 97d0352..50d1a0c 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1361,6 +1361,11 @@ static struct tevent_req *cli_session_setup_gensec_send( size_t converted; bool ok; + if (pass == NULL) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); + return tevent_req_post(req, ev); + } + converted = strhex_to_str((char *)nt_hash.hash, sizeof(nt_hash.hash), pass, strlen(pass)); -- 1.9.1 From 977b7e09b7ead00a1e7976774b17fed534037c4f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 15 Mar 2016 20:34:27 +0100 Subject: [PATCH 115/323] libads: Fix CID 1356316 Uninitialized pointer read BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit dcaa88158e6f0a9964ad051b4062d82e9f279b8c) --- source3/libads/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index e707228..e205e9f 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -646,7 +646,7 @@ static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) { TALLOC_CTX *frame = talloc_stackframe(); - struct ads_service_principal p; + struct ads_service_principal p = {0}; struct berval *scred=NULL; int rc, i; ADS_STATUS status; -- 1.9.1 From 45ee8257b458ac2b1c942cca36050fd13c9ede2f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 15:30:00 +0100 Subject: [PATCH 116/323] s4:selftest: run rpc.netlogon.admin also over ncalrpc and ncacn_ip_tcp BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Fri Mar 18 12:39:51 CET 2016 on sn-devel-144 (cherry picked from commit e8e2386bf6bd05c60a0f897587a9a676c86dee76) --- source4/selftest/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 98d9058..eb7a54a 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -93,9 +93,9 @@ else: # add tests to this list as they start passing, so we test # that they stay passing ncacn_np_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.netlogon.admin", "rpc.handles", "rpc.samsync", "rpc.samba3-sessionkey", "rpc.samba3-getusername", "rpc.samba3-lsa", "rpc.samba3-bind", "rpc.samba3-netlogon", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] -ncalrpc_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.drsuapi", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] +ncalrpc_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.netlogon.admin", "rpc.drsuapi", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] drs_rpc_tests = smbtorture4_testsuites("drs.rpc") -ncacn_ip_tcp_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.netlogon", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext", "rpc.samr.passwords.validate"] + drs_rpc_tests +ncacn_ip_tcp_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.netlogon", "rpc.netlogon.admin", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext", "rpc.samr.passwords.validate"] + drs_rpc_tests slow_ncacn_np_tests = ["rpc.samlogon", "rpc.samr", "rpc.samr.users", "rpc.samr.large-dc", "rpc.samr.users.privileges", "rpc.samr.passwords", "rpc.samr.passwords.pwdlastset", "rpc.samr.passwords.lockout", "rpc.samr.passwords.badpwdcount"] slow_ncacn_ip_tcp_tests = ["rpc.cracknames"] -- 1.9.1 From 8a41c8cc8549da461fa1a9c47c973a4adfa8a2a8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Feb 2016 23:32:50 +0100 Subject: [PATCH 117/323] s3:rpc_server/samr: correctly handle session_extract_session_key() failures BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider (cherry picked from commit 0906d61bb2f3446483d82928b55f5b797bac4804) --- source3/rpc_server/samr/srv_samr_nt.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c index 4b4b77a..7eb06cf 100644 --- a/source3/rpc_server/samr/srv_samr_nt.c +++ b/source3/rpc_server/samr/srv_samr_nt.c @@ -5097,7 +5097,7 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, case 18: status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); if(!NT_STATUS_IS_OK(status)) { - return status; + break; } /* Used by AS/U JRA. */ status = set_user_info_18(&info->info18, @@ -5114,7 +5114,7 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, case 21: status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); if(!NT_STATUS_IS_OK(status)) { - return status; + break; } status = set_user_info_21(&info->info21, p->mem_ctx, @@ -5124,6 +5124,9 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, case 23: status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); + if(!NT_STATUS_IS_OK(status)) { + break; + } arcfour_crypt_blob(info->info23.password.data, 516, &session_key); @@ -5137,6 +5140,9 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, case 24: status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); + if(!NT_STATUS_IS_OK(status)) { + break; + } arcfour_crypt_blob(info->info24.password.data, 516, &session_key); @@ -5150,6 +5156,9 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, case 25: status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); + if(!NT_STATUS_IS_OK(status)) { + break; + } encode_or_decode_arc4_passwd_buffer( info->info25.password.data, &session_key); @@ -5163,6 +5172,9 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, case 26: status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); + if(!NT_STATUS_IS_OK(status)) { + break; + } encode_or_decode_arc4_passwd_buffer( info->info26.password.data, &session_key); -- 1.9.1 From a925531dc192d2f1eec29121b2b9794874278fe0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Mar 2016 19:41:53 +0100 Subject: [PATCH 118/323] s3:ntlm_auth: pass manage_squid_request() needs a valid struct ntlm_auth_state from within get_password() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Tue Mar 22 19:20:38 CET 2016 on sn-devel-144 (cherry picked from commit ef1ad0e122659b5ff9097f0f7046f10fc2f3ec30) --- source3/utils/ntlm_auth.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index f37cfa3..27cb416 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -228,13 +228,25 @@ static void manage_gensec_get_pw_request(enum stdio_helper_mode stdio_helper_mod static const char *get_password(struct cli_credentials *credentials) { + TALLOC_CTX *frame = talloc_stackframe(); char *password = NULL; + struct ntlm_auth_state *state; + + state = talloc_zero(frame, struct ntlm_auth_state); + if (state == NULL) { + DEBUG(0, ("squid_stream: Failed to talloc ntlm_auth_state\n")); + x_fprintf(x_stderr, "ERR\n"); + exit(1); + } + + state->mem_ctx = state; /* Ask for a password */ x_fprintf(x_stdout, "PW\n"); - manage_squid_request(NUM_HELPER_MODES /* bogus */, NULL, NULL, manage_gensec_get_pw_request, (void **)&password); + manage_squid_request(NUM_HELPER_MODES /* bogus */, NULL, state, manage_gensec_get_pw_request, (void **)&password); talloc_steal(credentials, password); + TALLOC_FREE(frame); return password; } -- 1.9.1 From f141784219c68cb36034d5696c9004529afa6f27 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 08:46:45 +0100 Subject: [PATCH 119/323] CVE-2016-2110: auth/ntlmssp: let ntlmssp_handle_neg_flags() return NTSTATUS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In future we can do a more fine granted negotiation and assert specific security features. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp_client.c | 6 +++++- auth/ntlmssp/ntlmssp_private.h | 4 ++-- auth/ntlmssp/ntlmssp_server.c | 15 ++++++++++++--- auth/ntlmssp/ntlmssp_util.c | 26 ++++++++++++++------------ 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index fe9e5d4..bf3b8c0 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -247,7 +247,11 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, DEBUG(3, ("Got challenge flags:\n")); debug_ntlmssp_flags(chal_flags); - ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key); + nt_status = ntlmssp_handle_neg_flags(ntlmssp_state, + chal_flags, "challenge"); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } if (ntlmssp_state->unicode) { if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { diff --git a/auth/ntlmssp/ntlmssp_private.h b/auth/ntlmssp/ntlmssp_private.h index 29eca35..e938e5c 100644 --- a/auth/ntlmssp/ntlmssp_private.h +++ b/auth/ntlmssp/ntlmssp_private.h @@ -59,8 +59,8 @@ NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, /* The following definitions come from auth/ntlmssp_util.c */ void debug_ntlmssp_flags(uint32_t neg_flags); -void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, - uint32_t neg_flags, bool allow_lm); +NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, + uint32_t neg_flags, const char *name); const DATA_BLOB ntlmssp_version_blob(void); /* The following definitions come from auth/ntlmssp_server.c */ diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c index 4bb2a64..513d4a6 100644 --- a/auth/ntlmssp/ntlmssp_server.c +++ b/auth/ntlmssp/ntlmssp_server.c @@ -117,7 +117,10 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security } } - ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, ntlmssp_state->allow_lm_key); + status = ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, "negotiate"); + if (!NT_STATUS_IS_OK(status)){ + return status; + } /* Ask our caller what challenge they would like in the packet */ if (auth_context->get_ntlm_challenge) { @@ -331,8 +334,14 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, talloc_steal(state, state->encrypted_session_key.data); - if (auth_flags) - ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, ntlmssp_state->allow_lm_key); + if (auth_flags != 0) { + nt_status = ntlmssp_handle_neg_flags(ntlmssp_state, + auth_flags, + "authenticate"); + if (!NT_STATUS_IS_OK(nt_status)){ + return nt_status; + } + } if (DEBUGLEVEL >= 10) { struct AUTHENTICATE_MESSAGE *authenticate = talloc( diff --git a/auth/ntlmssp/ntlmssp_util.c b/auth/ntlmssp/ntlmssp_util.c index bfe27f9..8f11df1 100644 --- a/auth/ntlmssp/ntlmssp_util.c +++ b/auth/ntlmssp/ntlmssp_util.c @@ -70,10 +70,10 @@ void debug_ntlmssp_flags(uint32_t neg_flags) debug_ntlmssp_flags_raw(4, neg_flags); } -void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, - uint32_t neg_flags, bool allow_lm) +NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, + uint32_t flags, const char *name) { - if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { + if (flags & NTLMSSP_NEGOTIATE_UNICODE) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; ntlmssp_state->unicode = true; @@ -83,7 +83,7 @@ void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->unicode = false; } - if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) { + if ((flags & NTLMSSP_NEGOTIATE_LM_KEY) && ntlmssp_state->allow_lm_key) { /* other end forcing us to use LM */ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; ntlmssp_state->use_ntlmv2 = false; @@ -91,37 +91,39 @@ void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { + if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) { + if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) { + if (!(flags & NTLMSSP_NEGOTIATE_128)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) { + if (!(flags & NTLMSSP_NEGOTIATE_56)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { + if (!(flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) { + if (!(flags & NTLMSSP_NEGOTIATE_SIGN)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN; } - if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) { + if (!(flags & NTLMSSP_NEGOTIATE_SEAL)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL; } - if ((neg_flags & NTLMSSP_REQUEST_TARGET)) { + if ((flags & NTLMSSP_REQUEST_TARGET)) { ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET; } + + return NT_STATUS_OK; } /* Does this blob looks like it could be NTLMSSP? */ -- 1.9.1 From ddbf2d5a5f432927cdf226ffc277c812a6120f42 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 11:01:24 +0100 Subject: [PATCH 120/323] CVE-2016-2110: auth/ntlmssp: maintain conf_flags and required_flags variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now give an error when required flags are missing. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/gensec_ntlmssp_server.c | 3 +++ auth/ntlmssp/ntlmssp.h | 2 ++ auth/ntlmssp/ntlmssp_client.c | 6 ++++++ auth/ntlmssp/ntlmssp_util.c | 20 ++++++++++++++++++++ 4 files changed, 31 insertions(+) diff --git a/auth/ntlmssp/gensec_ntlmssp_server.c b/auth/ntlmssp/gensec_ntlmssp_server.c index 5a57413..ede6f46 100644 --- a/auth/ntlmssp/gensec_ntlmssp_server.c +++ b/auth/ntlmssp/gensec_ntlmssp_server.c @@ -225,6 +225,9 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state, dns_domain); NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain); + ntlmssp_state->neg_flags |= ntlmssp_state->required_flags; + ntlmssp_state->conf_flags = ntlmssp_state->neg_flags; + return NT_STATUS_OK; } diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index c63c23d..31062e5 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -92,6 +92,8 @@ struct ntlmssp_state DATA_BLOB nt_resp; DATA_BLOB session_key; + uint32_t conf_flags; + uint32_t required_flags; uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */ bool force_wrap_seal; diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index bf3b8c0..c8b7c43 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -168,6 +168,9 @@ NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security, ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } + ntlmssp_state->neg_flags |= ntlmssp_state->required_flags; + ntlmssp_state->conf_flags = ntlmssp_state->neg_flags; + if (DEBUGLEVEL >= 10) { struct NEGOTIATE_MESSAGE *negotiate = talloc( ntlmssp_state, struct NEGOTIATE_MESSAGE); @@ -669,6 +672,9 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) ntlmssp_state->use_ccache = true; } + ntlmssp_state->neg_flags |= ntlmssp_state->required_flags; + ntlmssp_state->conf_flags = ntlmssp_state->neg_flags; + return NT_STATUS_OK; } diff --git a/auth/ntlmssp/ntlmssp_util.c b/auth/ntlmssp/ntlmssp_util.c index 8f11df1..262bf61 100644 --- a/auth/ntlmssp/ntlmssp_util.c +++ b/auth/ntlmssp/ntlmssp_util.c @@ -73,6 +73,8 @@ void debug_ntlmssp_flags(uint32_t neg_flags) NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, uint32_t flags, const char *name) { + uint32_t missing_flags = ntlmssp_state->required_flags; + if (flags & NTLMSSP_NEGOTIATE_UNICODE) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; @@ -123,6 +125,24 @@ NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET; } + missing_flags &= ~ntlmssp_state->neg_flags; + if (missing_flags != 0) { + HRESULT hres = HRES_SEC_E_UNSUPPORTED_FUNCTION; + NTSTATUS status = NT_STATUS(HRES_ERROR_V(hres)); + DEBUG(1, ("%s: Got %s flags[0x%08x] " + "- possible downgrade detected! " + "missing_flags[0x%08x] - %s\n", + __func__, name, + (unsigned)flags, + (unsigned)missing_flags, + nt_errstr(status))); + debug_ntlmssp_flags_raw(1, missing_flags); + DEBUGADD(4, ("neg_flags[0x%08x]\n", + (unsigned)ntlmssp_state->neg_flags)); + debug_ntlmssp_flags_raw(4, ntlmssp_state->neg_flags); + return status; + } + return NT_STATUS_OK; } -- 1.9.1 From e1dbe130c04381b00751d67c587d3e927b09c9ae Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 14:58:19 +0100 Subject: [PATCH 121/323] CVE-2016-2110: auth/ntlmssp: split allow_lm_response from allow_lm_key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/gensec_ntlmssp_server.c | 5 ++++- auth/ntlmssp/ntlmssp.h | 1 + auth/ntlmssp/ntlmssp_client.c | 8 +++++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/auth/ntlmssp/gensec_ntlmssp_server.c b/auth/ntlmssp/gensec_ntlmssp_server.c index ede6f46..9186ce9 100644 --- a/auth/ntlmssp/gensec_ntlmssp_server.c +++ b/auth/ntlmssp/gensec_ntlmssp_server.c @@ -118,7 +118,10 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE; - if (lpcfg_lanman_auth(gensec_security->settings->lp_ctx) && + ntlmssp_state->allow_lm_response = + lpcfg_lanman_auth(gensec_security->settings->lp_ctx); + + if (ntlmssp_state->allow_lm_response && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false)) { diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index 31062e5..8c254f3 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -64,6 +64,7 @@ struct ntlmssp_state bool use_ccache; bool resume_ccache; bool use_nt_response; /* Set to 'False' to debug what happens when the NT response is omited */ + bool allow_lm_response;/* The LM_RESPONSE code is not very secure... */ bool allow_lm_key; /* The LM_KEY code is not very secure... */ const char *user; diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index c8b7c43..8a7d58f 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -447,7 +447,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, if (ntlmssp_state->use_nt_response) { flags |= CLI_CRED_NTLM_AUTH; } - if (lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx)) { + if (ntlmssp_state->allow_lm_response) { flags |= CLI_CRED_LANMAN_AUTH; } @@ -474,7 +474,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, } if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - && lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx) && lm_session_key.length == 16) { + && ntlmssp_state->allow_lm_key && lm_session_key.length == 16) { DATA_BLOB new_session_key = data_blob_talloc(mem_ctx, NULL, 16); if (lm_response.length == 24) { SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data, @@ -582,7 +582,9 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) ntlmssp_state->use_nt_response = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "send_nt_reponse", true); - ntlmssp_state->allow_lm_key = (lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx) + ntlmssp_state->allow_lm_response = lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx); + + ntlmssp_state->allow_lm_key = (ntlmssp_state->allow_lm_response && (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "allow_lm_key", false) || gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false))); -- 1.9.1 From 9e82d2261e6b3e02943df1384f14d66217ccbd04 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 15:01:09 +0100 Subject: [PATCH 122/323] CVE-2016-2110: auth/ntlmssp: don't allow a downgrade from NTLMv2 to LM_AUTH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit man smb.conf says "client ntlmv2 auth = yes" the default disables, "client lanman auth = yes": ... Likewise, if the client ntlmv2 auth parameter is enabled, then only NTLMv2 logins will be attempted. ... BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp_client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 8a7d58f..839d059 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -632,6 +632,8 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) if (ntlmssp_state->use_ntlmv2) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; + ntlmssp_state->allow_lm_response = false; + ntlmssp_state->allow_lm_key = false; } if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { -- 1.9.1 From 20ee6205d4013e88a71a73fd1429438cf742c4c1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 15:06:09 +0100 Subject: [PATCH 123/323] CVE-2016-2110: auth/ntlmssp: don't let ntlmssp_handle_neg_flags() change ntlmssp_state->use_ntlmv2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ntlmssp_handle_neg_flags() can only disable flags, but not set them. All supported flags are set at start time. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/gensec_ntlmssp_server.c | 4 ++++ auth/ntlmssp/ntlmssp_client.c | 4 ++++ auth/ntlmssp/ntlmssp_util.c | 22 +++++++++++++--------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/auth/ntlmssp/gensec_ntlmssp_server.c b/auth/ntlmssp/gensec_ntlmssp_server.c index 9186ce9..1a8e66e 100644 --- a/auth/ntlmssp/gensec_ntlmssp_server.c +++ b/auth/ntlmssp/gensec_ntlmssp_server.c @@ -151,6 +151,10 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; } + if (ntlmssp_state->allow_lm_key) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; + } + if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; } diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 839d059..096d48d 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -636,6 +636,10 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) ntlmssp_state->allow_lm_key = false; } + if (ntlmssp_state->allow_lm_key) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; + } + if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { /* * We need to set this to allow a later SetPassword diff --git a/auth/ntlmssp/ntlmssp_util.c b/auth/ntlmssp/ntlmssp_util.c index 262bf61..4ae6101 100644 --- a/auth/ntlmssp/ntlmssp_util.c +++ b/auth/ntlmssp/ntlmssp_util.c @@ -85,20 +85,24 @@ NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->unicode = false; } - if ((flags & NTLMSSP_NEGOTIATE_LM_KEY) && ntlmssp_state->allow_lm_key) { - /* other end forcing us to use LM */ - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; - ntlmssp_state->use_ntlmv2 = false; - } else { + /* + * NTLMSSP_NEGOTIATE_NTLM2 (NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY) + * has priority over NTLMSSP_NEGOTIATE_LM_KEY + */ + if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; + } + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } - if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + if (!(flags & NTLMSSP_NEGOTIATE_LM_KEY)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } - if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; + if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN; } if (!(flags & NTLMSSP_NEGOTIATE_128)) { -- 1.9.1 From ddddf4fb47726a078405379e61c4cc9f28128e23 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 14:54:13 +0100 Subject: [PATCH 124/323] CVE-2016-2110: auth/ntlmssp: let gensec_ntlmssp_client_start require flags depending on the requested features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp_client.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 096d48d..1b7f87a 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -115,6 +115,8 @@ NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security, * This is compat code for older callers * which were missing the "initial_blob" */ + ntlmssp_state->neg_flags |= ntlmssp_state->required_flags; + ntlmssp_state->required_flags = 0; ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; return NT_STATUS_MORE_PROCESSING_REQUIRED; } @@ -158,14 +160,14 @@ NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security, if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { gensec_security->want_features |= GENSEC_FEATURE_SIGN; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; } if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { gensec_security->want_features |= GENSEC_FEATURE_SEAL; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL; } ntlmssp_state->neg_flags |= ntlmssp_state->required_flags; @@ -650,10 +652,10 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) * that it thinks is only used for NTLMSSP signing and * sealing. (It is actually pulled out and used directly) */ - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; } if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) { /* @@ -669,12 +671,12 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) * in a few years. As all servers should have * GENSEC_FEATURE_LDAP_STYLE by then. */ - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL; } } if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL; } if (gensec_security->want_features & GENSEC_FEATURE_NTLM_CCACHE) { ntlmssp_state->use_ccache = true; -- 1.9.1 From cc3aa6356c6d40f8fe92fdd815eed05f323a1425 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Dec 2015 14:54:13 +0100 Subject: [PATCH 125/323] CVE-2016-2110: auth/ntlmssp: let gensec_ntlmssp_client_start require NTLM2 (EXTENDED_SESSIONSECURITY) when using ntlmv2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 1b7f87a..49933cb 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -633,7 +633,7 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) } if (ntlmssp_state->use_ntlmv2) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_NTLM2; ntlmssp_state->allow_lm_response = false; ntlmssp_state->allow_lm_key = false; } -- 1.9.1 From 94c202986a5e37a97c47bc17fadb1c1ea4530706 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 14:06:18 +0100 Subject: [PATCH 126/323] CVE-2016-2110: winbindd: add new_spnego to the WINBINDD_CCACHE_NTLMAUTH response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't need to change the protocol version because: 1. An old client may provide the "initial_blob" (which was and is still ignored when going via the wbcCredentialCache() function) and the new winbindd won't use new_spnego. 2. A new client will just get a zero byte from an old winbindd. As it uses talloc_zero() to create struct winbindd_response. 3. Changing the version number would introduce problems with backports to older Samba versions. New clients which are capable of using the new_spnego field will use "negotiate_blob" instead of "initial_blob". BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- nsswitch/libwbclient/wbc_pam.c | 21 ++++++++++++++++++++- nsswitch/winbind_struct_protocol.h | 1 + source3/winbindd/winbindd_ccache_access.c | 8 ++++++-- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/nsswitch/libwbclient/wbc_pam.c b/nsswitch/libwbclient/wbc_pam.c index 672cf37..0d1b90c 100644 --- a/nsswitch/libwbclient/wbc_pam.c +++ b/nsswitch/libwbclient/wbc_pam.c @@ -1286,7 +1286,17 @@ wbcErr wbcCtxCredentialCache(struct wbcContext *ctx, } for (i=0; inum_blobs; i++) { - if (strcasecmp(params->blobs[i].name, "initial_blob") == 0) { + /* + * Older callers may used to provide the NEGOTIATE request + * as "initial_blob", but it was completely ignored by winbindd. + * + * So we keep ignoring it. + * + * A new callers that is capable to support "new_spnego", + * will provide the NEGOTIATE request as "negotiate_blob" + * instead. + */ + if (strcasecmp(params->blobs[i].name, "negotiate_blob") == 0) { if (initial_blob != NULL) { status = WBC_ERR_INVALID_PARAM; goto fail; @@ -1384,6 +1394,15 @@ wbcErr wbcCtxCredentialCache(struct wbcContext *ctx, if (!WBC_ERROR_IS_OK(status)) { goto fail; } + if (response.data.ccache_ntlm_auth.new_spnego) { + status = wbcAddNamedBlob( + &result->num_blobs, &result->blobs, "new_spnego", 0, + &response.data.ccache_ntlm_auth.new_spnego, + sizeof(response.data.ccache_ntlm_auth.new_spnego)); + if (!WBC_ERROR_IS_OK(status)) { + goto fail; + } + } *info = result; result = NULL; diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h index 0dffa4b..245162d 100644 --- a/nsswitch/winbind_struct_protocol.h +++ b/nsswitch/winbind_struct_protocol.h @@ -486,6 +486,7 @@ struct winbindd_response { struct { uint8_t session_key[16]; uint32_t auth_blob_len; /* blob in extra_data */ + uint8_t new_spnego; } ccache_ntlm_auth; struct { fstring dc_unc; diff --git a/source3/winbindd/winbindd_ccache_access.c b/source3/winbindd/winbindd_ccache_access.c index ddedf6a..039e653 100644 --- a/source3/winbindd/winbindd_ccache_access.c +++ b/source3/winbindd/winbindd_ccache_access.c @@ -50,7 +50,8 @@ static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, const DATA_BLOB challenge_msg, TALLOC_CTX *mem_ctx, DATA_BLOB *auth_msg, - uint8_t session_key[16]) + uint8_t session_key[16], + uint8_t *new_spnego) { NTSTATUS status; struct auth_generic_state *auth_generic_state = NULL; @@ -144,6 +145,8 @@ static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, memcpy(session_key, session_key_blob.data, 16); data_blob_free(&session_key_blob); *auth_msg = reply; + *new_spnego = gensec_have_feature(auth_generic_state->gensec_security, + GENSEC_FEATURE_NEW_SPNEGO); status = NT_STATUS_OK; done: @@ -272,7 +275,8 @@ void winbindd_ccache_ntlm_auth(struct winbindd_cli_state *state) result = do_ntlm_auth_with_stored_pw( name_user, name_domain, entry->pass, initial, challenge, talloc_tos(), &auth, - state->response->data.ccache_ntlm_auth.session_key); + state->response->data.ccache_ntlm_auth.session_key, + &state->response->data.ccache_ntlm_auth.new_spnego); if (!NT_STATUS_IS_OK(result)) { goto process_result; -- 1.9.1 From 16178950c26e882c2a7502649d98b7defe2d99ef Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Dec 2013 12:42:06 +0100 Subject: [PATCH 127/323] CVE-2016-2110: libcli/auth: use enum spnego_negResult instead of uint8_t MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- libcli/auth/spnego.h | 2 +- libcli/auth/spnego_parse.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libcli/auth/spnego.h b/libcli/auth/spnego.h index 539b903..73196e6 100644 --- a/libcli/auth/spnego.h +++ b/libcli/auth/spnego.h @@ -58,7 +58,7 @@ struct spnego_negTokenInit { }; struct spnego_negTokenTarg { - uint8_t negResult; + enum spnego_negResult negResult; const char *supportedMech; DATA_BLOB responseToken; DATA_BLOB mechListMIC; diff --git a/libcli/auth/spnego_parse.c b/libcli/auth/spnego_parse.c index 1b294df..1230376 100644 --- a/libcli/auth/spnego_parse.c +++ b/libcli/auth/spnego_parse.c @@ -203,7 +203,9 @@ static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, while (!asn1_has_error(asn1) && 0 < asn1_tag_remaining(asn1)) { uint8_t context; + uint8_t neg_result; char *oid; + if (!asn1_peek_uint8(asn1, &context)) { asn1_set_error(asn1); break; @@ -213,7 +215,8 @@ static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, case ASN1_CONTEXT(0): if (!asn1_start_tag(asn1, ASN1_CONTEXT(0))) return false; if (!asn1_start_tag(asn1, ASN1_ENUMERATED)) return false; - if (!asn1_read_uint8(asn1, &token->negResult)) return false; + if (!asn1_read_uint8(asn1, &neg_result)) return false; + token->negResult = neg_result; if (!asn1_end_tag(asn1)) return false; if (!asn1_end_tag(asn1)) return false; break; -- 1.9.1 From 0c6a63ae56100299e45efd2b5490aa6279fb2b37 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Dec 2013 12:42:35 +0100 Subject: [PATCH 128/323] CVE-2016-2110: libcli/auth: add SPNEGO_REQUEST_MIC to enum spnego_negResult MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is defined in http://www.ietf.org/rfc/rfc4178.txt. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- libcli/auth/spnego.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libcli/auth/spnego.h b/libcli/auth/spnego.h index 73196e6..49645e0 100644 --- a/libcli/auth/spnego.h +++ b/libcli/auth/spnego.h @@ -45,7 +45,11 @@ enum spnego_negResult { SPNEGO_ACCEPT_COMPLETED = 0, SPNEGO_ACCEPT_INCOMPLETE = 1, SPNEGO_REJECT = 2, - SPNEGO_NONE_RESULT = 3 + SPNEGO_REQUEST_MIC = 3, + /* + * The max value is 0xff (255) on the wire + */ + SPNEGO_NONE_RESULT = 256 }; struct spnego_negTokenInit { -- 1.9.1 From 16b7917ee2dd13e6013d4ddc6da1220bde3f335a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 11:42:55 +0100 Subject: [PATCH 129/323] CVE-2016-2110: auth/gensec: fix the client side of a new_spnego exchange MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even for SMB where the server provides its mech list, the client needs to remember its own mech list for the mechListMIC calculation. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/gensec/spnego.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index 0079bb8..9c5e51d 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -784,6 +784,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA const char *my_mechs[] = {NULL, NULL}; NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; + bool ok; if (!in.length) { /* client to produce negTokenInit */ @@ -846,6 +847,14 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } + ok = spnego_write_mech_types(spnego_state, + my_mechs, + &spnego_state->mech_types); + if (!ok) { + DEBUG(1, ("SPNEGO: Failed to write mechTypes\n")); + return NT_STATUS_NO_MEMORY; + } + /* set next state */ spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; spnego_state->state_position = SPNEGO_CLIENT_TARG; -- 1.9.1 From ef8e16efda7af321542e4a07e3377de91ace6972 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 11:42:55 +0100 Subject: [PATCH 130/323] CVE-2016-2110: auth/gensec: fix the client side of a spnego downgrade MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New servers response with SPNEGO_REQUEST_MIC instead of SPNEGO_ACCEPT_INCOMPLETE to a downgrade. With just KRB5 and NTLMSSP this doesn't happen, but we want to be prepared for the future. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/gensec/spnego.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index 9c5e51d..ea24308 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -970,13 +970,15 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } /* Server didn't like our choice of mech, and chose something else */ - if ((spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_INCOMPLETE) && + if (((spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_INCOMPLETE) || + (spnego.negTokenTarg.negResult == SPNEGO_REQUEST_MIC)) && spnego.negTokenTarg.supportedMech && strcmp(spnego.negTokenTarg.supportedMech, spnego_state->neg_oid) != 0) { DEBUG(3,("GENSEC SPNEGO: client preferred mech (%s) not accepted, server wants: %s\n", - gensec_get_name_by_oid(gensec_security, spnego.negTokenTarg.supportedMech), - gensec_get_name_by_oid(gensec_security, spnego_state->neg_oid))); + gensec_get_name_by_oid(gensec_security, spnego_state->neg_oid), + gensec_get_name_by_oid(gensec_security, spnego.negTokenTarg.supportedMech))); + spnego_state->no_response_expected = false; talloc_free(spnego_state->sub_sec_security); nt_status = gensec_subcontext_start(spnego_state, gensec_security, -- 1.9.1 From a4d0ed35001a3a47fe7ede2ec3bffa0dbd49f716 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 20:13:24 +0100 Subject: [PATCH 131/323] CVE-2016-2110: auth/gensec: require spnego mechListMIC exchange for new_spnego backends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This used to work more or less before, but only for krb5 with the server finishing first. With NTLMSSP and new_spnego the client will finish first. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/gensec/spnego.c | 262 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 208 insertions(+), 54 deletions(-) diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index ea24308..f47221a 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -53,6 +53,11 @@ struct spnego_state { const char *neg_oid; DATA_BLOB mech_types; + size_t num_targs; + bool mic_requested; + bool needs_mic_sign; + bool needs_mic_check; + bool done_mic_check; /* * The following is used to implement @@ -416,6 +421,11 @@ static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_ spnego_state->neg_oid = all_sec[i].oid; *unwrapped_out = data_blob_null; nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; + /* + * Indicate the downgrade and request a + * mic. + */ + spnego_state->mic_requested = true; break; } @@ -674,22 +684,27 @@ static NTSTATUS gensec_spnego_server_negTokenTarg(struct spnego_state *spnego_st /* compose reply */ spnego_out.type = SPNEGO_NEG_TOKEN_TARG; spnego_out.negTokenTarg.responseToken = unwrapped_out; - spnego_out.negTokenTarg.mechListMIC = null_data_blob; + spnego_out.negTokenTarg.mechListMIC = mech_list_mic; spnego_out.negTokenTarg.supportedMech = NULL; if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { spnego_out.negTokenTarg.supportedMech = spnego_state->neg_oid; - spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; + if (spnego_state->mic_requested) { + spnego_out.negTokenTarg.negResult = SPNEGO_REQUEST_MIC; + spnego_state->mic_requested = false; + } else { + spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; + } spnego_state->state_position = SPNEGO_SERVER_TARG; } else if (NT_STATUS_IS_OK(nt_status)) { if (unwrapped_out.data) { spnego_out.negTokenTarg.supportedMech = spnego_state->neg_oid; } spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; - spnego_out.negTokenTarg.mechListMIC = mech_list_mic; spnego_state->state_position = SPNEGO_DONE; } else { spnego_out.negTokenTarg.negResult = SPNEGO_REJECT; + spnego_out.negTokenTarg.mechListMIC = null_data_blob; DEBUG(2, ("SPNEGO login failed: %s\n", nt_errstr(nt_status))); spnego_state->state_position = SPNEGO_DONE; } @@ -700,6 +715,7 @@ static NTSTATUS gensec_spnego_server_negTokenTarg(struct spnego_state *spnego_st } spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG; + spnego_state->num_targs++; return nt_status; } @@ -892,18 +908,57 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } + spnego_state->num_targs++; + if (!spnego_state->sub_sec_security) { DEBUG(1, ("SPNEGO: Did not setup a mech in NEG_TOKEN_INIT\n")); spnego_free_data(&spnego); return NT_STATUS_INVALID_PARAMETER; } + if (spnego_state->needs_mic_check) { + if (spnego.negTokenTarg.responseToken.length != 0) { + DEBUG(1, ("SPNEGO: Did not setup a mech in NEG_TOKEN_INIT\n")); + spnego_free_data(&spnego); + return NT_STATUS_INVALID_PARAMETER; + } + + nt_status = gensec_check_packet(spnego_state->sub_sec_security, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + &spnego.negTokenTarg.mechListMIC); + if (NT_STATUS_IS_OK(nt_status)) { + spnego_state->needs_mic_check = false; + spnego_state->done_mic_check = true; + } else { + DEBUG(2,("GENSEC SPNEGO: failed to verify mechListMIC: %s\n", + nt_errstr(nt_status))); + } + goto server_response; + } + nt_status = gensec_update_ev(spnego_state->sub_sec_security, - out_mem_ctx, ev, - spnego.negTokenTarg.responseToken, - &unwrapped_out); - if (NT_STATUS_IS_OK(nt_status) && spnego.negTokenTarg.mechListMIC.length > 0) { + out_mem_ctx, ev, + spnego.negTokenTarg.responseToken, + &unwrapped_out); + if (!NT_STATUS_IS_OK(nt_status)) { + goto server_response; + } + + new_spnego = gensec_have_feature(spnego_state->sub_sec_security, + GENSEC_FEATURE_NEW_SPNEGO); + if (spnego.negTokenTarg.mechListMIC.length > 0) { new_spnego = true; + } + + if (new_spnego) { + spnego_state->needs_mic_check = true; + spnego_state->needs_mic_sign = true; + } + + if (spnego.negTokenTarg.mechListMIC.length > 0) { nt_status = gensec_check_packet(spnego_state->sub_sec_security, spnego_state->mech_types.data, spnego_state->mech_types.length, @@ -913,9 +968,14 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(2,("GENSEC SPNEGO: failed to verify mechListMIC: %s\n", nt_errstr(nt_status))); + goto server_response; } + + spnego_state->needs_mic_check = false; + spnego_state->done_mic_check = true; } - if (NT_STATUS_IS_OK(nt_status) && new_spnego) { + + if (spnego_state->needs_mic_sign) { nt_status = gensec_sign_packet(spnego_state->sub_sec_security, out_mem_ctx, spnego_state->mech_types.data, @@ -926,9 +986,16 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(2,("GENSEC SPNEGO: failed to sign mechListMIC: %s\n", nt_errstr(nt_status))); + goto server_response; } + spnego_state->needs_mic_sign = false; } + if (spnego_state->needs_mic_check) { + nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; + } + + server_response: nt_status = gensec_spnego_server_negTokenTarg(spnego_state, out_mem_ctx, nt_status, @@ -942,7 +1009,8 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA } case SPNEGO_CLIENT_TARG: { - NTSTATUS nt_status; + NTSTATUS nt_status = NT_STATUS_INTERNAL_ERROR; + if (!in.length) { return NT_STATUS_INVALID_PARAMETER; } @@ -964,11 +1032,17 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } + spnego_state->num_targs++; + if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { spnego_free_data(&spnego); return NT_STATUS_LOGON_FAILURE; } + if (spnego.negTokenTarg.negResult == SPNEGO_REQUEST_MIC) { + spnego_state->mic_requested = true; + } + /* Server didn't like our choice of mech, and chose something else */ if (((spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_INCOMPLETE) || (spnego.negTokenTarg.negResult == SPNEGO_REQUEST_MIC)) && @@ -995,64 +1069,143 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return nt_status; } - nt_status = gensec_update_ev(spnego_state->sub_sec_security, - out_mem_ctx, ev, - spnego.negTokenTarg.responseToken, - &unwrapped_out); - spnego_state->neg_oid = talloc_strdup(spnego_state, spnego.negTokenTarg.supportedMech); - } else if (spnego_state->no_response_expected) { - if (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED) { - DEBUG(3,("GENSEC SPNEGO: client GENSEC accepted, but server rejected (bad password?)\n")); - nt_status = NT_STATUS_INVALID_PARAMETER; - } else if (spnego.negTokenTarg.responseToken.length) { - DEBUG(2,("GENSEC SPNEGO: client GENSEC accepted, but server continued negotiation!\n")); - nt_status = NT_STATUS_INVALID_PARAMETER; - } else { - nt_status = NT_STATUS_OK; + spnego_state->neg_oid = talloc_strdup(spnego_state, + spnego.negTokenTarg.supportedMech); + if (spnego_state->neg_oid == NULL) { + spnego_free_data(&spnego); + return NT_STATUS_NO_MEMORY; + }; + } + + if (spnego.negTokenTarg.mechListMIC.length > 0) { + if (spnego_state->no_response_expected) { + spnego_state->needs_mic_check = true; } - if (NT_STATUS_IS_OK(nt_status) && spnego.negTokenTarg.mechListMIC.length > 0) { - nt_status = gensec_check_packet(spnego_state->sub_sec_security, - spnego_state->mech_types.data, - spnego_state->mech_types.length, - spnego_state->mech_types.data, - spnego_state->mech_types.length, - &spnego.negTokenTarg.mechListMIC); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(2,("GENSEC SPNEGO: failed to verify mechListMIC: %s\n", - nt_errstr(nt_status))); - } + } + + if (spnego_state->needs_mic_check) { + if (spnego.negTokenTarg.responseToken.length != 0) { + DEBUG(1, ("SPNEGO: Did not setup a mech in NEG_TOKEN_INIT\n")); + spnego_free_data(&spnego); + return NT_STATUS_INVALID_PARAMETER; } - } else { - bool new_spnego = false; + nt_status = gensec_check_packet(spnego_state->sub_sec_security, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + &spnego.negTokenTarg.mechListMIC); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(2,("GENSEC SPNEGO: failed to verify mechListMIC: %s\n", + nt_errstr(nt_status))); + spnego_free_data(&spnego); + return nt_status; + } + spnego_state->needs_mic_check = false; + spnego_state->done_mic_check = true; + goto client_response; + } + + if (!spnego_state->no_response_expected) { nt_status = gensec_update_ev(spnego_state->sub_sec_security, out_mem_ctx, ev, spnego.negTokenTarg.responseToken, &unwrapped_out); + if (!NT_STATUS_IS_OK(nt_status)) { + goto client_response; + } + + spnego_state->no_response_expected = true; + } else { + nt_status = NT_STATUS_OK; + } + + if (spnego_state->no_response_expected && + !spnego_state->done_mic_check) + { + bool new_spnego = false; + + new_spnego = gensec_have_feature(spnego_state->sub_sec_security, + GENSEC_FEATURE_NEW_SPNEGO); + + switch (spnego.negTokenTarg.negResult) { + case SPNEGO_ACCEPT_COMPLETED: + case SPNEGO_NONE_RESULT: + if (spnego_state->num_targs == 1) { + /* + * the first exchange doesn't require + * verification + */ + new_spnego = false; + } + break; - if (NT_STATUS_IS_OK(nt_status) - && spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED) { - new_spnego = gensec_have_feature(spnego_state->sub_sec_security, - GENSEC_FEATURE_NEW_SPNEGO); + case SPNEGO_ACCEPT_INCOMPLETE: + case SPNEGO_REQUEST_MIC: + if (spnego.negTokenTarg.mechListMIC.length > 0) { + new_spnego = true; + } + break; + default: + break; } - if (NT_STATUS_IS_OK(nt_status) && new_spnego) { - nt_status = gensec_sign_packet(spnego_state->sub_sec_security, - out_mem_ctx, - spnego_state->mech_types.data, - spnego_state->mech_types.length, - spnego_state->mech_types.data, - spnego_state->mech_types.length, - &mech_list_mic); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(2,("GENSEC SPNEGO: failed to sign mechListMIC: %s\n", - nt_errstr(nt_status))); + + if (spnego_state->mic_requested) { + bool sign; + + sign = gensec_have_feature(spnego_state->sub_sec_security, + GENSEC_FEATURE_SIGN); + if (sign) { + new_spnego = true; } } - if (NT_STATUS_IS_OK(nt_status)) { - spnego_state->no_response_expected = true; + + if (new_spnego) { + spnego_state->needs_mic_check = true; + spnego_state->needs_mic_sign = true; + } + } + + if (spnego.negTokenTarg.mechListMIC.length > 0) { + nt_status = gensec_check_packet(spnego_state->sub_sec_security, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + &spnego.negTokenTarg.mechListMIC); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(2,("GENSEC SPNEGO: failed to verify mechListMIC: %s\n", + nt_errstr(nt_status))); + spnego_free_data(&spnego); + return nt_status; + } + spnego_state->needs_mic_check = false; + spnego_state->done_mic_check = true; + } + + if (spnego_state->needs_mic_sign) { + nt_status = gensec_sign_packet(spnego_state->sub_sec_security, + out_mem_ctx, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + spnego_state->mech_types.data, + spnego_state->mech_types.length, + &mech_list_mic); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(2,("GENSEC SPNEGO: failed to sign mechListMIC: %s\n", + nt_errstr(nt_status))); + spnego_free_data(&spnego); + return nt_status; } - } + spnego_state->needs_mic_sign = false; + } + + if (spnego_state->needs_mic_check) { + nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; + } + client_response: spnego_free_data(&spnego); if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) @@ -1076,6 +1229,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } + spnego_state->num_targs++; spnego_state->state_position = SPNEGO_CLIENT_TARG; nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; } else { -- 1.9.1 From 7196c871ec87db0c8153151ad0153fb2283ec9ff Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Dec 2013 11:49:31 +0100 Subject: [PATCH 132/323] CVE-2016-2110: auth/gensec: add gensec_may_reset_crypto() infrastructure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [MS-SPNG] requires the NTLMSSP RC4 states to be reset after the SPNEGO exchange with mechListMic verification (new_spnego). This provides the infrastructure for this feature. The 'reset_full' parameter is needed to support the broken behavior that windows only resets the RC4 states but not the sequence numbers. Which means this functionality is completely useless... But we want to work against all windows versions... BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/gensec/gensec.c | 10 ++++++++++ auth/gensec/gensec_internal.h | 5 +++++ auth/gensec/spnego.c | 7 +++++++ 3 files changed, 22 insertions(+) diff --git a/auth/gensec/gensec.c b/auth/gensec/gensec.c index e3b1352..2a8bba8 100644 --- a/auth/gensec/gensec.c +++ b/auth/gensec/gensec.c @@ -30,6 +30,16 @@ #include "auth/gensec/gensec_internal.h" #include "librpc/gen_ndr/dcerpc.h" +_PRIVATE_ NTSTATUS gensec_may_reset_crypto(struct gensec_security *gensec_security, + bool full_reset) +{ + if (!gensec_security->ops->may_reset_crypto) { + return NT_STATUS_OK; + } + + return gensec_security->ops->may_reset_crypto(gensec_security, full_reset); +} + /* wrappers for the gensec function pointers */ diff --git a/auth/gensec/gensec_internal.h b/auth/gensec/gensec_internal.h index 2751196..5535241 100644 --- a/auth/gensec/gensec_internal.h +++ b/auth/gensec/gensec_internal.h @@ -47,6 +47,8 @@ struct gensec_security_ops { NTSTATUS (*update_recv)(struct tevent_req *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out); + NTSTATUS (*may_reset_crypto)(struct gensec_security *gensec_security, + bool full_reset); NTSTATUS (*seal_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx, uint8_t *data, size_t length, const uint8_t *whole_pdu, size_t pdu_length, @@ -121,4 +123,7 @@ struct gensec_critical_sizes { int sizeof_gensec_security; }; +NTSTATUS gensec_may_reset_crypto(struct gensec_security *gensec_security, + bool full_reset); + #endif /* __GENSEC_H__ */ diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c index f47221a..2922478 100644 --- a/auth/gensec/spnego.c +++ b/auth/gensec/spnego.c @@ -1431,7 +1431,14 @@ static NTSTATUS gensec_spnego_update_wrapper(struct gensec_security *gensec_secu data_blob_free(&spnego_state->in_frag); spnego_state->in_needed = 0; if (NT_STATUS_IS_OK(status)) { + bool reset_full = true; + gensec_security->child_security = spnego_state->sub_sec_security; + + reset_full = !spnego_state->done_mic_check; + + status = gensec_may_reset_crypto(spnego_state->sub_sec_security, + reset_full); } if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { -- 1.9.1 From a667496b532aee62208f3284a2df79b022bfdba3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Dec 2013 11:27:27 +0100 Subject: [PATCH 133/323] CVE-2016-2110: auth/ntlmssp: call ntlmssp_sign_init if we provide GENSEC_FEATURE_SIGN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's important to check if got the GENSEC_FEATURE_SIGN and if the caller wanted it. The caller may only asked for GENSEC_FEATURE_SESSION_KEY which implicitly negotiates NTLMSSP_NEGOTIATE_SIGN, which might indicate GENSEC_FEATURE_SIGN to the SPNEGO glue code. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp_client.c | 2 +- auth/ntlmssp/ntlmssp_server.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index 49933cb..e91692b 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -538,7 +538,7 @@ done: ntlmssp_state->expected_state = NTLMSSP_DONE; - if (gensec_security->want_features & (GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)) { + if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { nt_status = ntlmssp_sign_init(ntlmssp_state); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c index 513d4a6..7013df7 100644 --- a/auth/ntlmssp/ntlmssp_server.c +++ b/auth/ntlmssp/ntlmssp_server.c @@ -598,7 +598,7 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security, talloc_steal(ntlmssp_state, session_key.data); } - if (ntlmssp_state->session_key.length) { + if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { nt_status = ntlmssp_sign_init(ntlmssp_state); } -- 1.9.1 From 66690a305ce480de83d0e5e19145d44884cf61c0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Dec 2013 11:49:31 +0100 Subject: [PATCH 134/323] CVE-2016-2110: auth/ntlmssp: implement gensec_ntlmssp_may_reset_crypto() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [MS-SPNG] requires the NTLMSSP RC4 states to be reset after the SPNEGO exchange with mechListMic verification (new_spnego). The 'reset_full' parameter is needed to support the broken behavior that windows only resets the RC4 states but not the sequence numbers. Which means this functionality is completely useless... But we want to work against all windows versions... BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp.c | 25 +++++++++++++++++++++++++ auth/ntlmssp/ntlmssp.h | 2 ++ auth/ntlmssp/ntlmssp_sign.c | 40 ++++++++++++++++++++++++++++------------ 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/auth/ntlmssp/ntlmssp.c b/auth/ntlmssp/ntlmssp.c index 091fdab..4abab88 100644 --- a/auth/ntlmssp/ntlmssp.c +++ b/auth/ntlmssp/ntlmssp.c @@ -179,6 +179,30 @@ NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, return NT_STATUS_OK; } +static NTSTATUS gensec_ntlmssp_may_reset_crypto(struct gensec_security *gensec_security, + bool full_reset) +{ + struct gensec_ntlmssp_context *gensec_ntlmssp = + talloc_get_type_abort(gensec_security->private_data, + struct gensec_ntlmssp_context); + struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; + NTSTATUS status; + bool reset_seqnums = full_reset; + + if (!gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { + return NT_STATUS_OK; + } + + status = ntlmssp_sign_reset(ntlmssp_state, reset_seqnums); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Could not reset NTLMSSP signing/sealing system (error was: %s)\n", + nt_errstr(status))); + return status; + } + + return NT_STATUS_OK; +} + static const char *gensec_ntlmssp_oids[] = { GENSEC_OID_NTLMSSP, NULL @@ -193,6 +217,7 @@ static const struct gensec_security_ops gensec_ntlmssp_security_ops = { .server_start = gensec_ntlmssp_server_start, .magic = gensec_ntlmssp_magic, .update = gensec_ntlmssp_update, + .may_reset_crypto= gensec_ntlmssp_may_reset_crypto, .sig_size = gensec_ntlmssp_sig_size, .sign_packet = gensec_ntlmssp_sign_packet, .check_packet = gensec_ntlmssp_check_packet, diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index 8c254f3..bb8807d 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -130,6 +130,8 @@ NTSTATUS ntlmssp_unwrap(struct ntlmssp_state *ntlmssp_stae, TALLOC_CTX *out_mem_ctx, const DATA_BLOB *in, DATA_BLOB *out); +NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state, + bool reset_seqnums); NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state); bool ntlmssp_blob_matches_magic(const DATA_BLOB *blob); diff --git a/auth/ntlmssp/ntlmssp_sign.c b/auth/ntlmssp/ntlmssp_sign.c index 2f8c6de..a975725 100644 --- a/auth/ntlmssp/ntlmssp_sign.c +++ b/auth/ntlmssp/ntlmssp_sign.c @@ -503,20 +503,14 @@ NTSTATUS ntlmssp_unwrap(struct ntlmssp_state *ntlmssp_state, /** Initialise the state for NTLMSSP signing. */ -NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) +NTSTATUS ntlmssp_sign_reset(struct ntlmssp_state *ntlmssp_state, + bool reset_seqnums) { DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); - if (ntlmssp_state->session_key.length < 8) { - DEBUG(3, ("NO session key, cannot intialise signing\n")); - return NT_STATUS_NO_USER_SESSION_KEY; - } - - ntlmssp_state->crypt = talloc_zero(ntlmssp_state, - union ntlmssp_crypt_state); if (ntlmssp_state->crypt == NULL) { - return NT_STATUS_NO_MEMORY; + return NT_STATUS_INVALID_PARAMETER_MIX; } if (ntlmssp_state->force_wrap_seal && @@ -606,7 +600,9 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) &ntlmssp_state->crypt->ntlm2.sending.seal_state); /* SEND: seq num */ - ntlmssp_state->crypt->ntlm2.sending.seq_num = 0; + if (reset_seqnums) { + ntlmssp_state->crypt->ntlm2.sending.seq_num = 0; + } /* RECV: sign key */ calc_ntlmv2_key(ntlmssp_state->crypt->ntlm2.receiving.sign_key, @@ -626,7 +622,9 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) &ntlmssp_state->crypt->ntlm2.receiving.seal_state); /* RECV: seq num */ - ntlmssp_state->crypt->ntlm2.receiving.seq_num = 0; + if (reset_seqnums) { + ntlmssp_state->crypt->ntlm2.receiving.seq_num = 0; + } } else { uint8_t weak_session_key[8]; DATA_BLOB seal_session_key = ntlmssp_state->session_key; @@ -676,8 +674,26 @@ NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) dump_arc4_state("NTLMv1 arc4 state:\n", &ntlmssp_state->crypt->ntlm.seal_state); - ntlmssp_state->crypt->ntlm.seq_num = 0; + if (reset_seqnums) { + ntlmssp_state->crypt->ntlm.seq_num = 0; + } } return NT_STATUS_OK; } + +NTSTATUS ntlmssp_sign_init(struct ntlmssp_state *ntlmssp_state) +{ + if (ntlmssp_state->session_key.length < 8) { + DEBUG(3, ("NO session key, cannot intialise signing\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + + ntlmssp_state->crypt = talloc_zero(ntlmssp_state, + union ntlmssp_crypt_state); + if (ntlmssp_state->crypt == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return ntlmssp_sign_reset(ntlmssp_state, true); +} -- 1.9.1 From 3fb628081bb9c18240d5d241f47727181451615a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Nov 2015 21:24:47 +0100 Subject: [PATCH 135/323] CVE-2016-2110: auth/credentials: clear the LMv2 key for NTLMv2 in cli_credentials_get_ntlm_response() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we clear CLI_CRED_LANMAN_AUTH and we should also clear the lm_response buffer and don't send it over the net. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/credentials/credentials_ntlm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/auth/credentials/credentials_ntlm.c b/auth/credentials/credentials_ntlm.c index 4e12277..3711b1e 100644 --- a/auth/credentials/credentials_ntlm.c +++ b/auth/credentials/credentials_ntlm.c @@ -110,6 +110,12 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred /* LM Key is incompatible... */ *flags &= ~CLI_CRED_LANMAN_AUTH; + if (lm_response.length != 0) { + /* + * We should not expose the lm key. + */ + memset(lm_response.data, 0, lm_response.length); + } } else if (*flags & CLI_CRED_NTLM2) { MD5_CTX md5_session_nonce_ctx; uint8_t session_nonce[16]; -- 1.9.1 From c423333e47bc8405efdac21181bf78126673fbbd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 09:29:11 +0100 Subject: [PATCH 136/323] CVE-2016-2110: auth/credentials: pass server_timestamp to cli_credentials_get_ntlm_response() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/credentials/credentials.h | 4 +++- auth/credentials/credentials_ntlm.c | 4 +++- auth/ntlmssp/ntlmssp_client.c | 5 +++-- source4/libcli/smb_composite/sesssetup.c | 2 ++ source4/torture/rpc/netlogon.c | 1 + source4/torture/rpc/remote_pac.c | 1 + source4/torture/rpc/samba3rpc.c | 2 +- source4/torture/rpc/samr.c | 1 + source4/torture/rpc/schannel.c | 2 ++ 9 files changed, 17 insertions(+), 5 deletions(-) diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index fdedd63..78dd59d 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -80,7 +80,9 @@ void cli_credentials_get_ntlm_username_domain(struct cli_credentials *cred, TALL const char **domain); NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred, TALLOC_CTX *mem_ctx, int *flags, - DATA_BLOB challenge, DATA_BLOB target_info, + DATA_BLOB challenge, + const NTTIME *server_timestamp, + DATA_BLOB target_info, DATA_BLOB *_lm_response, DATA_BLOB *_nt_response, DATA_BLOB *_lm_session_key, DATA_BLOB *_session_key); const char *cli_credentials_get_realm(struct cli_credentials *cred); diff --git a/auth/credentials/credentials_ntlm.c b/auth/credentials/credentials_ntlm.c index 3711b1e..a69add0 100644 --- a/auth/credentials/credentials_ntlm.c +++ b/auth/credentials/credentials_ntlm.c @@ -30,7 +30,9 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred, TALLOC_CTX *mem_ctx, int *flags, - DATA_BLOB challenge, DATA_BLOB target_info, + DATA_BLOB challenge, + const NTTIME *server_timestamp, + DATA_BLOB target_info, DATA_BLOB *_lm_response, DATA_BLOB *_nt_response, DATA_BLOB *_lm_session_key, DATA_BLOB *_session_key) { diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index e91692b..af4d249 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -228,6 +228,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, const char *user = NULL, *domain = NULL, *workstation = NULL; bool is_anonymous = false; const DATA_BLOB version_blob = ntlmssp_version_blob(); + const NTTIME *server_timestamp = NULL; TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx); if (!mem_ctx) { @@ -454,10 +455,10 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, } nt_status = cli_credentials_get_ntlm_response(gensec_security->credentials, mem_ctx, - &flags, challenge_blob, target_info, + &flags, challenge_blob, + server_timestamp, target_info, &lm_response, &nt_response, &lm_session_key, &session_key); - if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index e4964c1..903055f 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -332,6 +332,7 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, &flags, session->transport->negotiate.secblob, + NULL, /* server_timestamp */ names_blob, &state->setup.nt1.in.password1, &state->setup.nt1.in.password2, @@ -426,6 +427,7 @@ static NTSTATUS session_setup_old(struct composite_context *c, nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, &flags, session->transport->negotiate.secblob, + NULL, /* server_timestamp */ names_blob, &state->setup.old.in.password, NULL, diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index 01bba97..c8e864d 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -882,6 +882,7 @@ static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx, &flags, chal, + NULL, /* server_timestamp */ names_blob, &lm_resp, &nt_resp, NULL, NULL); diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index dd44796..2b72f38 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -735,6 +735,7 @@ static bool test_S2U4Self(struct torture_context *tctx, status = cli_credentials_get_ntlm_response(client_creds, tctx, &flags, chal, + NULL, /* server_timestamp */ names_blob, &lm_resp, &nt_resp, NULL, NULL); diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index 5f3f3d5..c454257 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -1192,7 +1192,7 @@ static bool schan(struct torture_context *tctx, cli_credentials_get_workstation(user_creds), cli_credentials_get_domain(user_creds)); status = cli_credentials_get_ntlm_response( - user_creds, mem_ctx, &flags, chal, names_blob, + user_creds, mem_ctx, &flags, chal, NULL, names_blob, &lm_resp, &nt_resp, NULL, NULL); if (!NT_STATUS_IS_OK(status)) { torture_comment(tctx, "cli_credentials_get_ntlm_response failed:" diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 0c786c1..dcdbb8a 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -3096,6 +3096,7 @@ static bool test_SamLogon(struct torture_context *tctx, status = cli_credentials_get_ntlm_response(test_credentials, tctx, &flags, chal, + NULL, /* server_timestamp */ names_blob, &lm_resp, &nt_resp, NULL, NULL); diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c index 57a97f3..829c969 100644 --- a/source4/torture/rpc/schannel.c +++ b/source4/torture/rpc/schannel.c @@ -87,6 +87,7 @@ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx, status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx, &flags, chal, + NULL, /* server_timestamp */ names_blob, &lm_resp, &nt_resp, NULL, NULL); @@ -853,6 +854,7 @@ static bool torture_schannel_bench_start(struct torture_schannel_bench_conn *con status = cli_credentials_get_ntlm_response(user_creds, conn->tmp, &flags, chal, + NULL, /* server_timestamp */ names_blob, &lm_resp, &nt_resp, NULL, NULL); -- 1.9.1 From 8b78da493b1cf4eafba23594690021fe20b4977a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2015 09:31:35 +0100 Subject: [PATCH 137/323] CVE-2016-2110: libcli/auth: pass server_timestamp to SMBNTLMv2encrypt_hash() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/credentials/credentials.h | 1 + auth/credentials/credentials_ntlm.c | 2 +- libcli/auth/proto.h | 1 + libcli/auth/smbencrypt.c | 36 +++++++++++++++++++++++++++--------- source4/auth/ntlm/auth_util.c | 4 +++- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 78dd59d..3779ec0 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -22,6 +22,7 @@ #ifndef __CREDENTIALS_H__ #define __CREDENTIALS_H__ +#include "../lib/util/time.h" #include "../lib/util/data_blob.h" #include "librpc/gen_ndr/misc.h" diff --git a/auth/credentials/credentials_ntlm.c b/auth/credentials/credentials_ntlm.c index a69add0..0abbb5c 100644 --- a/auth/credentials/credentials_ntlm.c +++ b/auth/credentials/credentials_ntlm.c @@ -104,7 +104,7 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred user, domain, nt_hash->hash, &challenge, - &target_info, + server_timestamp, &target_info, &lm_response, &nt_response, NULL, &session_key)) { return NT_STATUS_NO_MEMORY; diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h index c58a23f..acf39e1 100644 --- a/libcli/auth/proto.h +++ b/libcli/auth/proto.h @@ -144,6 +144,7 @@ DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, const char *user, const char *domain, const uint8_t nt_hash[16], const DATA_BLOB *server_chal, + const NTTIME *server_timestamp, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) ; diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c index e9eaadf..7ad4654 100644 --- a/libcli/auth/smbencrypt.c +++ b/libcli/auth/smbencrypt.c @@ -387,14 +387,13 @@ DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, return names_blob; } -static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLOB *names_blob) +static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, + NTTIME nttime, + const DATA_BLOB *names_blob) { uint8_t client_chal[8]; DATA_BLOB response = data_blob(NULL, 0); uint8_t long_date[8]; - NTTIME nttime; - - unix_to_nt_time(&nttime, time(NULL)); generate_random_buffer(client_chal, sizeof(client_chal)); @@ -417,6 +416,7 @@ static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLO static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx, const uint8_t ntlm_v2_hash[16], const DATA_BLOB *server_chal, + NTTIME nttime, const DATA_BLOB *names_blob) { uint8_t ntlmv2_response[16]; @@ -433,7 +433,7 @@ static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx, /* NTLMv2 */ /* generate some data to pass into the response function - including the hostname and domain name of the server */ - ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, names_blob); + ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, nttime, names_blob); /* Given that data, and the challenge from the server, generate a response */ SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response); @@ -479,6 +479,7 @@ static DATA_BLOB LMv2_generate_response(TALLOC_CTX *mem_ctx, bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, const char *user, const char *domain, const uint8_t nt_hash[16], const DATA_BLOB *server_chal, + const NTTIME *server_timestamp, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) @@ -494,8 +495,19 @@ bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, } if (nt_response) { + const NTTIME *nttime = server_timestamp; + NTTIME _now = 0; + + if (nttime == NULL) { + struct timeval tv_now = timeval_current(); + _now = timeval_to_nttime(&tv_now); + nttime = &_now; + } + *nt_response = NTLMv2_generate_response(mem_ctx, - ntlm_v2_hash, server_chal, + ntlm_v2_hash, + server_chal, + *nttime, names_blob); if (user_session_key) { *user_session_key = data_blob_talloc(mem_ctx, NULL, 16); @@ -509,8 +521,13 @@ bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, /* LMv2 */ if (lm_response) { - *lm_response = LMv2_generate_response(mem_ctx, - ntlm_v2_hash, server_chal); + if (server_timestamp != NULL) { + *lm_response = data_blob_talloc_zero(mem_ctx, 24); + } else { + *lm_response = LMv2_generate_response(mem_ctx, + ntlm_v2_hash, + server_chal); + } if (lm_session_key) { *lm_session_key = data_blob_talloc(mem_ctx, NULL, 16); @@ -535,7 +552,8 @@ bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx, E_md4hash(password, nt_hash); return SMBNTLMv2encrypt_hash(mem_ctx, - user, domain, nt_hash, server_chal, names_blob, + user, domain, nt_hash, + server_chal, NULL, names_blob, lm_response, nt_response, lm_session_key, user_session_key); } diff --git a/source4/auth/ntlm/auth_util.c b/source4/auth/ntlm/auth_util.c index 16977fa..3e5a0da 100644 --- a/source4/auth/ntlm/auth_util.c +++ b/source4/auth/ntlm/auth_util.c @@ -350,7 +350,9 @@ NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_conte if (!SMBNTLMv2encrypt_hash(user_info_temp, user_info_in->client.account_name, user_info_in->client.domain_name, - user_info_in->password.hash.nt->hash, &chall_blob, + user_info_in->password.hash.nt->hash, + &chall_blob, + NULL, /* server_timestamp */ &names_blob, &lmv2_response, &ntlmv2_response, &lmv2_session_key, &ntlmv2_session_key)) { -- 1.9.1 From c990c6878ba288d05bc65666592db3b3e6149b5d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 30 Nov 2015 09:13:14 +0100 Subject: [PATCH 138/323] CVE-2016-2110: ntlmssp.idl: add NTLMSSP_MIC_{OFFSET,SIZE} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- librpc/idl/ntlmssp.idl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/librpc/idl/ntlmssp.idl b/librpc/idl/ntlmssp.idl index 15c700e..f041e32 100644 --- a/librpc/idl/ntlmssp.idl +++ b/librpc/idl/ntlmssp.idl @@ -244,9 +244,12 @@ interface ntlmssp [default] NTLMv2_RESPONSE v2; } ntlmssp_NTLM_RESPONSE; + const int NTLMSSP_MIC_OFFSET = 72; + const int NTLMSSP_MIC_SIZE = 16; + typedef [flag(NDR_PAHEX)] struct { - uint8 MIC[16]; - } MIC; + uint8 MIC[NTLMSSP_MIC_SIZE]; + } ntlmssp_MIC; /* [MS-NLMP] 2.2.1.3 AUTHENTICATE_MESSAGE */ @@ -275,7 +278,7 @@ interface ntlmssp [switch_is(NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)] ntlmssp_Version Version; /* MIC (Message Integrity) is only included when the client has * sent a timestap Av struct in the CHALLENGE_MESSAGE AvPair */ - /* [flag(NDR_REMAINING)] MIC mic; */ + /* [flag(NDR_REMAINING)] ntlmssp_MIC mic; */ } AUTHENTICATE_MESSAGE; /* NTLMSSP signature version */ -- 1.9.1 From 8f92c2623d6b7a6d064259008aceb5f83e18f9ba Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Nov 2015 16:02:58 +0100 Subject: [PATCH 139/323] CVE-2016-2110: auth/ntlmssp: implement new_spnego support including MIC checking (as server) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now include a MsvAvTimestamp in our target info as indication for the client to include a NTLMSSP_MIC in the AUTH_MESSAGE. If the client uses NTLMv2 we check NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE and require a valid MIC. This is still disabled if the "map to guest" feature is used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/gensec_ntlmssp.c | 9 + auth/ntlmssp/gensec_ntlmssp_server.c | 23 ++- auth/ntlmssp/ntlmssp.h | 6 + auth/ntlmssp/ntlmssp_server.c | 341 ++++++++++++++++++++++++++++++++++- 4 files changed, 367 insertions(+), 12 deletions(-) diff --git a/auth/ntlmssp/gensec_ntlmssp.c b/auth/ntlmssp/gensec_ntlmssp.c index 5672589..329d8eb 100644 --- a/auth/ntlmssp/gensec_ntlmssp.c +++ b/auth/ntlmssp/gensec_ntlmssp.c @@ -105,6 +105,15 @@ bool gensec_ntlmssp_have_feature(struct gensec_security *gensec_security, if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) { return true; } + if (feature & GENSEC_FEATURE_NEW_SPNEGO) { + if (!ntlmssp_state->session_key.length) { + return false; + } + if (!(ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) { + return false; + } + return ntlmssp_state->new_spnego; + } return false; } diff --git a/auth/ntlmssp/gensec_ntlmssp_server.c b/auth/ntlmssp/gensec_ntlmssp_server.c index 1a8e66e..ca19863 100644 --- a/auth/ntlmssp/gensec_ntlmssp_server.c +++ b/auth/ntlmssp/gensec_ntlmssp_server.c @@ -34,9 +34,9 @@ #include "auth/gensec/gensec_internal.h" #include "auth/common_auth.h" #include "param/param.h" +#include "param/loadparm.h" #include "libds/common/roles.h" - /** * Return the credentials of a logged on user, including session keys * etc. @@ -99,6 +99,9 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) const char *netbios_domain; const char *dns_name; const char *dns_domain; + enum server_role role; + + role = lpcfg_server_role(gensec_security->settings->lp_ctx); nt_status = gensec_ntlmssp_start(gensec_security); NT_STATUS_NOT_OK_RETURN(nt_status); @@ -128,6 +131,22 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) ntlmssp_state->allow_lm_key = true; } + if (lpcfg_map_to_guest(gensec_security->settings->lp_ctx) != NEVER_MAP_TO_GUEST) { + /* + * map to guest is not secure anyway, so + * try to make it work and don't try to + * negotiate new_spnego and MIC checking + */ + ntlmssp_state->force_old_spnego = true; + } + + if (role == ROLE_ACTIVE_DIRECTORY_DC) { + /* + * map to guest is not supported on an AD DC. + */ + ntlmssp_state->force_old_spnego = false; + } + ntlmssp_state->neg_flags = NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION; @@ -175,7 +194,7 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } - if (lpcfg_server_role(gensec_security->settings->lp_ctx) == ROLE_STANDALONE) { + if (role == ROLE_STANDALONE) { ntlmssp_state->server.is_standalone = true; } else { ntlmssp_state->server.is_standalone = false; diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index bb8807d..bc2a822 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -72,6 +72,11 @@ struct ntlmssp_state uint8_t *nt_hash; uint8_t *lm_hash; + DATA_BLOB negotiate_blob; + DATA_BLOB challenge_blob; + bool new_spnego; + bool force_old_spnego; + struct { const char *netbios_name; const char *netbios_domain; @@ -83,6 +88,7 @@ struct ntlmssp_state const char *netbios_domain; const char *dns_name; const char *dns_domain; + NTTIME challenge_endtime; struct AV_PAIR_LIST av_pair_list; } server; diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c index 7013df7..17d5ade 100644 --- a/auth/ntlmssp/ntlmssp_server.c +++ b/auth/ntlmssp/ntlmssp_server.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "lib/util/time_basic.h" #include "auth/ntlmssp/ntlmssp.h" #include "auth/ntlmssp/ntlmssp_private.h" #include "../librpc/gen_ndr/ndr_ntlmssp.h" @@ -84,6 +85,27 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security uint8_t cryptkey[8]; const char *target_name; NTSTATUS status; + struct timeval tv_now = timeval_current(); + /* + * See [MS-NLMP] + * + * Windows NT 4.0, windows_2000: use 30 minutes, + * Windows XP, Windows Server 2003, Windows Vista, + * Windows Server 2008, Windows 7, and Windows Server 2008 R2 + * use 36 hours. + * + * Newer systems doesn't check this, likely because the + * connectionless NTLMSSP is no longer supported. + * + * As we expect the AUTHENTICATION_MESSAGE to arrive + * directly after the NEGOTIATE_MESSAGE (typically less than + * as 1 second later). We use a hard timeout of 30 Minutes. + * + * We don't look at AUTHENTICATE_MESSAGE.NtChallengeResponse.TimeStamp + * instead we just remember our own time. + */ + uint32_t max_lifetime = 30 * 60; + struct timeval tv_end = timeval_add(&tv_now, max_lifetime, 0); /* parse the NTLMSSP packet */ #if 0 @@ -91,6 +113,12 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security #endif if (request.length) { + if (request.length > UINT16_MAX) { + DEBUG(1, ("ntlmssp_server_negotiate: reject large request of length %u\n", + (unsigned int)request.length)); + return NT_STATUS_INVALID_PARAMETER; + } + if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd", "NTLMSSP", &ntlmssp_command, @@ -141,6 +169,7 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security */ chal_flags = ntlmssp_state->neg_flags; + ntlmssp_state->server.challenge_endtime = timeval_to_nttime(&tv_end); /* get the right name to fill in as 'target' */ target_name = ntlmssp_target_name(ntlmssp_state, @@ -158,7 +187,7 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security struct AV_PAIR *pairs = NULL; uint32_t count = 5; - pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count); + pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count + 1); if (pairs == NULL) { return NT_STATUS_NO_MEMORY; } @@ -175,7 +204,16 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security pairs[3].AvId = MsvAvDnsComputerName; pairs[3].Value.AvDnsComputerName= ntlmssp_state->server.dns_name; - pairs[4].AvId = MsvAvEOL; + if (!ntlmssp_state->force_old_spnego) { + pairs[4].AvId = MsvAvTimestamp; + pairs[4].Value.AvTimestamp = + timeval_to_nttime(&tv_now); + count += 1; + + pairs[5].AvId = MsvAvEOL; + } else { + pairs[4].AvId = MsvAvEOL; + } ntlmssp_state->server.av_pair_list.count = count; ntlmssp_state->server.av_pair_list.pair = pairs; @@ -235,6 +273,18 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security data_blob_free(&struct_blob); + ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state, + request); + if (ntlmssp_state->negotiate_blob.length != request.length) { + return NT_STATUS_NO_MEMORY; + } + + ntlmssp_state->challenge_blob = data_blob_dup_talloc(ntlmssp_state, + *reply); + if (ntlmssp_state->challenge_blob.length != reply->length) { + return NT_STATUS_NO_MEMORY; + } + ntlmssp_state->expected_state = NTLMSSP_AUTH; return NT_STATUS_MORE_PROCESSING_REQUIRED; @@ -267,19 +317,24 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, struct auth4_context *auth_context = gensec_security->auth_context; uint32_t ntlmssp_command, auth_flags; NTSTATUS nt_status; - + const unsigned int version_len = 8; + DATA_BLOB version_blob = data_blob_null; + const unsigned int mic_len = NTLMSSP_MIC_SIZE; + DATA_BLOB mic_blob = data_blob_null; uint8_t session_nonce_hash[16]; - const char *parse_string; + bool ok; + struct timeval endtime; + bool expired = false; #if 0 file_save("ntlmssp_auth.dat", request.data, request.length); #endif if (ntlmssp_state->unicode) { - parse_string = "CdBBUUUBd"; + parse_string = "CdBBUUUBdbb"; } else { - parse_string = "CdBBAAABd"; + parse_string = "CdBBAAABdbb"; } /* zero these out */ @@ -292,7 +347,7 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, ntlmssp_state->client.netbios_name = NULL; /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(ntlmssp_state, &request, parse_string, + ok = msrpc_parse(ntlmssp_state, &request, parse_string, "NTLMSSP", &ntlmssp_command, &ntlmssp_state->lm_resp, @@ -301,7 +356,35 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, &ntlmssp_state->user, &ntlmssp_state->client.netbios_name, &state->encrypted_session_key, - &auth_flags)) { + &auth_flags, + &version_blob, version_len, + &mic_blob, mic_len); + if (!ok) { + DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n")); + dump_data(10, request.data, request.length); + + data_blob_free(&version_blob); + data_blob_free(&mic_blob); + + if (ntlmssp_state->unicode) { + parse_string = "CdBBUUUBd"; + } else { + parse_string = "CdBBAAABd"; + } + + ok = msrpc_parse(ntlmssp_state, &request, parse_string, + "NTLMSSP", + &ntlmssp_command, + &ntlmssp_state->lm_resp, + &ntlmssp_state->nt_resp, + &ntlmssp_state->domain, + &ntlmssp_state->user, + &ntlmssp_state->client.netbios_name, + &state->encrypted_session_key, + &auth_flags); + } + + if (!ok) { DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n")); dump_data(10, request.data, request.length); @@ -370,6 +453,194 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length); #endif + if (ntlmssp_state->nt_resp.length > 24) { + struct NTLMv2_RESPONSE v2_resp; + enum ndr_err_code err; + uint32_t i = 0; + uint32_t count = 0; + const struct AV_PAIR *flags = NULL; + const struct AV_PAIR *eol = NULL; + uint32_t av_flags = 0; + + err = ndr_pull_struct_blob(&ntlmssp_state->nt_resp, + ntlmssp_state, + &v2_resp, + (ndr_pull_flags_fn_t)ndr_pull_NTLMv2_RESPONSE); + if (!NDR_ERR_CODE_IS_SUCCESS(err)) { + nt_status = ndr_map_error2ntstatus(err); + DEBUG(1,("%s: failed to parse NTLMv2_RESPONSE of length %zu for " + "user=[%s] domain=[%s] workstation=[%s] - %s %s\n", + __func__, ntlmssp_state->nt_resp.length, + ntlmssp_state->user, ntlmssp_state->domain, + ntlmssp_state->client.netbios_name, + ndr_errstr(err), nt_errstr(nt_status))); + return nt_status; + } + + if (DEBUGLVL(10)) { + NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &v2_resp); + } + + eol = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs, + MsvAvEOL); + if (eol == NULL) { + DEBUG(1,("%s: missing MsvAvEOL for " + "user=[%s] domain=[%s] workstation=[%s]\n", + __func__, ntlmssp_state->user, ntlmssp_state->domain, + ntlmssp_state->client.netbios_name)); + return NT_STATUS_INVALID_PARAMETER; + } + + flags = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs, + MsvAvFlags); + if (flags != NULL) { + av_flags = flags->Value.AvFlags; + } + + if (av_flags & NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE) { + if (mic_blob.length != NTLMSSP_MIC_SIZE) { + DEBUG(1,("%s: mic_blob.length[%u] for " + "user=[%s] domain=[%s] workstation=[%s]\n", + __func__, + (unsigned)mic_blob.length, + ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->client.netbios_name)); + return NT_STATUS_INVALID_PARAMETER; + } + + if (request.length < + (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE)) + { + DEBUG(1,("%s: missing MIC " + "request.length[%u] for " + "user=[%s] domain=[%s] workstation=[%s]\n", + __func__, + (unsigned)request.length, + ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->client.netbios_name)); + return NT_STATUS_INVALID_PARAMETER; + } + + ntlmssp_state->new_spnego = true; + } + + count = ntlmssp_state->server.av_pair_list.count; + if (v2_resp.Challenge.AvPairs.count < count) { + return NT_STATUS_INVALID_PARAMETER; + } + + for (i = 0; i < count; i++) { + const struct AV_PAIR *sp = + &ntlmssp_state->server.av_pair_list.pair[i]; + const struct AV_PAIR *cp = NULL; + + if (sp->AvId == MsvAvEOL) { + continue; + } + + cp = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs, + sp->AvId); + if (cp == NULL) { + DEBUG(1,("%s: AvId 0x%x missing for" + "user=[%s] domain=[%s] " + "workstation=[%s]\n", + __func__, + (unsigned)sp->AvId, + ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->client.netbios_name)); + return NT_STATUS_INVALID_PARAMETER; + } + + switch (cp->AvId) { +#define CASE_STRING(v) case Msv ## v: do { \ + int cmp; \ + if (sp->Value.v == NULL) { \ + return NT_STATUS_INTERNAL_ERROR; \ + } \ + if (cp->Value.v == NULL) { \ + DEBUG(1,("%s: invalid %s " \ + "got[%s] expect[%s] for " \ + "user=[%s] domain=[%s] workstation=[%s]\n", \ + __func__, #v, \ + cp->Value.v, \ + sp->Value.v, \ + ntlmssp_state->user, \ + ntlmssp_state->domain, \ + ntlmssp_state->client.netbios_name)); \ + return NT_STATUS_INVALID_PARAMETER; \ + } \ + cmp = strcmp(cp->Value.v, sp->Value.v); \ + if (cmp != 0) { \ + DEBUG(1,("%s: invalid %s " \ + "got[%s] expect[%s] for " \ + "user=[%s] domain=[%s] workstation=[%s]\n", \ + __func__, #v, \ + cp->Value.v, \ + sp->Value.v, \ + ntlmssp_state->user, \ + ntlmssp_state->domain, \ + ntlmssp_state->client.netbios_name)); \ + return NT_STATUS_INVALID_PARAMETER; \ + } \ +} while(0); break + CASE_STRING(AvNbComputerName); + CASE_STRING(AvNbDomainName); + CASE_STRING(AvDnsComputerName); + CASE_STRING(AvDnsDomainName); + CASE_STRING(AvDnsTreeName); + case MsvAvTimestamp: + if (cp->Value.AvTimestamp != sp->Value.AvTimestamp) { + struct timeval ct; + struct timeval st; + struct timeval_buf tmp1; + struct timeval_buf tmp2; + + nttime_to_timeval(&ct, + cp->Value.AvTimestamp); + nttime_to_timeval(&st, + sp->Value.AvTimestamp); + + DEBUG(1,("%s: invalid AvTimestamp " + "got[%s] expect[%s] for " + "user=[%s] domain=[%s] " + "workstation=[%s]\n", + __func__, + timeval_str_buf(&ct, false, + true, &tmp1), + timeval_str_buf(&st, false, + true, &tmp2), + ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->client.netbios_name)); + return NT_STATUS_INVALID_PARAMETER; + } + break; + default: + /* + * This can't happen as we control + * ntlmssp_state->server.av_pair_list + */ + return NT_STATUS_INTERNAL_ERROR; + } + } + } + + nttime_to_timeval(&endtime, ntlmssp_state->server.challenge_endtime); + expired = timeval_expired(&endtime); + if (expired) { + struct timeval_buf tmp; + DEBUG(1,("%s: challenge invalid (expired %s) for " + "user=[%s] domain=[%s] workstation=[%s]\n", + __func__, + timeval_str_buf(&endtime, false, true, &tmp), + ntlmssp_state->user, ntlmssp_state->domain, + ntlmssp_state->client.netbios_name)); + return NT_STATUS_INVALID_PARAMETER; + } + /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a client challenge @@ -481,7 +752,8 @@ static NTSTATUS ntlmssp_server_check_password(struct gensec_security *gensec_sec static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security, struct gensec_ntlmssp_context *gensec_ntlmssp, - struct ntlmssp_server_auth_state *state) + struct ntlmssp_server_auth_state *state, + DATA_BLOB request) { struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; DATA_BLOB user_session_key = state->user_session_key; @@ -598,6 +870,55 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security, talloc_steal(ntlmssp_state, session_key.data); } + if (ntlmssp_state->new_spnego) { + HMACMD5Context ctx; + uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, }; + int cmp; + + hmac_md5_init_limK_to_64(ntlmssp_state->session_key.data, + ntlmssp_state->session_key.length, + &ctx); + + hmac_md5_update(ntlmssp_state->negotiate_blob.data, + ntlmssp_state->negotiate_blob.length, + &ctx); + hmac_md5_update(ntlmssp_state->challenge_blob.data, + ntlmssp_state->challenge_blob.length, + &ctx); + + /* checked were we set ntlmssp_state->new_spnego */ + SMB_ASSERT(request.length > + (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE)); + + hmac_md5_update(request.data, NTLMSSP_MIC_OFFSET, &ctx); + hmac_md5_update(mic_buffer, NTLMSSP_MIC_SIZE, &ctx); + hmac_md5_update(request.data + + (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE), + request.length - + (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE), + &ctx); + hmac_md5_final(mic_buffer, &ctx); + + cmp = memcmp(request.data + NTLMSSP_MIC_OFFSET, + mic_buffer, NTLMSSP_MIC_SIZE); + if (cmp != 0) { + DEBUG(1,("%s: invalid NTLMSSP_MIC for " + "user=[%s] domain=[%s] workstation=[%s]\n", + __func__, + ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->client.netbios_name)); + dump_data(1, request.data + NTLMSSP_MIC_OFFSET, + NTLMSSP_MIC_SIZE); + dump_data(1, mic_buffer, + NTLMSSP_MIC_SIZE); + return NT_STATUS_INVALID_PARAMETER; + } + } + + data_blob_free(&ntlmssp_state->negotiate_blob); + data_blob_free(&ntlmssp_state->challenge_blob); + if (gensec_ntlmssp_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { nt_status = ntlmssp_sign_init(ntlmssp_state); } @@ -663,7 +984,7 @@ NTSTATUS gensec_ntlmssp_server_auth(struct gensec_security *gensec_security, ntlmssp_state->check_password, the ntlmssp_server_postpath can be done in a callback */ - nt_status = ntlmssp_server_postauth(gensec_security, gensec_ntlmssp, state); + nt_status = ntlmssp_server_postauth(gensec_security, gensec_ntlmssp, state, in); TALLOC_FREE(state); return nt_status; } -- 1.9.1 From 66f93aaf5aca49cdbff225f2f22a289cf907d18d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Nov 2015 16:26:49 +0100 Subject: [PATCH 140/323] CVE-2016-2110: auth/ntlmssp: implement new_spnego support including MIC generation (as client) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now detect a MsvAvTimestamp in target info as indication of the server to support NTLMSSP_MIC in the AUTH_MESSAGE. If the client uses NTLMv2 we provide NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE and valid MIC. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/ntlmssp/ntlmssp.h | 1 + auth/ntlmssp/ntlmssp_client.c | 206 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 202 insertions(+), 5 deletions(-) diff --git a/auth/ntlmssp/ntlmssp.h b/auth/ntlmssp/ntlmssp.h index bc2a822..2412768 100644 --- a/auth/ntlmssp/ntlmssp.h +++ b/auth/ntlmssp/ntlmssp.h @@ -80,6 +80,7 @@ struct ntlmssp_state struct { const char *netbios_name; const char *netbios_domain; + struct AV_PAIR_LIST av_pair_list; } client; struct { diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c index af4d249..b419615 100644 --- a/auth/ntlmssp/ntlmssp_client.c +++ b/auth/ntlmssp/ntlmssp_client.c @@ -90,6 +90,12 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security, } } + ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state, + *out); + if (ntlmssp_state->negotiate_blob.length != out->length) { + return NT_STATUS_NO_MEMORY; + } + ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; return NT_STATUS_MORE_PROCESSING_REQUIRED; @@ -113,8 +119,15 @@ NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security, if (in.length == 0) { /* * This is compat code for older callers - * which were missing the "initial_blob" + * which were missing the "initial_blob"/"negotiate_blob". + * + * That means we can't calculate the NTLMSSP_MIC + * field correctly and need to force the + * old_spnego behaviour. */ + DEBUG(10, ("%s: in.length==%u force_old_spnego!\n", + __func__, (unsigned int)in.length)); + ntlmssp_state->force_old_spnego = true; ntlmssp_state->neg_flags |= ntlmssp_state->required_flags; ntlmssp_state->required_flags = 0; ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; @@ -187,6 +200,12 @@ NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security, } } + ntlmssp_state->negotiate_blob = data_blob_dup_talloc(ntlmssp_state, + in); + if (ntlmssp_state->negotiate_blob.length != in.length) { + return NT_STATUS_NO_MEMORY; + } + ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; return NT_STATUS_MORE_PROCESSING_REQUIRED; @@ -229,6 +248,9 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, bool is_anonymous = false; const DATA_BLOB version_blob = ntlmssp_version_blob(); const NTTIME *server_timestamp = NULL; + uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, }; + DATA_BLOB mic_blob = data_blob_const(mic_buffer, sizeof(mic_buffer)); + HMACMD5Context ctx; TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx); if (!mem_ctx) { @@ -266,7 +288,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, chal_parse_string = "CdUdbdd"; chal_parse_string_short = "CdUdb"; } - auth_gen_string = "CdBBUUUBdb"; + auth_gen_string = "CdBBUUUBdbb"; } else { if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { chal_parse_string = "CdAdbddB"; @@ -275,7 +297,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, chal_parse_string_short = "CdAdb"; } - auth_gen_string = "CdBBAAABdb"; + auth_gen_string = "CdBBAAABdbb"; } if (!msrpc_parse(mem_ctx, @@ -386,11 +408,12 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, struct wbcCredentialCacheParams params; struct wbcCredentialCacheInfo *info = NULL; struct wbcAuthErrorInfo *error = NULL; - struct wbcNamedBlob auth_blobs[1]; + struct wbcNamedBlob auth_blobs[2]; const struct wbcBlob *wbc_auth_blob = NULL; const struct wbcBlob *wbc_session_key = NULL; wbcErr wbc_status; int i; + bool new_spnego = false; params.account_name = user; params.domain_name = domain; @@ -400,6 +423,10 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, auth_blobs[0].flags = 0; auth_blobs[0].blob.data = in.data; auth_blobs[0].blob.length = in.length; + auth_blobs[1].name = "negotiate_blob"; + auth_blobs[1].flags = 0; + auth_blobs[1].blob.data = ntlmssp_state->negotiate_blob.data; + auth_blobs[1].blob.length = ntlmssp_state->negotiate_blob.length; params.num_blobs = ARRAY_SIZE(auth_blobs); params.blobs = auth_blobs; @@ -416,6 +443,9 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, if (strequal(info->blobs[i].name, "session_key")) { wbc_session_key = &info->blobs[i].blob; } + if (strequal(info->blobs[i].name, "new_spnego")) { + new_spnego = true; + } } if ((wbc_auth_blob == NULL) || (wbc_session_key == NULL)) { wbcFreeMemory(info); @@ -436,6 +466,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, wbcFreeMemory(info); return NT_STATUS_NO_MEMORY; } + ntlmssp_state->new_spnego = new_spnego; wbcFreeMemory(info); goto done; @@ -454,6 +485,150 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, flags |= CLI_CRED_LANMAN_AUTH; } + if (target_info.length != 0 && !is_anonymous) { + struct AV_PAIR *pairs = NULL; + uint32_t count = 0; + enum ndr_err_code err; + struct AV_PAIR *timestamp = NULL; + struct AV_PAIR *eol = NULL; + uint32_t i = 0; + const char *service = NULL; + const char *hostname = NULL; + + err = ndr_pull_struct_blob(&target_info, + ntlmssp_state, + &ntlmssp_state->server.av_pair_list, + (ndr_pull_flags_fn_t)ndr_pull_AV_PAIR_LIST); + if (!NDR_ERR_CODE_IS_SUCCESS(err)) { + return ndr_map_error2ntstatus(err); + } + + count = ntlmssp_state->server.av_pair_list.count; + /* + * We need room for Flags, SingleHost, + * ChannelBindings and Target + */ + pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, + count + 4); + if (pairs == NULL) { + return NT_STATUS_NO_MEMORY; + } + + for (i = 0; i < count; i++) { + pairs[i] = ntlmssp_state->server.av_pair_list.pair[i]; + } + + ntlmssp_state->client.av_pair_list.count = count; + ntlmssp_state->client.av_pair_list.pair = pairs; + + eol = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list, + MsvAvEOL); + if (eol == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + timestamp = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list, + MsvAvTimestamp); + if (timestamp != NULL) { + uint32_t sign_features = + GENSEC_FEATURE_SESSION_KEY | + GENSEC_FEATURE_SIGN | + GENSEC_FEATURE_SEAL; + + server_timestamp = ×tamp->Value.AvTimestamp; + + if (ntlmssp_state->force_old_spnego) { + sign_features = 0; + } + + if (gensec_security->want_features & sign_features) { + struct AV_PAIR *av_flags = NULL; + + av_flags = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list, + MsvAvFlags); + if (av_flags == NULL) { + av_flags = eol; + eol++; + count++; + *eol = *av_flags; + av_flags->AvId = MsvAvFlags; + av_flags->Value.AvFlags = 0; + } + + av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE; + ntlmssp_state->new_spnego = true; + } + } + + { + struct AV_PAIR *SingleHost = NULL; + + SingleHost = eol; + eol++; + count++; + *eol = *SingleHost; + + /* + * This is not really used, but we want to + * add some more random bytes and match + * Windows. + */ + SingleHost->AvId = MsvAvSingleHost; + SingleHost->Value.AvSingleHost.token_info.Flags = 0; + SingleHost->Value.AvSingleHost.token_info.TokenIL = 0; + generate_random_buffer(SingleHost->Value.AvSingleHost.token_info.MachineId, + sizeof(SingleHost->Value.AvSingleHost.token_info.MachineId)); + SingleHost->Value.AvSingleHost.remaining = data_blob_null; + } + + { + struct AV_PAIR *ChannelBindings = NULL; + + ChannelBindings = eol; + eol++; + count++; + *eol = *ChannelBindings; + + /* + * gensec doesn't support channel bindings yet, + * but we want to match Windows on the wire + */ + ChannelBindings->AvId = MsvChannelBindings; + memset(ChannelBindings->Value.ChannelBindings, 0, + sizeof(ChannelBindings->Value.ChannelBindings)); + } + + service = gensec_get_target_service(gensec_security); + hostname = gensec_get_target_hostname(gensec_security); + if (service != NULL && hostname != NULL) { + struct AV_PAIR *target = NULL; + + target = eol; + eol++; + count++; + *eol = *target; + + target->AvId = MsvAvTargetName; + target->Value.AvTargetName = talloc_asprintf(pairs, "%s/%s", + service, + hostname); + if (target->Value.AvTargetName == NULL) { + return NT_STATUS_NO_MEMORY; + } + } + + ntlmssp_state->client.av_pair_list.count = count; + ntlmssp_state->client.av_pair_list.pair = pairs; + + err = ndr_push_struct_blob(&target_info, + ntlmssp_state, + &ntlmssp_state->client.av_pair_list, + (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST); + if (!NDR_ERR_CODE_IS_SUCCESS(err)) { + return NT_STATUS_NO_MEMORY; + } + } + nt_status = cli_credentials_get_ntlm_response(gensec_security->credentials, mem_ctx, &flags, challenge_blob, server_timestamp, target_info, @@ -522,13 +697,34 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, workstation, encrypted_session_key.data, encrypted_session_key.length, ntlmssp_state->neg_flags, - version_blob.data, version_blob.length); + version_blob.data, version_blob.length, + mic_blob.data, mic_blob.length); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; } + /* + * We always include the MIC, even without: + * av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE; + * ntlmssp_state->new_spnego = true; + * + * This matches a Windows client. + */ + hmac_md5_init_limK_to_64(session_key.data, + session_key.length, + &ctx); + hmac_md5_update(ntlmssp_state->negotiate_blob.data, + ntlmssp_state->negotiate_blob.length, + &ctx); + hmac_md5_update(in.data, in.length, &ctx); + hmac_md5_update(out->data, out->length, &ctx); + hmac_md5_final(mic_buffer, &ctx); + memcpy(out->data + NTLMSSP_MIC_OFFSET, mic_buffer, NTLMSSP_MIC_SIZE); + done: + data_blob_free(&ntlmssp_state->negotiate_blob); + ntlmssp_state->session_key = session_key; talloc_steal(ntlmssp_state, session_key.data); -- 1.9.1 From d929eef40384f3d3ec994c24c2c8df77a0e19ad1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 15:11:32 +0100 Subject: [PATCH 141/323] CVE-2016-2111: auth/gensec: require DCERPC_AUTH_LEVEL_INTEGRITY or higher in schannel_update() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It doesn't make any sense to allow other auth levels. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/gensec/schannel.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c index 9b28c45..be2e94e 100644 --- a/auth/gensec/schannel.c +++ b/auth/gensec/schannel.c @@ -467,6 +467,16 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ *out = data_blob(NULL, 0); + if (gensec_security->dcerpc_auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { + switch (gensec_security->gensec_role) { + case GENSEC_CLIENT: + return NT_STATUS_INVALID_PARAMETER_MIX; + case GENSEC_SERVER: + return NT_STATUS_INVALID_PARAMETER; + } + return NT_STATUS_INTERNAL_ERROR; + } + switch (gensec_security->gensec_role) { case GENSEC_CLIENT: if (state != NULL) { -- 1.9.1 From 5c941fcfea6c4d40e315f2cf327db14a62ec9d5d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 15:10:20 +0100 Subject: [PATCH 142/323] CVE-2016-2111: auth/gensec: correctly report GENSEC_FEATURE_{SIGN,SEAL} in schannel_have_feature() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This depends on the DCERPC auth level. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- auth/gensec/schannel.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c index be2e94e..8baf803 100644 --- a/auth/gensec/schannel.c +++ b/auth/gensec/schannel.c @@ -672,9 +672,15 @@ static NTSTATUS schannel_client_start(struct gensec_security *gensec_security) static bool schannel_have_feature(struct gensec_security *gensec_security, uint32_t feature) { - if (feature & (GENSEC_FEATURE_SIGN | - GENSEC_FEATURE_SEAL)) { - return true; + if (gensec_security->dcerpc_auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { + if (feature & GENSEC_FEATURE_SIGN) { + return true; + } + } + if (gensec_security->dcerpc_auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { + if (feature & GENSEC_FEATURE_SEAL) { + return true; + } } if (feature & GENSEC_FEATURE_DCE_STYLE) { return true; -- 1.9.1 From 8639a69ce0f463e25fee13a62f974022e87e8911 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Mar 2016 15:31:23 +0100 Subject: [PATCH 143/323] CVE-2016-2111: s4:rpc_server: implement 'server schannel = yes' restriction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 49b5b2f..2f63aaeb 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -128,6 +128,8 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(dce_call->conn->dce_ctx->lp_ctx); bool reject_des_client = !allow_nt4_crypto; bool reject_md5_client = lpcfg_reject_md5_clients(dce_call->conn->dce_ctx->lp_ctx); + int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx); + bool reject_none_rpc = (schannel == true); ZERO_STRUCTP(r->out.return_credentials); *r->out.rid = 0; @@ -200,6 +202,10 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca negotiate_flags = *r->in.negotiate_flags & server_flags; + if (negotiate_flags & NETLOGON_NEG_AUTHENTICATED_RPC) { + reject_none_rpc = false; + } + if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) { reject_des_client = false; } @@ -236,6 +242,14 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca */ *r->out.negotiate_flags = negotiate_flags; + if (reject_none_rpc) { + /* schannel must be used, but client did not offer it. */ + DEBUG(0,("%s: schannel required but client failed " + "to offer it. Client was %s\n", + __func__, r->in.account_name)); + return NT_STATUS_ACCESS_DENIED; + } + switch (r->in.secure_channel_type) { case SEC_CHAN_WKSTA: case SEC_CHAN_DNS_DOMAIN: @@ -551,7 +565,8 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc { NTSTATUS nt_status; struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info; - bool schannel_global_required = false; /* Should be lpcfg_schannel_server() == true */ + int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx); + bool schannel_global_required = (schannel == true); if (schannel_global_required) { nt_status = schannel_check_required(auth_info, -- 1.9.1 From 53193baa05114f893db607bd0e406df78e4d6711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Sat, 26 Sep 2015 01:29:10 +0200 Subject: [PATCH 144/323] CVE-2016-2111: s3:rpc_server/netlogon: always go through netr_creds_server_step_check() The ensures we apply the "server schannel = yes" restrictions. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Guenther Deschner Signed-off-by: Stefan Metzmacher --- source3/rpc_server/netlogon/srv_netlog_nt.c | 40 ++++++++++------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c index e0c1b85..d5fd745 100644 --- a/source3/rpc_server/netlogon/srv_netlog_nt.c +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c @@ -2468,22 +2468,16 @@ NTSTATUS _netr_GetForestTrustInformation(struct pipes_struct *p, NTSTATUS status; struct netlogon_creds_CredentialState *creds; struct lsa_ForestTrustInformation *info, **info_ptr; - struct loadparm_context *lp_ctx; /* TODO: check server name */ - lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers()); - if (lp_ctx == NULL) { - DEBUG(0, ("loadparm_init_s3 failed\n")); - return NT_STATUS_INTERNAL_ERROR; - } - - status = schannel_check_creds_state(p->mem_ctx, lp_ctx, - r->in.computer_name, - r->in.credential, - r->out.return_authenticator, - &creds); - talloc_unlink(p->mem_ctx, lp_ctx); + become_root(); + status = netr_creds_server_step_check(p, p->mem_ctx, + r->in.computer_name, + r->in.credential, + r->out.return_authenticator, + &creds); + unbecome_root(); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -2570,22 +2564,16 @@ NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p, bool trusted; struct netr_TrustInfo *trust_info; struct pdb_trusted_domain *td; - struct loadparm_context *lp_ctx; - - lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers()); - if (lp_ctx == NULL) { - DEBUG(0, ("loadparm_init_s3 failed\n")); - return NT_STATUS_INTERNAL_ERROR; - } /* TODO: check server name */ - status = schannel_check_creds_state(p->mem_ctx, lp_ctx, - r->in.computer_name, - r->in.credential, - r->out.return_authenticator, - &creds); - talloc_unlink(p->mem_ctx, lp_ctx); + become_root(); + status = netr_creds_server_step_check(p, p->mem_ctx, + r->in.computer_name, + r->in.credential, + r->out.return_authenticator, + &creds); + unbecome_root(); if (!NT_STATUS_IS_OK(status)) { return status; } -- 1.9.1 From d662a68f27fc33021cc8fc627253beabea859385 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 13:33:17 +0200 Subject: [PATCH 145/323] CVE-2016-2111: s4:rpc_server/netlogon: require DCERPC_AUTH_LEVEL_PRIVACY for validation level 6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 2f63aaeb..778f62b 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -993,6 +993,16 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal break; case 6: + if (dce_call->conn->auth_state.auth_info == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (dce_call->conn->auth_state.auth_info->auth_level != + DCERPC_AUTH_LEVEL_PRIVACY) + { + return NT_STATUS_INVALID_PARAMETER; + } + nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx, user_info_dc, &sam3); -- 1.9.1 From 984761ffdf05f84bb8b112b5d1e779f771c22a4a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 13:33:17 +0200 Subject: [PATCH 146/323] CVE-2016-2111: s3:rpc_server/netlogon: require DCERPC_AUTH_LEVEL_PRIVACY for validation level 6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/netlogon/srv_netlog_nt.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c index d5fd745..aec0d89 100644 --- a/source3/rpc_server/netlogon/srv_netlog_nt.c +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c @@ -1719,6 +1719,14 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p, r->out.validation->sam3); break; case 6: + /* Only allow this if the pipe is protected. */ + if (p->auth.auth_level < DCERPC_AUTH_LEVEL_PRIVACY) { + DEBUG(0,("netr_Validation6: client %s not using privacy for netlogon\n", + get_remote_machine_name())); + status = NT_STATUS_INVALID_PARAMETER; + break; + } + status = serverinfo_to_SamInfo6(server_info, r->out.validation->sam6); break; -- 1.9.1 From 337463de2925bfcd6ee1a7e7b7b4abcf850d73d0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 12 Dec 2015 22:23:18 +0100 Subject: [PATCH 147/323] CVE-2016-2111: s4:torture/rpc: fix rpc.samba3.netlogon ntlmv2 test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The computer name of the NTLMv2 blob needs to match the schannel connection. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/torture/rpc/samba3rpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index c454257..9e521cd 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -1189,8 +1189,8 @@ static bool schan(struct torture_context *tctx, generate_random_buffer(chal.data, chal.length); names_blob = NTLMv2_generate_names_blob( mem_ctx, - cli_credentials_get_workstation(user_creds), - cli_credentials_get_domain(user_creds)); + cli_credentials_get_workstation(wks_creds), + cli_credentials_get_domain(wks_creds)); status = cli_credentials_get_ntlm_response( user_creds, mem_ctx, &flags, chal, NULL, names_blob, &lm_resp, &nt_resp, NULL, NULL); -- 1.9.1 From 093ce667c47e529b35437ceda980f9980f014500 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 12 Dec 2015 22:23:18 +0100 Subject: [PATCH 148/323] CVE-2016-2111: s4:torture/rpc: fix rpc.pac ntlmv2 test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The computer name of the NTLMv2 blob needs to match the schannel connection. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/torture/rpc/remote_pac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index 2b72f38..e880f80 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -729,8 +729,8 @@ static bool test_S2U4Self(struct torture_context *tctx, chal = data_blob_const(ninfo.challenge, sizeof(ninfo.challenge)); - names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(client_creds), - cli_credentials_get_domain(client_creds)); + names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(server_creds), + cli_credentials_get_domain(server_creds)); status = cli_credentials_get_ntlm_response(client_creds, tctx, &flags, -- 1.9.1 From 2d9f405dc526ab0660ba25168586e346282c7cfb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Feb 2016 19:08:31 +0100 Subject: [PATCH 149/323] CVE-2016-2111: libcli/auth: add NTLMv2_RESPONSE_verify_netlogon_creds() helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the function that prevents spoofing like Microsoft's CVE-2015-0005. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- libcli/auth/proto.h | 5 ++ libcli/auth/smbencrypt.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 138 insertions(+), 1 deletion(-) diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h index acf39e1..cc9ae33 100644 --- a/libcli/auth/proto.h +++ b/libcli/auth/proto.h @@ -155,6 +155,11 @@ bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) ; +NTSTATUS NTLMv2_RESPONSE_verify_netlogon_creds(const char *account_name, + const char *account_domain, + const DATA_BLOB response, + const struct netlogon_creds_CredentialState *creds, + const char *workgroup); /*********************************************************** encode a password buffer with a unicode password. The buffer diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c index 7ad4654..ebf6812 100644 --- a/libcli/auth/smbencrypt.c +++ b/libcli/auth/smbencrypt.c @@ -26,7 +26,7 @@ #include "../libcli/auth/msrpc_parse.h" #include "../lib/crypto/crypto.h" #include "../libcli/auth/libcli_auth.h" -#include "../librpc/gen_ndr/ntlmssp.h" +#include "../librpc/gen_ndr/ndr_ntlmssp.h" void SMBencrypt_hash(const uint8_t lm_hash[16], const uint8_t *c8, uint8_t p24[24]) { @@ -557,6 +557,138 @@ bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx, lm_response, nt_response, lm_session_key, user_session_key); } +NTSTATUS NTLMv2_RESPONSE_verify_netlogon_creds(const char *account_name, + const char *account_domain, + const DATA_BLOB response, + const struct netlogon_creds_CredentialState *creds, + const char *workgroup) +{ + TALLOC_CTX *frame = NULL; + /* RespType + HiRespType */ + static const char *magic = "\x01\x01"; + int cmp; + struct NTLMv2_RESPONSE v2_resp; + enum ndr_err_code err; + const struct AV_PAIR *av_nb_cn = NULL; + const struct AV_PAIR *av_nb_dn = NULL; + + if (response.length < 48) { + /* + * NTLMv2_RESPONSE has at least 48 bytes. + */ + return NT_STATUS_OK; + } + + cmp = memcmp(response.data + 16, magic, 2); + if (cmp != 0) { + /* + * It doesn't look like a valid NTLMv2_RESPONSE + */ + return NT_STATUS_OK; + } + + frame = talloc_stackframe(); + + err = ndr_pull_struct_blob(&response, frame, &v2_resp, + (ndr_pull_flags_fn_t)ndr_pull_NTLMv2_RESPONSE); + if (!NDR_ERR_CODE_IS_SUCCESS(err)) { + NTSTATUS status; + status = ndr_map_error2ntstatus(err); + DEBUG(2,("Failed to parse NTLMv2_RESPONSE " + "length %u - %s - %s\n", + (unsigned)response.length, + ndr_map_error2string(err), + nt_errstr(status))); + dump_data(2, response.data, response.length); + TALLOC_FREE(frame); + return status; + } + + if (DEBUGLVL(10)) { + NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &v2_resp); + } + + /* + * Make sure the netbios computer name in the + * NTLMv2_RESPONSE matches the computer name + * in the secure channel credentials for workstation + * trusts. + * + * And the netbios domain name matches our + * workgroup. + * + * This prevents workstations from requesting + * the session key of NTLMSSP sessions of clients + * to other hosts. + */ + if (creds->secure_channel_type == SEC_CHAN_WKSTA) { + av_nb_cn = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs, + MsvAvNbComputerName); + av_nb_dn = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs, + MsvAvNbDomainName); + } + + if (av_nb_cn != NULL) { + const char *v = NULL; + char *a = NULL; + size_t len; + + v = av_nb_cn->Value.AvNbComputerName; + + a = talloc_strdup(frame, creds->account_name); + if (a == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + len = strlen(a); + if (len > 0 && a[len - 1] == '$') { + a[len - 1] = '\0'; + } + + cmp = strcasecmp_m(a, v); + if (cmp != 0) { + DEBUG(2,("%s: NTLMv2_RESPONSE with " + "NbComputerName[%s] rejected " + "for user[%s\\%s] " + "against SEC_CHAN_WKSTA[%s/%s] " + "in workgroup[%s]\n", + __func__, v, + account_domain, + account_name, + creds->computer_name, + creds->account_name, + workgroup)); + TALLOC_FREE(frame); + return NT_STATUS_LOGON_FAILURE; + } + } + if (av_nb_dn != NULL) { + const char *v = NULL; + + v = av_nb_dn->Value.AvNbDomainName; + + cmp = strcasecmp_m(workgroup, v); + if (cmp != 0) { + DEBUG(2,("%s: NTLMv2_RESPONSE with " + "NbDomainName[%s] rejected " + "for user[%s\\%s] " + "against SEC_CHAN_WKSTA[%s/%s] " + "in workgroup[%s]\n", + __func__, v, + account_domain, + account_name, + creds->computer_name, + creds->account_name, + workgroup)); + TALLOC_FREE(frame); + return NT_STATUS_LOGON_FAILURE; + } + } + + TALLOC_FREE(frame); + return NT_STATUS_OK; +} + /*********************************************************** encode a password buffer with a unicode password. The buffer is filled with random data to make it harder to attack. -- 1.9.1 From 641f69205e02c13268d34af136e21c726359cf7a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 13:12:43 +0100 Subject: [PATCH 150/323] CVE-2016-2111: s4:rpc_server/netlogon: check NTLMv2_RESPONSE values for SEC_CHAN_WKSTA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prevents spoofing like Microsoft's CVE-2015-0005. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 778f62b..527718d 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -828,6 +828,8 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_check(const struct netr_LogonSamLogonE static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_LogonSamLogonEx *r, struct netlogon_creds_CredentialState *creds) { + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; + const char *workgroup = lpcfg_workgroup(lp_ctx); struct auth4_context *auth_context; struct auth_usersupplied_info *user_info; struct auth_user_info_dc *user_info_dc; @@ -898,6 +900,13 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length); user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length); + nt_status = NTLMv2_RESPONSE_verify_netlogon_creds( + user_info->client.account_name, + user_info->client.domain_name, + user_info->password.response.nt, + creds, workgroup); + NT_STATUS_NOT_OK_RETURN(nt_status); + break; -- 1.9.1 From 8102a2e07a5c66e498178ff40d774ca58afa66c9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 9 Dec 2015 13:12:43 +0100 Subject: [PATCH 151/323] CVE-2016-2111: s3:rpc_server/netlogon: check NTLMv2_RESPONSE values for SEC_CHAN_WKSTA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prevents spoofing like Microsoft's CVE-2015-0005. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/netlogon/srv_netlog_nt.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c index aec0d89..176769f 100644 --- a/source3/rpc_server/netlogon/srv_netlog_nt.c +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c @@ -1585,6 +1585,7 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p, case NetlogonNetworkTransitiveInformation: { const char *wksname = nt_workstation; + const char *workgroup = lp_workgroup(); status = make_auth_context_fixed(talloc_tos(), &auth_context, logon->network->challenge); @@ -1611,6 +1612,14 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p, logon->network->nt.length)) { status = NT_STATUS_NO_MEMORY; } + + if (NT_STATUS_IS_OK(status)) { + status = NTLMv2_RESPONSE_verify_netlogon_creds( + user_info->client.account_name, + user_info->client.domain_name, + user_info->password.response.nt, + creds, workgroup); + } break; } case NetlogonInteractiveInformation: -- 1.9.1 From d623409d63b3c612fa29c422ef9692254fefb829 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 22:24:23 +0100 Subject: [PATCH 152/323] CVE-2016-2111: s4:torture/raw: don't use ntlmv2 for dos connection in raw.samba3badpath BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/torture/raw/samba3misc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/torture/raw/samba3misc.c b/source4/torture/raw/samba3misc.c index f40a4f1..dc460b9 100644 --- a/source4/torture/raw/samba3misc.c +++ b/source4/torture/raw/samba3misc.c @@ -440,22 +440,29 @@ bool torture_samba3_badpath(struct torture_context *torture) bool ret = true; TALLOC_CTX *mem_ctx; bool nt_status_support; + bool client_ntlmv2_auth; torture_assert(torture, mem_ctx = talloc_init("torture_samba3_badpath"), "talloc_init failed"); nt_status_support = lpcfg_nt_status_support(torture->lp_ctx); + client_ntlmv2_auth = lpcfg_client_ntlmv2_auth(torture->lp_ctx); torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "yes"), ret, fail, "Could not set 'nt status support = yes'\n"); + torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth", "yes"), ret, fail, "Could not set 'client ntlmv2 auth = yes'\n"); torture_assert_goto(torture, torture_open_connection(&cli_nt, torture, 0), ret, fail, "Could not open NTSTATUS connection\n"); torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "no"), ret, fail, "Could not set 'nt status support = no'\n"); + torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth", "no"), ret, fail, "Could not set 'client ntlmv2 auth = no'\n"); torture_assert_goto(torture, torture_open_connection(&cli_dos, torture, 1), ret, fail, "Could not open DOS connection\n"); torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", nt_status_support ? "yes":"no"), ret, fail, "Could not set 'nt status support' back to where it was\n"); + torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth", + client_ntlmv2_auth ? "yes":"no"), + ret, fail, "Could not set 'client ntlmv2 auth' back to where it was\n"); torture_assert(torture, torture_setup_dir(cli_nt, dirname), "creating test directory"); -- 1.9.1 From be3b506ff84b0173c898c8fcd7da83feaa9fe2c8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 22:24:23 +0100 Subject: [PATCH 153/323] CVE-2016-2111: s4:torture/base: don't use ntlmv2 for dos connection in base.samba3error BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/torture/basic/base.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/source4/torture/basic/base.c b/source4/torture/basic/base.c index e8ae4b6..081f479 100644 --- a/source4/torture/basic/base.c +++ b/source4/torture/basic/base.c @@ -1526,6 +1526,7 @@ static bool torture_chkpath_test(struct torture_context *tctx, static bool torture_samba3_errorpaths(struct torture_context *tctx) { bool nt_status_support; + bool client_ntlmv2_auth; struct smbcli_state *cli_nt = NULL, *cli_dos = NULL; bool result = false; int fnum; @@ -1535,18 +1536,27 @@ static bool torture_samba3_errorpaths(struct torture_context *tctx) NTSTATUS status; nt_status_support = lpcfg_nt_status_support(tctx->lp_ctx); + client_ntlmv2_auth = lpcfg_client_ntlmv2_auth(tctx->lp_ctx); if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "yes")) { torture_result(tctx, TORTURE_FAIL, "Could not set 'nt status support = yes'\n"); goto fail; } + if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", "yes")) { + torture_result(tctx, TORTURE_FAIL, "Could not set 'client ntlmv2 auth = yes'\n"); + goto fail; + } if (!torture_open_connection(&cli_nt, tctx, 0)) { goto fail; } if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "no")) { - torture_result(tctx, TORTURE_FAIL, "Could not set 'nt status support = yes'\n"); + torture_result(tctx, TORTURE_FAIL, "Could not set 'nt status support = no'\n"); + goto fail; + } + if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", "no")) { + torture_result(tctx, TORTURE_FAIL, "Could not set 'client ntlmv2 auth = no'\n"); goto fail; } @@ -1556,7 +1566,12 @@ static bool torture_samba3_errorpaths(struct torture_context *tctx) if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", nt_status_support ? "yes":"no")) { - torture_result(tctx, TORTURE_FAIL, "Could not reset 'nt status support = yes'"); + torture_result(tctx, TORTURE_FAIL, "Could not reset 'nt status support'"); + goto fail; + } + if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", + client_ntlmv2_auth ? "yes":"no")) { + torture_result(tctx, TORTURE_FAIL, "Could not reset 'client ntlmv2 auth'"); goto fail; } -- 1.9.1 From ffd8f6538995a3c3dec72c05afe732f9a237a48d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:08:16 +0100 Subject: [PATCH 154/323] CVE-2016-2111: s4:libcli: don't allow the LANMAN2 session setup without "client lanman auth = yes" BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/libcli/smb_composite/sesssetup.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 903055f..f09a3f8 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -393,24 +393,13 @@ static NTSTATUS session_setup_old(struct composite_context *c, struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); const char *password = cli_credentials_get_password(io->in.credentials); - const char *domain = cli_credentials_get_domain(io->in.credentials); /* * domain controllers tend to reject the NTLM v2 blob * if the netbiosname is not valid (e.g. IP address or FQDN) * so just leave it away (as Windows client do) */ - DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, NULL, domain); - DATA_BLOB session_key; - int flags = 0; - if (session->options.lanman_auth) { - flags |= CLI_CRED_LANMAN_AUTH; - } - - if (session->options.ntlmv2_auth) { - flags |= CLI_CRED_NTLMv2_AUTH; - } state->setup.old.level = RAW_SESSSETUP_OLD; state->setup.old.in.bufsize = session->transport->options.max_xmit; @@ -424,6 +413,17 @@ static NTSTATUS session_setup_old(struct composite_context *c, &state->setup.old.in.domain); if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + DATA_BLOB names_blob = data_blob_null; + int flags = 0; + + if (!cli_credentials_is_anonymous(io->in.credentials) && + !session->options.lanman_auth) + { + return NT_STATUS_INVALID_PARAMETER; + } + + flags |= CLI_CRED_LANMAN_AUTH; + nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, &flags, session->transport->negotiate.secblob, -- 1.9.1 From b866e32eee3c6506111ea9bdb14051dabc6db693 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:08:16 +0100 Subject: [PATCH 155/323] CVE-2016-2111: s4:param: use "client use spnego" to initialize options->use_spnego BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/param/loadparm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index af3313f..71331fb 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -36,7 +36,7 @@ void lpcfg_smbcli_options(struct loadparm_context *lp_ctx, { options->max_xmit = lpcfg_max_xmit(lp_ctx); options->max_mux = lpcfg_max_mux(lp_ctx); - options->use_spnego = lpcfg_nt_status_support(lp_ctx) && lpcfg_use_spnego(lp_ctx); + options->use_spnego = lpcfg_nt_status_support(lp_ctx) && lpcfg_client_use_spnego(lp_ctx); options->signing = lpcfg_client_signing(lp_ctx); options->request_timeout = SMB_REQUEST_TIMEOUT; options->ntstatus_support = lpcfg_nt_status_support(lp_ctx); -- 1.9.1 From 0466542f9fbf9fcdbb59df1d0e3f2d9f874b954a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:08:16 +0100 Subject: [PATCH 156/323] CVE-2016-2111: s4:libcli: don't send a raw NTLMv2 response when we want to use spnego BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/libcli/smb_composite/sesssetup.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index f09a3f8..9f989f2 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -329,6 +329,17 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { + if (!cli_credentials_is_anonymous(io->in.credentials) && + session->options.ntlmv2_auth && + session->transport->options.use_spnego) + { + /* + * Don't send an NTLMv2_RESPONSE without NTLMSSP + * if we want to use spnego + */ + return NT_STATUS_INVALID_PARAMETER; + } + nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, &flags, session->transport->negotiate.secblob, -- 1.9.1 From 2ad632fc3944d4182b498cbb8558e24186cca2db Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:08:16 +0100 Subject: [PATCH 157/323] CVE-2016-2111: s3:libsmb: don't send a raw NTLMv2 response when we want to use spnego BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source3/libsmb/cliconnect.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 50d1a0c..d1848a2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2119,6 +2119,17 @@ struct tevent_req *cli_session_setup_send(TALLOC_CTX *mem_ctx, return req; } else { /* otherwise do a NT1 style session setup */ + if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) { + /* + * Don't send an NTLMv2 response without NTLMSSP + * if we want to use spnego support + */ + DEBUG(1, ("Server does not support EXTENDED_SECURITY " + " but 'client use spnego = yes" + " and 'client ntlmv2 auth = yes'\n")); + tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); + return tevent_req_post(req, ev); + } subreq = cli_session_setup_nt1_send( state, ev, cli, user, pass, passlen, ntpass, ntpasslen, -- 1.9.1 From a852eb007a4bd63b8e178a1021b525fa01913fa1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 27 Mar 2016 01:09:05 +0100 Subject: [PATCH 158/323] CVE-2016-2111: docs-xml: document the new "client NTLMv2 auth" and "client use spnego" interaction BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- docs-xml/smbdotconf/protocol/clientusespnego.xml | 5 +++++ docs-xml/smbdotconf/security/clientntlmv2auth.xml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/docs-xml/smbdotconf/protocol/clientusespnego.xml b/docs-xml/smbdotconf/protocol/clientusespnego.xml index f5a3512..b2f3b12 100644 --- a/docs-xml/smbdotconf/protocol/clientusespnego.xml +++ b/docs-xml/smbdotconf/protocol/clientusespnego.xml @@ -8,6 +8,11 @@ supporting servers (including WindowsXP, Windows2000 and Samba 3.0) to agree upon an authentication mechanism. This enables Kerberos authentication in particular. + + When is also set to + yes extended security (SPNEGO) is required + in order to use NTLMv2 only within NTLMSSP. This behavior was + introduced with the patches for CVE-2016-2111. yes diff --git a/docs-xml/smbdotconf/security/clientntlmv2auth.xml b/docs-xml/smbdotconf/security/clientntlmv2auth.xml index 531c8fc..f42f627 100644 --- a/docs-xml/smbdotconf/security/clientntlmv2auth.xml +++ b/docs-xml/smbdotconf/security/clientntlmv2auth.xml @@ -27,6 +27,11 @@ NTLMv2 by default, and some sites (particularly those following 'best practice' security polices) only allow NTLMv2 responses, and not the weaker LM or NTLM. + + When is also set to + yes extended security (SPNEGO) is required + in order to use NTLMv2 only within NTLMSSP. This behavior was + introduced with the patches for CVE-2016-2111. yes -- 1.9.1 From d6c4f632c2f4b62d1807799fdf9a75b5a966cd03 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Mar 2016 21:02:34 +0100 Subject: [PATCH 159/323] CVE-2016-2111: docs-xml: add "raw NTLMv2 auth" defaulting to "yes" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- docs-xml/smbdotconf/security/rawntlmv2auth.xml | 20 ++++++++++++++++++++ lib/param/loadparm.c | 1 + source3/param/loadparm.c | 1 + 3 files changed, 22 insertions(+) create mode 100644 docs-xml/smbdotconf/security/rawntlmv2auth.xml diff --git a/docs-xml/smbdotconf/security/rawntlmv2auth.xml b/docs-xml/smbdotconf/security/rawntlmv2auth.xml new file mode 100644 index 0000000..ef26297 --- /dev/null +++ b/docs-xml/smbdotconf/security/rawntlmv2auth.xml @@ -0,0 +1,20 @@ + + + This parameter determines whether or not smbd + 8 will allow SMB1 clients without + extended security (without SPNEGO) to use NTLMv2 authentication. + + If this option, lanman auth + and ntlm auth are all disabled, + then only clients with SPNEGO support will be permitted. + That means NTLMv2 is only supported within NTLMSSP. + + Note that the default will change to "no" with Samba 4.5. + + +yes +no + diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 9a3451f..3a00cc5 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2629,6 +2629,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "ClientNTLMv2Auth", "True"); lpcfg_do_global_parameter(lp_ctx, "LanmanAuth", "False"); lpcfg_do_global_parameter(lp_ctx, "NTLMAuth", "True"); + lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "True"); lpcfg_do_global_parameter(lp_ctx, "client use spnego principal", "False"); lpcfg_do_global_parameter(lp_ctx, "UnixExtensions", "True"); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 50b29e3..ed5a5b9 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -690,6 +690,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */ Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */ Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */ + Globals.raw_ntlmv2_auth = true; /* Allow NTLMv2 without NTLMSSP */ Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */ /* Note, that we will also use NTLM2 session security (which is different), if it is available */ -- 1.9.1 From aad08479ce11630d179a3ee3f2f33e18ff61750e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 10:25:54 +0100 Subject: [PATCH 160/323] CVE-2016-2111: s3:auth: implement "raw NTLMv2 auth" checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/auth/auth_util.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index b079d04..c23de7e 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -34,6 +34,7 @@ #include "../auth/auth_sam_reply.h" #include "../librpc/gen_ndr/idmap.h" #include "lib/param/loadparm.h" +#include "../lib/tsocket/tsocket.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH @@ -353,6 +354,20 @@ NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx, const struct tsocket_address *remote_address, DATA_BLOB lm_resp, DATA_BLOB nt_resp) { + bool allow_raw = lp_raw_ntlmv2_auth(); + + if (!allow_raw && nt_resp.length >= 48) { + /* + * NTLMv2_RESPONSE has at least 48 bytes + * and should only be supported via NTLMSSP. + */ + DEBUG(2,("Rejecting raw NTLMv2 authentication with " + "user [%s\\%s] from[%s]\n", + client_domain, smb_name, + tsocket_address_string(remote_address, mem_ctx))); + return NT_STATUS_INVALID_PARAMETER; + } + return make_user_info(mem_ctx, user_info, smb_name, smb_name, client_domain, client_domain, -- 1.9.1 From b95e9c5f36caa07dacf3fbc69a7d40a17d14a322 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Mar 2016 10:25:54 +0100 Subject: [PATCH 161/323] CVE-2016-2111: s4:smb_server: implement "raw NTLMv2 auth" checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/smb_server/smb/sesssetup.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c index 4ebc0c4..e06853a 100644 --- a/source4/smb_server/smb/sesssetup.c +++ b/source4/smb_server/smb/sesssetup.c @@ -263,6 +263,7 @@ static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess) const char *remote_machine = NULL; struct tevent_req *subreq; struct sesssetup_context *state; + bool allow_raw = lpcfg_raw_ntlmv2_auth(req->smb_conn->lp_ctx); sess->nt1.out.vuid = 0; sess->nt1.out.action = 0; @@ -338,6 +339,15 @@ static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess) user_info->password.response.nt = sess->nt1.in.password2; user_info->password.response.nt.data = talloc_steal(user_info, sess->nt1.in.password2.data); + if (!allow_raw && user_info->password.response.nt.length >= 48) { + /* + * NTLMv2_RESPONSE has at least 48 bytes + * and should only be supported via NTLMSSP. + */ + status = NT_STATUS_INVALID_PARAMETER; + goto failed; + } + subreq = auth_check_password_send(state, req->smb_conn->connection->event.ctx, state->auth_context, -- 1.9.1 From 43477ab8da0fa3daa3f2b825b5b27ec9f0433041 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 22:08:38 +0100 Subject: [PATCH 162/323] CVE-2016-2111: selftest:Samba3: use "raw NTLMv2 auth = yes" for nt4_dc BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- selftest/target/Samba3.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 6f7407a..8ff1e7c 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -213,6 +213,7 @@ sub setup_nt4_dc($$) domain master = yes domain logons = yes lanman auth = yes + raw NTLMv2 auth = yes rpc_server:epmapper = external rpc_server:spoolss = external -- 1.9.1 From e7a53a0facd9da1360c5e484df57c5e00b4fd3d9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Mar 2016 21:59:42 +0100 Subject: [PATCH 163/323] CVE-2016-2111: docs-xml/smbdotconf: default "raw NTLMv2 auth" to "no" BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- docs-xml/smbdotconf/security/rawntlmv2auth.xml | 7 +++---- lib/param/loadparm.c | 2 +- source3/param/loadparm.c | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs-xml/smbdotconf/security/rawntlmv2auth.xml b/docs-xml/smbdotconf/security/rawntlmv2auth.xml index ef26297..30e7280 100644 --- a/docs-xml/smbdotconf/security/rawntlmv2auth.xml +++ b/docs-xml/smbdotconf/security/rawntlmv2auth.xml @@ -11,10 +11,9 @@ and ntlm auth are all disabled, then only clients with SPNEGO support will be permitted. That means NTLMv2 is only supported within NTLMSSP. - - Note that the default will change to "no" with Samba 4.5. -yes -no +lanman auth +ntlm auth +no diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 3a00cc5..696c2d6 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2629,7 +2629,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "ClientNTLMv2Auth", "True"); lpcfg_do_global_parameter(lp_ctx, "LanmanAuth", "False"); lpcfg_do_global_parameter(lp_ctx, "NTLMAuth", "True"); - lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "True"); + lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "False"); lpcfg_do_global_parameter(lp_ctx, "client use spnego principal", "False"); lpcfg_do_global_parameter(lp_ctx, "UnixExtensions", "True"); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index ed5a5b9..e790406 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -690,7 +690,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */ Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */ Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */ - Globals.raw_ntlmv2_auth = true; /* Allow NTLMv2 without NTLMSSP */ + Globals.raw_ntlmv2_auth = false; /* Reject NTLMv2 without NTLMSSP */ Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */ /* Note, that we will also use NTLM2 session security (which is different), if it is available */ -- 1.9.1 From 821e4167c53544cfb731eacc1e14779ccea4042b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Mar 2016 15:50:49 +0100 Subject: [PATCH 164/323] CVE-2016-2112: s3:libads: make sure we detect downgrade attacks BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Pair-programmed-with: Ralph Boehme Signed-off-by: Stefan Metzmacher Signed-off-by: Ralph Boehme --- source3/libads/sasl.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index e205e9f..4fcd733 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -276,6 +276,37 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads, data_blob_free(&blob_in); data_blob_free(&blob_out); + if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SEAL) { + bool ok; + + ok = gensec_have_feature(auth_generic_state->gensec_security, + GENSEC_FEATURE_SEAL); + if (!ok) { + DEBUG(0,("The gensec feature sealing request, but unavailable\n")); + TALLOC_FREE(auth_generic_state); + return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); + } + + ok = gensec_have_feature(auth_generic_state->gensec_security, + GENSEC_FEATURE_SIGN); + if (!ok) { + DEBUG(0,("The gensec feature signing request, but unavailable\n")); + TALLOC_FREE(auth_generic_state); + return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); + } + + } else if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SIGN) { + bool ok; + + ok = gensec_have_feature(auth_generic_state->gensec_security, + GENSEC_FEATURE_SIGN); + if (!ok) { + DEBUG(0,("The gensec feature signing request, but unavailable\n")); + TALLOC_FREE(auth_generic_state); + return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE); + } + } + if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) { size_t max_wrapped = gensec_max_wrapped_size(auth_generic_state->gensec_security); ads->ldap.out.max_unwrapped = gensec_max_input_size(auth_generic_state->gensec_security); -- 1.9.1 From 223824c953e58609d28f6c3f1707e3c7b380e612 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 08:29:50 +0100 Subject: [PATCH 165/323] CVE-2016-2112: s4:libcli/ldap: honour "client ldap sasl wrapping" option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/libcli/ldap/ldap_bind.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index d2f4ca7..db8de4e 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -32,6 +32,7 @@ #include "auth/credentials/credentials.h" #include "lib/stream/packet.h" #include "param/param.h" +#include "param/loadparm.h" struct ldap_simple_creds { const char *dn; @@ -216,7 +217,7 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct ldap_SearchResEntry *search; int count, i; bool first = true; - + int wrap_flags = 0; const char **sasl_names; uint32_t old_gensec_features; static const char *supported_sasl_mech_attrs[] = { @@ -285,6 +286,21 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, gensec_init(); + if (conn->sockets.active == conn->sockets.tls) { + /* + * require Kerberos SIGN/SEAL only if we don't use SSL + * Windows seem not to like double encryption + */ + wrap_flags = 0; + } else if (cli_credentials_is_anonymous(creds)) { + /* + * anonymous isn't protected + */ + wrap_flags = 0; + } else { + wrap_flags = lpcfg_client_ldap_sasl_wrapping(lp_ctx); + } + try_logon_again: /* we loop back here on a logon failure, and re-create the @@ -301,10 +317,8 @@ try_logon_again: goto failed; } - /* require Kerberos SIGN/SEAL only if we don't use SSL - * Windows seem not to like double encryption */ old_gensec_features = cli_credentials_get_gensec_features(creds); - if (conn->sockets.active == conn->sockets.tls) { + if (wrap_flags == 0) { cli_credentials_set_gensec_features(creds, old_gensec_features & ~(GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)); } @@ -320,6 +334,14 @@ try_logon_again: * context, so we don't tatoo it ) */ cli_credentials_set_gensec_features(creds, old_gensec_features); + if (wrap_flags & ADS_AUTH_SASL_SEAL) { + gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN); + gensec_want_feature(conn->gensec, GENSEC_FEATURE_SEAL); + } + if (wrap_flags & ADS_AUTH_SASL_SIGN) { + gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN); + } + /* * This is an indication for the NTLMSSP backend to * also encrypt when only GENSEC_FEATURE_SIGN is requested -- 1.9.1 From ec12ce00edbec6f2bc474fb3f0d36469372d8fe3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 08:29:50 +0100 Subject: [PATCH 166/323] CVE-2016-2112: s4:libcli/ldap: make sure we detect downgrade attacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/libcli/ldap/ldap_bind.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index db8de4e..79478e7 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -495,6 +495,20 @@ try_logon_again: conn->bind.type = LDAP_BIND_SASL; conn->bind.creds = creds; + if (wrap_flags & ADS_AUTH_SASL_SEAL) { + if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN)) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + } else if (wrap_flags & ADS_AUTH_SASL_SIGN) { + if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN)) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + } + if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) && !gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) { return NT_STATUS_OK; -- 1.9.1 From 4e3e6913e889862a285657987badabf30c47e3e8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 08:29:50 +0100 Subject: [PATCH 167/323] CVE-2016-2112: s4:libcli/ldap: auto upgrade to SIGN after STRONG_AUTH_REQUIRED MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/libcli/ldap/ldap_bind.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 79478e7..c5d8219 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -437,6 +437,13 @@ try_logon_again: result = response->r.BindResponse.response.resultcode; + if (result == LDAP_STRONG_AUTH_REQUIRED) { + if (wrap_flags == 0) { + wrap_flags = ADS_AUTH_SASL_SIGN; + goto try_logon_again; + } + } + if (result == LDAP_INVALID_CREDENTIALS) { /* try a second time on invalid credentials, to -- 1.9.1 From df05dfa5459c900f8793480d8eedd23f254347da Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 11:56:29 +0100 Subject: [PATCH 168/323] CVE-2016-2112: s4:selftest: use --option=clientldapsaslwrapping=plain for plain connections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index eb7a54a..379043f 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -44,7 +44,7 @@ bbdir = os.path.join(srcdir(), "testprogs/blackbox") # Simple tests for LDAP and CLDAP for auth_type in ['', '-k no', '-k yes']: - for auth_level in ['', '--sign', '--encrypt']: + for auth_level in ['--option=clientldapsaslwrapping=plain', '--sign', '--encrypt']: creds = '-U"$USERNAME%$PASSWORD"' options = creds + ' ' + auth_type + ' ' + auth_level plantestsuite("samba4.ldb.ldap with options %r(ad_dc_ntvfs)" % options, "ad_dc_ntvfs", "%s/test_ldb.sh ldap $SERVER %s" % (bbdir, options)) -- 1.9.1 From a1814dc74146e830619e87a96094f64036b5df56 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 12:45:56 +0100 Subject: [PATCH 169/323] CVE-2016-2112: s4:ldap_server: reduce scope of old_session_info variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/ldap_server/ldap_bind.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c index fb7a6ed..7113b63 100644 --- a/source4/ldap_server/ldap_bind.c +++ b/source4/ldap_server/ldap_bind.c @@ -218,7 +218,6 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call) result = LDAP_SASL_BIND_IN_PROGRESS; errstr = NULL; } else if (NT_STATUS_IS_OK(status)) { - struct auth_session_info *old_session_info=NULL; struct ldapsrv_sasl_postprocess_context *context = NULL; result = LDAP_SUCCESS; @@ -266,14 +265,13 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call) } if (result != LDAP_SUCCESS) { - conn->session_info = old_session_info; } else if (!NT_STATUS_IS_OK(status)) { - conn->session_info = old_session_info; result = LDAP_OPERATIONS_ERROR; errstr = talloc_asprintf(reply, "SASL:[%s]: Failed to setup SASL socket: %s", req->creds.SASL.mechanism, nt_errstr(status)); } else { + struct auth_session_info *old_session_info=NULL; old_session_info = conn->session_info; conn->session_info = NULL; -- 1.9.1 From 0ffae7513eb99d949597e996696c423ebdd90710 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 12:03:56 +0100 Subject: [PATCH 170/323] CVE-2016-2112: docs-xml: add "ldap server require strong auth" option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- .../ldap/ldapserverrequirestrongauth.xml | 28 ++++++++++++++++++++++ lib/param/loadparm.c | 2 ++ lib/param/loadparm.h | 6 +++++ lib/param/param_table.c | 12 ++++++++++ source3/param/loadparm.c | 3 +++ 5 files changed, 51 insertions(+) create mode 100644 docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml diff --git a/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml b/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml new file mode 100644 index 0000000..18d695b --- /dev/null +++ b/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml @@ -0,0 +1,28 @@ + + + + The defines whether + the ldap server requires ldap traffic to be signed or signed and encrypted (sealed). + Possible values are no, allow_sasl_over_tls + and yes. + + + A value of no allows simple and sasl binds over + all transports. + + A value of allow_sasl_over_tls allows simple and sasl binds + (without sign or seal) over TLS encrypted connections. Unencrypted connections only + allow sasl binds with sign or seal. + + A value of yes allows only simple binds + over TLS encrypted connections. Unencrypted connections only + allow sasl binds with sign or seal. + + Note the default will change to yes with Samba 4.5. + +no + diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 696c2d6..d26a3f8 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2810,6 +2810,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "client ldap sasl wrapping", "sign"); + lpcfg_do_global_parameter(lp_ctx, "ldap server require strong auth", "no"); + lpcfg_do_global_parameter(lp_ctx, "follow symlinks", "yes"); lpcfg_do_global_parameter(lp_ctx, "machine password timeout", "604800"); diff --git a/lib/param/loadparm.h b/lib/param/loadparm.h index b453aca..aa256c1 100644 --- a/lib/param/loadparm.h +++ b/lib/param/loadparm.h @@ -204,6 +204,12 @@ enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX, #define ADS_AUTH_SASL_FORCE 0x0080 #define ADS_AUTH_USER_CREDS 0x0100 +enum ldap_server_require_strong_auth { + LDAP_SERVER_REQUIRE_STRONG_AUTH_NO, + LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS, + LDAP_SERVER_REQUIRE_STRONG_AUTH_YES, +}; + /* DNS update settings */ enum dns_update_settings {DNS_UPDATE_OFF, DNS_UPDATE_ON, DNS_UPDATE_SIGNED}; diff --git a/lib/param/param_table.c b/lib/param/param_table.c index 1ebb2f8..be4881f 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -223,6 +223,18 @@ static const struct enum_list enum_ldap_sasl_wrapping[] = { {-1, NULL} }; +static const struct enum_list enum_ldap_server_require_strong_auth_vals[] = { + { LDAP_SERVER_REQUIRE_STRONG_AUTH_NO, "No" }, + { LDAP_SERVER_REQUIRE_STRONG_AUTH_NO, "False" }, + { LDAP_SERVER_REQUIRE_STRONG_AUTH_NO, "0" }, + { LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS, + "allow_sasl_over_tls" }, + { LDAP_SERVER_REQUIRE_STRONG_AUTH_YES, "Yes" }, + { LDAP_SERVER_REQUIRE_STRONG_AUTH_YES, "True" }, + { LDAP_SERVER_REQUIRE_STRONG_AUTH_YES, "1" }, + {-1, NULL} +}; + static const struct enum_list enum_ldap_ssl[] = { {LDAP_SSL_OFF, "no"}, {LDAP_SSL_OFF, "off"}, diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index e790406..6649984 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -741,6 +741,9 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN; + Globals.ldap_server_require_strong_auth = + LDAP_SERVER_REQUIRE_STRONG_AUTH_NO; + /* This is what we tell the afs client. in reality we set the token * to never expire, though, when this runs out the afs client will * forget the token. Set to 0 to get NEVERDATE.*/ -- 1.9.1 From eab6029747ad48db164d027455135f24cfb96af8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 28 Aug 2015 12:19:37 +0200 Subject: [PATCH 171/323] CVE-2016-2112: s4:ldap_server: implement "ldap server require strong auth" option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/ldap_server/ldap_bind.c | 45 ++++++++++++++++++++++++++++++++++----- source4/ldap_server/ldap_server.c | 6 ++++++ source4/ldap_server/ldap_server.h | 2 ++ 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c index 7113b63..99ca148 100644 --- a/source4/ldap_server/ldap_bind.c +++ b/source4/ldap_server/ldap_bind.c @@ -45,6 +45,23 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call) DEBUG(10, ("BindSimple dn: %s\n",req->dn)); + reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse); + if (!reply) { + return NT_STATUS_NO_MEMORY; + } + + if (req->dn != NULL && + strlen(req->dn) != 0 && + call->conn->require_strong_auth > LDAP_SERVER_REQUIRE_STRONG_AUTH_NO && + call->conn->sockets.active != call->conn->sockets.tls) + { + status = NT_STATUS_NETWORK_ACCESS_DENIED; + result = LDAP_STRONG_AUTH_REQUIRED; + errstr = talloc_asprintf(reply, + "BindSimple: Transport encryption required."); + goto do_reply; + } + status = crack_auto_name_to_nt4_name(call, call->conn->connection->event.ctx, call->conn->lp_ctx, req->dn, &nt4_domain, &nt4_account); if (NT_STATUS_IS_OK(status)) { status = authenticate_username_pw(call, @@ -58,11 +75,6 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call) &session_info); } - reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse); - if (!reply) { - return NT_STATUS_NO_MEMORY; - } - if (NT_STATUS_IS_OK(status)) { result = LDAP_SUCCESS; errstr = NULL; @@ -86,6 +98,7 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call) errstr = talloc_asprintf(reply, "Simple Bind Failed: %s", nt_errstr(status)); } +do_reply: resp = &reply->msg->r.BindResponse; resp->response.resultcode = result; resp->response.errormessage = errstr; @@ -262,6 +275,28 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call) status = NT_STATUS_NO_MEMORY; } } + } else { + switch (call->conn->require_strong_auth) { + case LDAP_SERVER_REQUIRE_STRONG_AUTH_NO: + break; + case LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS: + if (call->conn->sockets.active == call->conn->sockets.tls) { + break; + } + status = NT_STATUS_NETWORK_ACCESS_DENIED; + result = LDAP_STRONG_AUTH_REQUIRED; + errstr = talloc_asprintf(reply, + "SASL:[%s]: not allowed if TLS is used.", + req->creds.SASL.mechanism); + break; + case LDAP_SERVER_REQUIRE_STRONG_AUTH_YES: + status = NT_STATUS_NETWORK_ACCESS_DENIED; + result = LDAP_STRONG_AUTH_REQUIRED; + errstr = talloc_asprintf(reply, + "SASL:[%s]: Sign or Seal are required.", + req->creds.SASL.mechanism); + break; + } } if (result != LDAP_SUCCESS) { diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index 3afbcdb..1f31627 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -335,6 +335,12 @@ static void ldapsrv_accept(struct stream_connection *c, conn->sockets.active = conn->sockets.raw; + if (conn->is_privileged) { + conn->require_strong_auth = LDAP_SERVER_REQUIRE_STRONG_AUTH_NO; + } else { + conn->require_strong_auth = lpcfg_ldap_server_require_strong_auth(conn->lp_ctx); + } + if (!NT_STATUS_IS_OK(ldapsrv_backend_Init(conn))) { ldapsrv_terminate_connection(conn, "backend Init failed"); return; diff --git a/source4/ldap_server/ldap_server.h b/source4/ldap_server/ldap_server.h index 6f8b433..87a7163 100644 --- a/source4/ldap_server/ldap_server.h +++ b/source4/ldap_server/ldap_server.h @@ -22,6 +22,7 @@ #include "lib/socket/socket.h" #include "lib/stream/packet.h" #include "system/network.h" +#include "lib/param/loadparm.h" struct ldapsrv_connection { struct loadparm_context *lp_ctx; @@ -42,6 +43,7 @@ struct ldapsrv_connection { bool global_catalog; bool is_privileged; + enum ldap_server_require_strong_auth require_strong_auth; struct { int initial_timeout; -- 1.9.1 From 44c68d74237a5ac176d685df0b4de32ee9e40b6a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 18:07:02 +0100 Subject: [PATCH 172/323] CVE-2016-2112: s4:selftest: run samba4.ldap.bind against fl2008r2dc This uses "ldap server require strong auth = no". BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/selftest/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 379043f..8caf01c 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -536,7 +536,7 @@ plantestsuite("samba4.blackbox.setpassword.py", "none", ["PYTHON=%s" % python, o plantestsuite("samba4.blackbox.newuser.py", "none", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_newuser.sh"), '$PREFIX/provision']) plantestsuite("samba4.blackbox.group.py", "none", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_group.sh"), '$PREFIX/provision']) plantestsuite("samba4.blackbox.spn.py(ad_dc_ntvfs:local)", "ad_dc_ntvfs:local", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_spn.sh"), '$PREFIX/ad_dc_ntvfs']) -plantestsuite_loadlist("samba4.ldap.bind(ad_dc_ntvfs)", "ad_dc_ntvfs", [python, os.path.join(srcdir(), "auth/credentials/tests/bind.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '$LOADLIST', '$LISTOPT']) +plantestsuite_loadlist("samba4.ldap.bind(fl2008r2dc)", "fl2008r2dc", [python, os.path.join(srcdir(), "auth/credentials/tests/bind.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '$LOADLIST', '$LISTOPT']) # This makes sure we test the rid allocation code t = "rpc.samr.large-dc" -- 1.9.1 From 4294dc954d61f73c68c44c36ec441437290aa22b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 10:27:33 +0100 Subject: [PATCH 173/323] CVE-2016-2112: selftest: servers with explicit "ldap server require strong auth" options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default is "ldap server require strong auth = yes", ad_dc_ntvfs uses "ldap server require strong auth = allow_sasl_over_tls", fl2008r2dc uses "ldap server require strong auth = no". BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Alexander Bokovoy --- selftest/target/Samba4.pm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 0c9dcaf..252d5c8 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -545,6 +545,7 @@ sub provision_raw_step1($$) dcerpc endpoint servers = +winreg +srvsvc notify:inotify = false ldb:nosync = true + ldap server require strong auth = yes #We don't want to pass our self-tests if the PAC code is wrong gensec:require_pac = true log file = $ctx->{logdir}/log.\%m @@ -1334,7 +1335,9 @@ sub provision_ad_dc_ntvfs($$) print "PROVISIONING AD DC (NTVFS)..."; my $extra_conf_options = "netbios aliases = localDC1-a - server services = +winbind -winbindd"; + server services = +winbind -winbindd + ldap server require strong auth = allow_sasl_over_tls + "; my $ret = $self->provision($prefix, "domain controller", "localdc", @@ -1452,6 +1455,7 @@ sub provision_fl2008r2dc($$$) my ($self, $prefix, $dcvars) = @_; print "PROVISIONING DC WITH FOREST LEVEL 2008r2..."; + my $extra_conf_options = "ldap server require strong auth = no"; my $ret = $self->provision($prefix, "domain controller", "dc7", @@ -1461,7 +1465,7 @@ sub provision_fl2008r2dc($$$) "locDCpass7", undef, undef, - "", + $extra_conf_options, "", undef); -- 1.9.1 From 4cb45bded8e8a6489cd0c6c3c3e69febe75f3684 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 10:04:48 +0100 Subject: [PATCH 174/323] CVE-2016-2112: s4:selftest: run some ldap test against ad_dc_ntvfs, fl2008r2dc and fl2003dc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want to test against all "ldap server require strong auth" combinations. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner Reviewed-by: Alexander Bokovoy --- selftest/knownfail | 6 +++++ source4/selftest/tests.py | 24 ++++++++++++++++++++ testprogs/blackbox/test_ldb_simple.sh | 41 +++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100755 testprogs/blackbox/test_ldb_simple.sh diff --git a/selftest/knownfail b/selftest/knownfail index eb2f0ba..10a335f 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -300,3 +300,9 @@ # we can watch for set methods on. # ^samba.tests.dcerpc.integer.samba.tests.dcerpc.integer.IntegerTests.test_.*_into_uint8_list +# +## We assert all "ldap server require strong auth" combinations +# +^samba4.ldb.simple.ldap with SIMPLE-BIND.*ad_dc_ntvfs # ldap server require strong auth = allow_sasl_over_tls +^samba4.ldb.simple.ldap with SIMPLE-BIND.*fl2003dc # ldap server require strong auth = yes +^samba4.ldb.simple.ldaps with SASL-BIND.*fl2003dc # ldap server require strong auth = yes diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 8caf01c..22828c7 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -74,6 +74,30 @@ if have_tls_support: plantestsuite("samba4.ldb.ldaps with options %s(ad_dc_ntvfs)" % options, "ad_dc_ntvfs", "%s/test_ldb.sh ldaps $SERVER_IP %s" % (bbdir, options)) +# test all "ldap server require strong auth" combinations +for env in ["ad_dc_ntvfs", "fl2008r2dc", "fl2003dc"]: + options = '--simple-bind-dn="$USERNAME@$REALM" --password="$PASSWORD"' + plantestsuite("samba4.ldb.simple.ldap with SIMPLE-BIND %s(%s)" % (options, env), + env, "%s/test_ldb_simple.sh ldap $SERVER %s" % (bbdir, options)) + if have_tls_support: + plantestsuite("samba4.ldb.simple.ldaps with SIMPLE-BIND %s(%s)" % (options, env), + env, "%s/test_ldb_simple.sh ldaps $SERVER %s" % (bbdir, options)) + + auth_options = [ + '--option=clientldapsaslwrapping=plain', + '--sign', + '--encrypt', + ] + + for auth_option in auth_options: + options = '-U"$USERNAME%$PASSWORD"' + ' ' + auth_option + plantestsuite("samba4.ldb.simple.ldap with SASL-BIND %s(%s)" % (options, env), + env, "%s/test_ldb_simple.sh ldap $SERVER %s" % (bbdir, options)) + if have_tls_support: + options = '-U"$USERNAME%$PASSWORD"' + plantestsuite("samba4.ldb.simple.ldaps with SASL-BIND %s(%s)" % (options, env), + env, "%s/test_ldb_simple.sh ldaps $SERVER %s" % (bbdir, options)) + for options in ['-U"$USERNAME%$PASSWORD"']: plantestsuite("samba4.ldb.ldapi with options %s(ad_dc_ntvfs:local)" % options, "ad_dc_ntvfs:local", "%s/test_ldb.sh ldapi $PREFIX_ABS/ad_dc_ntvfs/private/ldapi %s" % (bbdir, options)) diff --git a/testprogs/blackbox/test_ldb_simple.sh b/testprogs/blackbox/test_ldb_simple.sh new file mode 100755 index 0000000..7375cbf --- /dev/null +++ b/testprogs/blackbox/test_ldb_simple.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +if [ $# -lt 2 ]; then +cat < Date: Fri, 25 Mar 2016 19:24:20 +0100 Subject: [PATCH 175/323] CVE-2016-2112: docs-xml: change the default of "ldap server require strong auth" to "yes" BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml | 4 +--- lib/param/loadparm.c | 2 +- source3/param/loadparm.c | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml b/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml index 18d695b..02bdd81 100644 --- a/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml +++ b/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml @@ -21,8 +21,6 @@ A value of yes allows only simple binds over TLS encrypted connections. Unencrypted connections only allow sasl binds with sign or seal. - - Note the default will change to yes with Samba 4.5. -no +yes diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index d26a3f8..5584d87 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2810,7 +2810,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "client ldap sasl wrapping", "sign"); - lpcfg_do_global_parameter(lp_ctx, "ldap server require strong auth", "no"); + lpcfg_do_global_parameter(lp_ctx, "ldap server require strong auth", "yes"); lpcfg_do_global_parameter(lp_ctx, "follow symlinks", "yes"); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 6649984..112fc8e 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -742,7 +742,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN; Globals.ldap_server_require_strong_auth = - LDAP_SERVER_REQUIRE_STRONG_AUTH_NO; + LDAP_SERVER_REQUIRE_STRONG_AUTH_YES; /* This is what we tell the afs client. in reality we set the token * to never expire, though, when this runs out the afs client will -- 1.9.1 From 3ef823d68c022dd312a370eae52a6b9556d74272 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 15:39:48 +0100 Subject: [PATCH 176/323] CVE-2016-2113: s4:lib/tls: create better certificates and sign the host cert with the ca cert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generated ca cert (in ca.pem) was completely useless, it could be replaced by cert.pem. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/lib/tls/tlscert.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source4/lib/tls/tlscert.c b/source4/lib/tls/tlscert.c index 8eab04a..f1808d7 100644 --- a/source4/lib/tls/tlscert.c +++ b/source4/lib/tls/tlscert.c @@ -30,9 +30,10 @@ #endif #define ORGANISATION_NAME "Samba Administration" -#define UNIT_NAME "Samba - temporary autogenerated certificate" +#define CA_NAME "Samba - temporary autogenerated CA certificate" +#define UNIT_NAME "Samba - temporary autogenerated HOST certificate" #define LIFETIME 700*24*60*60 -#define DH_BITS 1024 +#define RSA_BITS 4096 /* auto-generate a set of self signed certificates @@ -77,11 +78,11 @@ void tls_cert_generate(TALLOC_CTX *mem_ctx, DEBUG(3,("Generating private key\n")); TLSCHECK(gnutls_x509_privkey_init(&key)); - TLSCHECK(gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, DH_BITS, 0)); + TLSCHECK(gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, RSA_BITS, 0)); DEBUG(3,("Generating CA private key\n")); TLSCHECK(gnutls_x509_privkey_init(&cakey)); - TLSCHECK(gnutls_x509_privkey_generate(cakey, GNUTLS_PK_RSA, DH_BITS, 0)); + TLSCHECK(gnutls_x509_privkey_generate(cakey, GNUTLS_PK_RSA, RSA_BITS, 0)); DEBUG(3,("Generating CA certificate\n")); TLSCHECK(gnutls_x509_crt_init(&cacrt)); @@ -90,7 +91,7 @@ void tls_cert_generate(TALLOC_CTX *mem_ctx, ORGANISATION_NAME, strlen(ORGANISATION_NAME))); TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, - UNIT_NAME, strlen(UNIT_NAME))); + CA_NAME, strlen(CA_NAME))); TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, GNUTLS_OID_X520_COMMON_NAME, 0, hostname, strlen(hostname))); @@ -98,10 +99,8 @@ void tls_cert_generate(TALLOC_CTX *mem_ctx, TLSCHECK(gnutls_x509_crt_set_serial(cacrt, &serial, sizeof(serial))); TLSCHECK(gnutls_x509_crt_set_activation_time(cacrt, activation)); TLSCHECK(gnutls_x509_crt_set_expiration_time(cacrt, expiry)); - TLSCHECK(gnutls_x509_crt_set_ca_status(cacrt, 0)); -#ifdef GNUTLS_KP_TLS_WWW_SERVER - TLSCHECK(gnutls_x509_crt_set_key_purpose_oid(cacrt, GNUTLS_KP_TLS_WWW_SERVER, 0)); -#endif + TLSCHECK(gnutls_x509_crt_set_ca_status(cacrt, 1)); + TLSCHECK(gnutls_x509_crt_set_key_usage(cacrt, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN)); TLSCHECK(gnutls_x509_crt_set_version(cacrt, 3)); TLSCHECK(gnutls_x509_crt_get_key_id(cacrt, 0, keyid, &keyidsize)); #if HAVE_GNUTLS_X509_CRT_SET_SUBJECT_KEY_ID @@ -134,6 +133,7 @@ void tls_cert_generate(TALLOC_CTX *mem_ctx, TLSCHECK(gnutls_x509_crt_set_subject_key_id(crt, keyid, keyidsize)); #endif TLSCHECK(gnutls_x509_crt_sign(crt, crt, key)); + TLSCHECK(gnutls_x509_crt_sign(crt, cacrt, cakey)); DEBUG(3,("Exporting TLS keys\n")); -- 1.9.1 From c3c136136302101247281a1f310b6f28e9430a78 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 16:17:04 +0100 Subject: [PATCH 177/323] CVE-2016-2113: s4:lib/tls: implement infrastructure to do peer verification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/lib/tls/tls.h | 23 ++++ source4/lib/tls/tls_tstream.c | 249 ++++++++++++++++++++++++++++++++++++++ source4/lib/tls/wscript | 5 + source4/libcli/ldap/ldap_client.c | 2 + source4/librpc/rpc/dcerpc_roh.c | 2 + 5 files changed, 281 insertions(+) diff --git a/source4/lib/tls/tls.h b/source4/lib/tls/tls.h index 71e6cfb..91eeaae 100644 --- a/source4/lib/tls/tls.h +++ b/source4/lib/tls/tls.h @@ -61,10 +61,33 @@ const struct socket_ops *socket_tls_ops(enum socket_type type); struct tstream_context; struct tstream_tls_params; +enum tls_verify_peer_state { + TLS_VERIFY_PEER_NO_CHECK = 0, +#define TLS_VERIFY_PEER_NO_CHECK_STRING "no_check" + + TLS_VERIFY_PEER_CA_ONLY = 10, +#define TLS_VERIFY_PEER_CA_ONLY_STRING "ca_only" + + TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE = 20, +#define TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE_STRING \ + "ca_and_name_if_available" + + TLS_VERIFY_PEER_CA_AND_NAME = 30, +#define TLS_VERIFY_PEER_CA_AND_NAME_STRING "ca_and_name" + + TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE = 9999, +#define TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE_STRING \ + "as_strict_as_possible" +}; + +const char *tls_verify_peer_string(enum tls_verify_peer_state verify_peer); + NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, const char *ca_file, const char *crl_file, const char *tls_priority, + enum tls_verify_peer_state verify_peer, + const char *peer_name, struct tstream_tls_params **_tlsp); NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx, diff --git a/source4/lib/tls/tls_tstream.c b/source4/lib/tls/tls_tstream.c index 5c3e9f1..5045e88 100644 --- a/source4/lib/tls/tls_tstream.c +++ b/source4/lib/tls/tls_tstream.c @@ -20,13 +20,16 @@ #include "includes.h" #include "system/network.h" #include "system/filesys.h" +#include "system/time.h" #include "../util/tevent_unix.h" #include "../lib/tsocket/tsocket.h" #include "../lib/tsocket/tsocket_internal.h" +#include "../lib/util/util_net.h" #include "lib/tls/tls.h" #if ENABLE_GNUTLS #include +#include #define DH_BITS 2048 @@ -34,8 +37,47 @@ typedef gnutls_datum gnutls_datum_t; #endif +/* + * define our own values in a high range + */ +#ifndef HAVE_DECL_GNUTLS_CERT_EXPIRED +#define GNUTLS_CERT_EXPIRED 0x10000000 +#define REQUIRE_CERT_TIME_CHECKS 1 +#endif +#ifndef HAVE_DECL_GNUTLS_CERT_NOT_ACTIVATED +#define GNUTLS_CERT_NOT_ACTIVATED 0x20000000 +#ifndef REQUIRE_CERT_TIME_CHECKS +#define REQUIRE_CERT_TIME_CHECKS 1 +#endif +#endif +#ifndef HAVE_DECL_GNUTLS_CERT_UNEXPECTED_OWNER +#define GNUTLS_CERT_UNEXPECTED_OWNER 0x40000000 +#endif + #endif /* ENABLE_GNUTLS */ +const char *tls_verify_peer_string(enum tls_verify_peer_state verify_peer) +{ + switch (verify_peer) { + case TLS_VERIFY_PEER_NO_CHECK: + return TLS_VERIFY_PEER_NO_CHECK_STRING; + + case TLS_VERIFY_PEER_CA_ONLY: + return TLS_VERIFY_PEER_CA_ONLY_STRING; + + case TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE: + return TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE_STRING; + + case TLS_VERIFY_PEER_CA_AND_NAME: + return TLS_VERIFY_PEER_CA_AND_NAME_STRING; + + case TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE: + return TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE_STRING; + } + + return "unknown tls_verify_peer_state"; +} + static const struct tstream_context_ops tstream_tls_ops; struct tstream_tls { @@ -46,6 +88,9 @@ struct tstream_tls { gnutls_session tls_session; #endif /* ENABLE_GNUTLS */ + enum tls_verify_peer_state verify_peer; + const char *peer_name; + struct tevent_context *current_ev; struct tevent_immediate *retry_im; @@ -871,6 +916,8 @@ struct tstream_tls_params { const char *tls_priority; #endif /* ENABLE_GNUTLS */ bool tls_enabled; + enum tls_verify_peer_state verify_peer; + const char *peer_name; }; static int tstream_tls_params_destructor(struct tstream_tls_params *tlsp) @@ -897,6 +944,8 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, const char *ca_file, const char *crl_file, const char *tls_priority, + enum tls_verify_peer_state verify_peer, + const char *peer_name, struct tstream_tls_params **_tlsp) { #if ENABLE_GNUTLS @@ -914,6 +963,21 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, talloc_set_destructor(tlsp, tstream_tls_params_destructor); + tlsp->verify_peer = verify_peer; + if (peer_name != NULL) { + tlsp->peer_name = talloc_strdup(tlsp, peer_name); + if (tlsp->peer_name == NULL) { + talloc_free(tlsp); + return NT_STATUS_NO_MEMORY; + } + } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_CA_AND_NAME) { + DEBUG(0,("TLS failed to missing peer_name - " + "with 'tls verify peer = %s'\n", + tls_verify_peer_string(tlsp->verify_peer))); + talloc_free(tlsp); + return NT_STATUS_INVALID_PARAMETER_MIX; + } + ret = gnutls_certificate_allocate_credentials(&tlsp->x509_cred); if (ret != GNUTLS_E_SUCCESS) { DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); @@ -931,6 +995,13 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, talloc_free(tlsp); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } + } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_CA_ONLY) { + DEBUG(0,("TLS failed to missing cafile %s - " + "with 'tls verify peer = %s'\n", + ca_file, + tls_verify_peer_string(tlsp->verify_peer))); + talloc_free(tlsp); + return NT_STATUS_INVALID_PARAMETER_MIX; } if (crl_file && *crl_file && file_exist(crl_file)) { @@ -943,6 +1014,13 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, talloc_free(tlsp); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } + } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE) { + DEBUG(0,("TLS failed to missing crlfile %s - " + "with 'tls verify peer = %s'\n", + crl_file, + tls_verify_peer_string(tlsp->verify_peer))); + talloc_free(tlsp); + return NT_STATUS_INVALID_PARAMETER_MIX; } tlsp->tls_priority = talloc_strdup(tlsp, tls_priority); @@ -997,6 +1075,13 @@ struct tevent_req *_tstream_tls_connect_send(TALLOC_CTX *mem_ctx, talloc_set_destructor(tlss, tstream_tls_destructor); tlss->plain_stream = plain_stream; + tlss->verify_peer = tls_params->verify_peer; + if (tls_params->peer_name != NULL) { + tlss->peer_name = talloc_strdup(tlss, tls_params->peer_name); + if (tevent_req_nomem(tlss->peer_name, req)) { + return tevent_req_post(req, ev); + } + } tlss->current_ev = ev; tlss->retry_im = tevent_create_immediate(tlss); @@ -1362,6 +1447,170 @@ static void tstream_tls_retry_handshake(struct tstream_context *stream) return; } + if (tlss->verify_peer >= TLS_VERIFY_PEER_CA_ONLY) { + unsigned int status = UINT32_MAX; + bool ip = true; + const char *hostname = NULL; +#ifndef HAVE_GNUTLS_CERTIFICATE_VERIFY_PEERS3 + bool need_crt_checks = false; +#endif + + if (tlss->peer_name != NULL) { + ip = is_ipaddress(tlss->peer_name); + } + + if (!ip) { + hostname = tlss->peer_name; + } + + if (tlss->verify_peer == TLS_VERIFY_PEER_CA_ONLY) { + hostname = NULL; + } + + if (tlss->verify_peer >= TLS_VERIFY_PEER_CA_AND_NAME) { + if (hostname == NULL) { + DEBUG(1,("TLS %s - no hostname available for " + "verify_peer[%s] and peer_name[%s]\n", + __location__, + tls_verify_peer_string(tlss->verify_peer), + tlss->peer_name)); + tlss->error = EINVAL; + tevent_req_error(req, tlss->error); + return; + } + } + +#ifdef HAVE_GNUTLS_CERTIFICATE_VERIFY_PEERS3 + ret = gnutls_certificate_verify_peers3(tlss->tls_session, + hostname, + &status); + if (ret != GNUTLS_E_SUCCESS) { + DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); + tlss->error = EIO; + tevent_req_error(req, tlss->error); + return; + } +#else /* not HAVE_GNUTLS_CERTIFICATE_VERIFY_PEERS3 */ + ret = gnutls_certificate_verify_peers2(tlss->tls_session, &status); + if (ret != GNUTLS_E_SUCCESS) { + DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); + tlss->error = EIO; + tevent_req_error(req, tlss->error); + return; + } + + if (status == 0) { + if (hostname != NULL) { + need_crt_checks = true; + } +#ifdef REQUIRE_CERT_TIME_CHECKS + need_crt_checks = true; +#endif + } + + if (need_crt_checks) { + gnutls_x509_crt crt; + const gnutls_datum *cert_list; + unsigned int cert_list_size = 0; +#ifdef REQUIRE_CERT_TIME_CHECKS + time_t now = time(NULL); + time_t tret = -1; +#endif + + cert_list = gnutls_certificate_get_peers(tlss->tls_session, + &cert_list_size); + if (cert_list == NULL) { + cert_list_size = 0; + } + if (cert_list_size == 0) { + DEBUG(1,("TLS %s - cert_list_size == 0\n", + __location__)); + tlss->error = EIO; + tevent_req_error(req, tlss->error); + return; + } + + ret = gnutls_x509_crt_init(&crt); + if (ret != GNUTLS_E_SUCCESS) { + DEBUG(1,("TLS %s - %s\n", __location__, + gnutls_strerror(ret))); + tlss->error = EIO; + tevent_req_error(req, tlss->error); + return; + } + ret = gnutls_x509_crt_import(crt, + &cert_list[0], + GNUTLS_X509_FMT_DER); + if (ret != GNUTLS_E_SUCCESS) { + DEBUG(1,("TLS %s - %s\n", __location__, + gnutls_strerror(ret))); + gnutls_x509_crt_deinit(crt); + tlss->error = EIO; + tevent_req_error(req, tlss->error); + return; + } + + if (hostname != NULL) { + ret = gnutls_x509_crt_check_hostname(crt, + hostname); + if (ret == 0) { + status |= GNUTLS_CERT_INVALID; + status |= GNUTLS_CERT_UNEXPECTED_OWNER; + } + } + +#ifndef HAVE_DECL_GNUTLS_CERT_NOT_ACTIVATED + /* + * GNUTLS_CERT_NOT_ACTIVATED is defined by ourself + */ + tret = gnutls_x509_crt_get_activation_time(crt); + if ((tret == -1) || (now > tret)) { + status |= GNUTLS_CERT_INVALID; + status |= GNUTLS_CERT_NOT_ACTIVATED; + } +#endif +#ifndef HAVE_DECL_GNUTLS_CERT_EXPIRED + /* + * GNUTLS_CERT_EXPIRED is defined by ourself + */ + tret = gnutls_certificate_expiration_time_peers(tlss->tls_session); + if ((tret == -1) || (now > tret)) { + status |= GNUTLS_CERT_INVALID; + status |= GNUTLS_CERT_EXPIRED; + } +#endif + gnutls_x509_crt_deinit(crt); + } +#endif + + if (status != 0) { + DEBUG(1,("TLS %s - check failed for " + "verify_peer[%s] and peer_name[%s] " + "status 0x%x (%s%s%s%s%s%s%s%s)\n", + __location__, + tls_verify_peer_string(tlss->verify_peer), + tlss->peer_name, + status, + status & GNUTLS_CERT_INVALID ? "invalid " : "", + status & GNUTLS_CERT_REVOKED ? "revoked " : "", + status & GNUTLS_CERT_SIGNER_NOT_FOUND ? + "signer_not_found " : "", + status & GNUTLS_CERT_SIGNER_NOT_CA ? + "signer_not_ca " : "", + status & GNUTLS_CERT_INSECURE_ALGORITHM ? + "insecure_algorithm " : "", + status & GNUTLS_CERT_NOT_ACTIVATED ? + "not_activated " : "", + status & GNUTLS_CERT_EXPIRED ? + "expired " : "", + status & GNUTLS_CERT_UNEXPECTED_OWNER ? + "unexptected_owner " : "")); + tlss->error = EINVAL; + tevent_req_error(req, tlss->error); + return; + } + } + tevent_req_done(req); #else /* ENABLE_GNUTLS */ tevent_req_error(req, ENOSYS); diff --git a/source4/lib/tls/wscript b/source4/lib/tls/wscript index 2083409..ecde360 100644 --- a/source4/lib/tls/wscript +++ b/source4/lib/tls/wscript @@ -53,6 +53,11 @@ def configure(conf): conf.CHECK_FUNCS_IN('gnutls_global_init', 'gnutls', headers='gnutls/gnutls.h') + conf.CHECK_FUNCS_IN('gnutls_certificate_verify_peers3', 'gnutls', + headers='gnutls/gnutls.h') + conf.CHECK_DECLS('GNUTLS_CERT_EXPIRED GNUTLS_CERT_NOT_ACTIVATED GNUTLS_CERT_UNEXPECTED_OWNER', + headers='gnutls/gnutls.h gnutls/x509.h') + conf.CHECK_VARIABLE('gnutls_x509_crt_set_version', headers='gnutls/gnutls.h gnutls/x509.h', define='HAVE_GNUTLS_X509_CRT_SET_VERSION', diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 97a83ce..152d5b9 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -475,6 +475,8 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con ca_file, crl_file, tls_priority, + TLS_VERIFY_PEER_NO_CHECK, + NULL, &state->tls_params); if (!NT_STATUS_IS_OK(status)) { composite_error(result, status); diff --git a/source4/librpc/rpc/dcerpc_roh.c b/source4/librpc/rpc/dcerpc_roh.c index 61a22a7..c4842fb 100644 --- a/source4/librpc/rpc/dcerpc_roh.c +++ b/source4/librpc/rpc/dcerpc_roh.c @@ -187,6 +187,8 @@ struct tevent_req *dcerpc_pipe_open_roh_send(struct dcecli_connection *conn, if (use_tls) { status = tstream_tls_params_client(state->roh, NULL, NULL, lpcfg_tls_priority(lp_ctx), + TLS_VERIFY_PEER_NO_CHECK, + NULL, &state->tls_params); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("%s: Failed tstream_tls_params_client - %s\n", -- 1.9.1 From f96140503bad28674b9dfefae2adae8123346e03 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 22:12:56 +0100 Subject: [PATCH 178/323] CVE-2016-2113: docs-xml: add "tls verify peer" option defaulting to "no_check" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- docs-xml/smbdotconf/security/tlsverifypeer.xml | 51 ++++++++++++++++++++++++++ lib/param/loadparm.c | 1 + lib/param/param_table.c | 15 ++++++++ source3/param/loadparm.c | 2 + 4 files changed, 69 insertions(+) create mode 100644 docs-xml/smbdotconf/security/tlsverifypeer.xml diff --git a/docs-xml/smbdotconf/security/tlsverifypeer.xml b/docs-xml/smbdotconf/security/tlsverifypeer.xml new file mode 100644 index 0000000..ce6897d --- /dev/null +++ b/docs-xml/smbdotconf/security/tlsverifypeer.xml @@ -0,0 +1,51 @@ + + + This controls if and how strict the client will verify the peer's certificate and name. + Possible values are (in increasing order): + no_check, + ca_only, + ca_and_name_if_available, + ca_and_name + and + as_strict_as_possible. + + When set to no_check the certificate is not verified at + all, which allows trivial man in the middle attacks. + + + When set to ca_only the certificate is verified to + be signed from a ca specified in the option. + Setting to a valid file is required. + The certificate lifetime is also verified. If the + option is configured, the certificate is also verified against the ca crl. + + + When set to ca_and_name_if_available all checks from + ca_only are performed. In addition, the peer hostname is verified + against the certificate's name, if it is provided by the application layer and + not given as an ip address string. + + + When set to ca_and_name all checks from + ca_and_name_if_available are performed. + In addition the peer hostname needs to be provided and even an ip + address is checked against the certificate's name. + + + When set to as_strict_as_possible all checks from + ca_and_name are performed. In addition the + needs to be configured. + Future versions of Samba may implement additional checks. + + + Note that the default is likely to change from + no_check to as_strict_as_possible + with Samba 4.5. + + +no_check + diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 5584d87..43defc1 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2674,6 +2674,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "min wins ttl", "21600"); lpcfg_do_global_parameter(lp_ctx, "tls enabled", "True"); + lpcfg_do_global_parameter(lp_ctx, "tls verify peer", "no_check"); lpcfg_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem"); lpcfg_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem"); lpcfg_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem"); diff --git a/lib/param/param_table.c b/lib/param/param_table.c index be4881f..d8d9144 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -33,6 +33,7 @@ #include "lib/param/param_global.h" #include "libcli/smb/smb_constants.h" #include "libds/common/roles.h" +#include "source4/lib/tls/tls.h" #ifndef N_ #define N_(x) x @@ -125,6 +126,20 @@ static const struct enum_list enum_smb_signing_vals[] = { {-1, NULL} }; +static const struct enum_list enum_tls_verify_peer_vals[] = { + {TLS_VERIFY_PEER_NO_CHECK, + TLS_VERIFY_PEER_NO_CHECK_STRING}, + {TLS_VERIFY_PEER_CA_ONLY, + TLS_VERIFY_PEER_CA_ONLY_STRING}, + {TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE, + TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE_STRING}, + {TLS_VERIFY_PEER_CA_AND_NAME, + TLS_VERIFY_PEER_CA_AND_NAME_STRING}, + {TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE, + TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE_STRING}, + {-1, NULL} +}; + /* DNS update options. */ static const struct enum_list enum_dns_update_settings[] = { {DNS_UPDATE_OFF, "disabled"}, diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 112fc8e..fdd8ce9 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -70,6 +70,7 @@ #include "dbwrap/dbwrap_rbt.h" #include "../lib/util/bitmap.h" #include "librpc/gen_ndr/nbt.h" +#include "source4/lib/tls/tls.h" #ifdef HAVE_SYS_SYSCTL_H #include @@ -868,6 +869,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL); Globals.tls_enabled = true; + Globals.tls_verify_peer = TLS_VERIFY_PEER_NO_CHECK; lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem"); lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem"); -- 1.9.1 From bfed16107206f33f4f391ab20433a19dd1942ee9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Mar 2016 03:56:22 +0100 Subject: [PATCH 179/323] CVE-2016-2113: s4:selftest: explicitly use '--option="tlsverifypeer=no_check" for some ldaps tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/selftest/tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 22828c7..5c25b91 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -80,6 +80,7 @@ for env in ["ad_dc_ntvfs", "fl2008r2dc", "fl2003dc"]: plantestsuite("samba4.ldb.simple.ldap with SIMPLE-BIND %s(%s)" % (options, env), env, "%s/test_ldb_simple.sh ldap $SERVER %s" % (bbdir, options)) if have_tls_support: + options += ' --option="tlsverifypeer=no_check"' plantestsuite("samba4.ldb.simple.ldaps with SIMPLE-BIND %s(%s)" % (options, env), env, "%s/test_ldb_simple.sh ldaps $SERVER %s" % (bbdir, options)) @@ -94,7 +95,7 @@ for env in ["ad_dc_ntvfs", "fl2008r2dc", "fl2003dc"]: plantestsuite("samba4.ldb.simple.ldap with SASL-BIND %s(%s)" % (options, env), env, "%s/test_ldb_simple.sh ldap $SERVER %s" % (bbdir, options)) if have_tls_support: - options = '-U"$USERNAME%$PASSWORD"' + options = '-U"$USERNAME%$PASSWORD" --option="tlsverifypeer=no_check"' plantestsuite("samba4.ldb.simple.ldaps with SASL-BIND %s(%s)" % (options, env), env, "%s/test_ldb_simple.sh ldaps $SERVER %s" % (bbdir, options)) -- 1.9.1 From e8818e7c992ed8109dfb7b2cc940f26eab461a2c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 16:17:04 +0100 Subject: [PATCH 180/323] CVE-2016-2113: s4:libcli/ldap: verify the server certificate and hostname if configured MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/libcli/ldap/ldap_client.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 152d5b9..f362560 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -465,18 +465,15 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con char *ca_file = lpcfg_tls_cafile(state, conn->lp_ctx); char *crl_file = lpcfg_tls_crlfile(state, conn->lp_ctx); const char *tls_priority = lpcfg_tls_priority(conn->lp_ctx); - if (!ca_file || !*ca_file) { - composite_error(result, - NT_STATUS_INVALID_PARAMETER_MIX); - return result; - } + enum tls_verify_peer_state verify_peer = + lpcfg_tls_verify_peer(conn->lp_ctx); status = tstream_tls_params_client(state, ca_file, crl_file, tls_priority, - TLS_VERIFY_PEER_NO_CHECK, - NULL, + verify_peer, + conn->host, &state->tls_params); if (!NT_STATUS_IS_OK(status)) { composite_error(result, status); -- 1.9.1 From d2d1b72353213329bd00c07e6f62b7dc47f21a6f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 16:17:04 +0100 Subject: [PATCH 181/323] CVE-2016-2113: s4:librpc/rpc: verify the rpc_proxy certificate and hostname if configured MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc_roh.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/source4/librpc/rpc/dcerpc_roh.c b/source4/librpc/rpc/dcerpc_roh.c index c4842fb..6da2978 100644 --- a/source4/librpc/rpc/dcerpc_roh.c +++ b/source4/librpc/rpc/dcerpc_roh.c @@ -185,10 +185,17 @@ struct tevent_req *dcerpc_pipe_open_roh_send(struct dcecli_connection *conn, /* Initialize TLS */ if (use_tls) { - status = tstream_tls_params_client(state->roh, NULL, NULL, - lpcfg_tls_priority(lp_ctx), - TLS_VERIFY_PEER_NO_CHECK, - NULL, + char *ca_file = lpcfg_tls_cafile(state, lp_ctx); + char *crl_file = lpcfg_tls_crlfile(state, lp_ctx); + const char *tls_priority = lpcfg_tls_priority(lp_ctx); + enum tls_verify_peer_state verify_peer = + lpcfg_tls_verify_peer(lp_ctx); + + status = tstream_tls_params_client(state->roh, + ca_file, crl_file, + tls_priority, + verify_peer, + state->rpc_proxy, &state->tls_params); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("%s: Failed tstream_tls_params_client - %s\n", -- 1.9.1 From c118027c8473e545d624b5e92a3ccdf564be4795 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Mar 2016 15:07:36 +0100 Subject: [PATCH 182/323] CVE-2016-2113: selftest: test all "tls verify peer" combinations with ldaps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- selftest/knownfail | 10 ++++++++++ source4/selftest/tests.py | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/selftest/knownfail b/selftest/knownfail index 10a335f..964e061 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -306,3 +306,13 @@ ^samba4.ldb.simple.ldap with SIMPLE-BIND.*ad_dc_ntvfs # ldap server require strong auth = allow_sasl_over_tls ^samba4.ldb.simple.ldap with SIMPLE-BIND.*fl2003dc # ldap server require strong auth = yes ^samba4.ldb.simple.ldaps with SASL-BIND.*fl2003dc # ldap server require strong auth = yes +# These are supposed to fail as we want to verify the "tls verify peer" +# restrictions. Note that fl2008r2dc uses a self-signed certificate +# with does not have a crl file. +# +^samba4.ldb.simple.ldaps.*SERVER_NAME.*tlsverifypeer=ca_and_name_if_available\( +^samba4.ldb.simple.ldaps.*SERVER_NAME.*tlsverifypeer=ca_and_name\( +^samba4.ldb.simple.ldaps.*SERVER_NAME.*tlsverifypeer=as_strict_as_possible\( +^samba4.ldb.simple.ldaps.*SERVER_IP.*tlsverifypeer=ca_and_name\( +^samba4.ldb.simple.ldaps.*SERVER_IP.*tlsverifypeer=as_strict_as_possible\( +^samba4.ldb.simple.ldaps.*SERVER.REALM.*tlsverifypeer=as_strict_as_possible.*fl2008r2dc diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 5c25b91..f6bbfe74 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -74,6 +74,33 @@ if have_tls_support: plantestsuite("samba4.ldb.ldaps with options %s(ad_dc_ntvfs)" % options, "ad_dc_ntvfs", "%s/test_ldb.sh ldaps $SERVER_IP %s" % (bbdir, options)) + creds_options = [ + '--simple-bind-dn=$USERNAME@$REALM --password=$PASSWORD', + ] + peer_options = { + 'SERVER_IP': '$SERVER_IP', + 'SERVER_NAME': '$SERVER', + 'SERVER.REALM': '$SERVER.$REALM', + } + tls_verify_options = [ + '--option="tlsverifypeer=no_check"', + '--option="tlsverifypeer=ca_only"', + '--option="tlsverifypeer=ca_and_name_if_available"', + '--option="tlsverifypeer=ca_and_name"', + '--option="tlsverifypeer=as_strict_as_possible"', + ] + + # we use :local for fl2008r2dc because of the self-signed certificate + for env in ["ad_dc_ntvfs", "fl2008r2dc:local"]: + for peer_key in peer_options.keys(): + peer_val = peer_options[peer_key] + for creds in creds_options: + for tls_verify in tls_verify_options: + options = creds + ' ' + tls_verify + plantestsuite("samba4.ldb.simple.ldaps with options %s %s(%s)" % ( + peer_key, options, env), env, + "%s/test_ldb_simple.sh ldaps %s %s" % (bbdir, peer_val, options)) + # test all "ldap server require strong auth" combinations for env in ["ad_dc_ntvfs", "fl2008r2dc", "fl2003dc"]: options = '--simple-bind-dn="$USERNAME@$REALM" --password="$PASSWORD"' -- 1.9.1 From 1d9a6806958b24dfba438e79c4bcb6a2dd73a55a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 08:38:46 +0100 Subject: [PATCH 183/323] CVE-2016-2113: selftest: use "tls verify peer = no_check" Individual tests will check the more secure values. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- selftest/selftest.pl | 1 + selftest/target/Samba4.pm | 1 + 2 files changed, 2 insertions(+) diff --git a/selftest/selftest.pl b/selftest/selftest.pl index fa2f4cd..ff5f27d 100755 --- a/selftest/selftest.pl +++ b/selftest/selftest.pl @@ -594,6 +594,7 @@ sub write_clientconf($$$) winbind separator = / tls cafile = ${cacert} tls crlfile = ${cacrl_pem} + tls verify peer = no_check "; close(CF); } diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 252d5c8..be6c47c 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -538,6 +538,7 @@ sub provision_raw_step1($$) interfaces = $ctx->{interfaces} tls dh params file = $ctx->{tlsdir}/dhparms.pem tls crlfile = ${crlfile} + tls verify peer = no_check panic action = $RealBin/gdb_backtrace \%d wins support = yes server role = $ctx->{server_role} -- 1.9.1 From 267b30d257efc7295623527b8d055ba1b577cd4c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Mar 2016 13:03:08 +0100 Subject: [PATCH 184/323] CVE-2016-2113: docs-xml: let "tls verify peer" default to "as_strict_as_possible" BUG: https://bugzilla.samba.org/show_bug.cgi?id=11752 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- docs-xml/smbdotconf/security/tlsverifypeer.xml | 6 +----- lib/param/loadparm.c | 2 +- source3/param/loadparm.c | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/docs-xml/smbdotconf/security/tlsverifypeer.xml b/docs-xml/smbdotconf/security/tlsverifypeer.xml index ce6897d..4f47dd4 100644 --- a/docs-xml/smbdotconf/security/tlsverifypeer.xml +++ b/docs-xml/smbdotconf/security/tlsverifypeer.xml @@ -41,11 +41,7 @@ needs to be configured. Future versions of Samba may implement additional checks. - - Note that the default is likely to change from - no_check to as_strict_as_possible - with Samba 4.5. -no_check +as_strict_as_possible diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 43defc1..5c9f6a1 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2674,7 +2674,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "min wins ttl", "21600"); lpcfg_do_global_parameter(lp_ctx, "tls enabled", "True"); - lpcfg_do_global_parameter(lp_ctx, "tls verify peer", "no_check"); + lpcfg_do_global_parameter(lp_ctx, "tls verify peer", "as_strict_as_possible"); lpcfg_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem"); lpcfg_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem"); lpcfg_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem"); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index fdd8ce9..934964f 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -869,7 +869,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL); Globals.tls_enabled = true; - Globals.tls_verify_peer = TLS_VERIFY_PEER_NO_CHECK; + Globals.tls_verify_peer = TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE; lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem"); lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem"); -- 1.9.1 From 77432819be20114d277c53c24221d013cc652463 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2015 04:45:16 +0200 Subject: [PATCH 185/323] CVE-2016-2114: s4:smb2_server: fix session setup with required signing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The client can't sign the session setup request... BUG: https://bugzilla.samba.org/show_bug.cgi?id=11687 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/smb_server/smb2/sesssetup.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/source4/smb_server/smb2/sesssetup.c b/source4/smb_server/smb2/sesssetup.c index d4b8de6..5e261a2 100644 --- a/source4/smb_server/smb2/sesssetup.c +++ b/source4/smb_server/smb2/sesssetup.c @@ -201,14 +201,6 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses set SMB2_NEGOTIATE_SIGNING_REQUIRED */ if (io->smb2.in.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) { smb_sess->smb2_signing.required = true; - } else if (req->smb_conn->smb2_signing_required) { - /* - * if required signing was negotiates in SMB2 Negotiate - * then the client made an error not using it here - */ - DEBUG(1, ("SMB2 signing required on the connection but not used on session\n")); - req->status = NT_STATUS_FOOBAR; - goto failed; } /* disable receipt of more packets on this socket until we've -- 1.9.1 From 9883e7b3760f76d1ac97ca96ea85fc7998da8912 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 10:57:03 +0200 Subject: [PATCH 186/323] CVE-2016-2114: s3:smbd: use the correct default values for "smb signing" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This means an ad_dc will now require signing by default. This matches the default behavior of Windows dc and avoids man in the middle attacks. The main logic for this hides in lpcfg_server_signing_allowed(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11687 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/smbd/negprot.c | 6 ++++-- source3/smbd/smb2_negprot.c | 10 +++++++++- source3/smbd/smb2_sesssetup.c | 3 ++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index 7590421..d2e5e2e 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -543,6 +543,7 @@ void reply_negprot(struct smb_request *req) size_t converted_size; struct smbXsrv_connection *xconn = req->xconn; struct smbd_server_connection *sconn = req->sconn; + bool signing_required = true; START_PROFILE(SMBnegprot); @@ -716,8 +717,9 @@ void reply_negprot(struct smb_request *req) DEBUG( 5, ( "negprot index=%d\n", choice ) ); - if ((lp_server_signing() == SMB_SIGNING_REQUIRED) - && (chosen_level < PROTOCOL_NT1)) { + /* We always have xconn->smb1.signing_state also for >= SMB2_02 */ + signing_required = smb_signing_is_mandatory(xconn->smb1.signing_state); + if (signing_required && (chosen_level < PROTOCOL_NT1)) { exit_server_cleanly("SMB signing is required and " "client negotiated a downlevel protocol"); } diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c index e48d2b8..9c03b2c 100644 --- a/source3/smbd/smb2_negprot.c +++ b/source3/smbd/smb2_negprot.c @@ -25,6 +25,7 @@ #include "../libcli/smb/smb2_negotiate_context.h" #include "../lib/tsocket/tsocket.h" #include "../librpc/ndr/libndr.h" +#include "../libcli/smb/smb_signing.h" extern fstring remote_proto; @@ -160,6 +161,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) uint32_t max_read = lp_smb2_max_read(); uint32_t max_write = lp_smb2_max_write(); NTTIME now = timeval_to_nttime(&req->request_time); + bool signing_required = true; status = smbd_smb2_request_verify_sizes(req, 0x24); if (!NT_STATUS_IS_OK(status)) { @@ -294,7 +296,13 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) } security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED; - if (lp_server_signing() == SMB_SIGNING_REQUIRED) { + /* + * We use xconn->smb1.signing_state as that's already present + * and used lpcfg_server_signing_allowed() to get the correct + * defaults, e.g. signing_required for an ad_dc. + */ + signing_required = smb_signing_is_mandatory(xconn->smb1.signing_state); + if (signing_required) { security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED; } diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index a95f8a1..78bda7b 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -262,7 +262,8 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, } if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) || - lp_server_signing() == SMB_SIGNING_REQUIRED) { + (xconn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED)) + { x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED; } -- 1.9.1 From 0f30f81e77053c5b5d4cfeb73695a77dd47fbb54 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 22 Mar 2016 16:25:32 +0100 Subject: [PATCH 187/323] CVE-2016-2114: libcli/smb: let mandatory signing imply allowed signing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11687 Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Ralph Boehme Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- libcli/smb/smb_signing.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libcli/smb/smb_signing.c b/libcli/smb/smb_signing.c index e128e8f..a7bc819 100644 --- a/libcli/smb/smb_signing.c +++ b/libcli/smb/smb_signing.c @@ -424,6 +424,10 @@ bool smb_signing_set_negotiated(struct smb_signing_state *si, return true; } + if (mandatory) { + allowed = true; + } + if (!si->allowed && mandatory) { return false; } -- 1.9.1 From 049130f7d79ba97f674a8fe3c1246a87d00963a3 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 22 Mar 2016 16:30:42 +0100 Subject: [PATCH 188/323] CVE-2016-2114: s3:smbd: enforce "server signing = mandatory" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a regression that was introduced by commit abb24bf8e874d525382e994af7ae432212775153 ("s3:smbd: make use of better SMB signing negotiation"). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11687 Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Ralph Boehme Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/smbd/sesssetup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index fbc4013..b7fdd00 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -32,6 +32,7 @@ #include "../libcli/security/security.h" #include "auth/gensec/gensec.h" #include "lib/conn_tdb.h" +#include "../libcli/smb/smb_signing.h" /**************************************************************************** Add the standard 'Samba' signature to the end of the session setup. @@ -607,7 +608,8 @@ void reply_sesssetup_and_X(struct smb_request *req) struct smbd_server_connection *sconn = req->sconn; bool doencrypt = xconn->smb1.negprot.encrypted_passwords; bool signing_allowed = false; - bool signing_mandatory = false; + bool signing_mandatory = smb_signing_is_mandatory( + xconn->smb1.signing_state); START_PROFILE(SMBsesssetupX); -- 1.9.1 From 34664a36d49e51a08e89f0bdc96f8093e02dcc38 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 10:57:03 +0200 Subject: [PATCH 189/323] CVE-2016-2114: docs-xml: let the "smb signing" documentation reflect the reality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11687 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- docs-xml/smbdotconf/security/serversigning.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-xml/smbdotconf/security/serversigning.xml b/docs-xml/smbdotconf/security/serversigning.xml index 21b79f0..0b7755a 100644 --- a/docs-xml/smbdotconf/security/serversigning.xml +++ b/docs-xml/smbdotconf/security/serversigning.xml @@ -11,7 +11,7 @@ By default, and when smb signing is set to - default, smb signing enabled when + default, smb signing is required when is active directory domain controller and disabled otherwise. -- 1.9.1 From ff7cbf0436da666089481f3b977d58d3d81ac5a1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 03:45:43 +0100 Subject: [PATCH 190/323] CVE-2016-2115: docs-xml: add "client ipc min protocol" and "client ipc max protocol" options BUG: https://bugzilla.samba.org/show_bug.cgi?id=11796 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- .../smbdotconf/protocol/clientipcmaxprotocol.xml | 29 ++++++++++++++++++++++ .../smbdotconf/protocol/clientipcminprotocol.xml | 29 ++++++++++++++++++++++ docs-xml/smbdotconf/protocol/clientmaxprotocol.xml | 9 ++++--- docs-xml/smbdotconf/protocol/clientminprotocol.xml | 6 +++++ lib/param/loadparm.c | 26 +++++++++++++++++++ source3/include/proto.h | 2 ++ source3/param/loadparm.c | 26 +++++++++++++++++++ 7 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 docs-xml/smbdotconf/protocol/clientipcmaxprotocol.xml create mode 100644 docs-xml/smbdotconf/protocol/clientipcminprotocol.xml diff --git a/docs-xml/smbdotconf/protocol/clientipcmaxprotocol.xml b/docs-xml/smbdotconf/protocol/clientipcmaxprotocol.xml new file mode 100644 index 0000000..408af50 --- /dev/null +++ b/docs-xml/smbdotconf/protocol/clientipcmaxprotocol.xml @@ -0,0 +1,29 @@ + + + The value of the parameter (a string) is the highest + protocol level that will be supported for IPC$ connections as DCERPC transport. + + Normally this option should not be set as the automatic + negotiation phase in the SMB protocol takes care of choosing + the appropriate protocol. + + The value default refers to the latest + supported protocol, currently SMB3_11. + + See for a full list + of available protocols. The values CORE, COREPLUS, LANMAN1, LANMAN2 + are silently upgraded to NT1. + + +client ipc min protocol +client min protocol +client max protocol + +default +SMB2_10 + diff --git a/docs-xml/smbdotconf/protocol/clientipcminprotocol.xml b/docs-xml/smbdotconf/protocol/clientipcminprotocol.xml new file mode 100644 index 0000000..fc04b78 --- /dev/null +++ b/docs-xml/smbdotconf/protocol/clientipcminprotocol.xml @@ -0,0 +1,29 @@ + + + This setting controls the minimum protocol version that the + will be attempted to use for IPC$ connections as DCERPC transport. + + Normally this option should not be set as the automatic + negotiation phase in the SMB protocol takes care of choosing + the appropriate protocol. + + The value default refers to the higher value + of NT1 and the effective value of + . + + See for a full list + of available protocols. The values CORE, COREPLUS, LANMAN1, LANMAN2 + are silently upgraded to NT1. + + +client ipc max protocol +client min protocol +client max protocol +default +SMB3_11 + diff --git a/docs-xml/smbdotconf/protocol/clientmaxprotocol.xml b/docs-xml/smbdotconf/protocol/clientmaxprotocol.xml index 240ba1a..0131331 100644 --- a/docs-xml/smbdotconf/protocol/clientmaxprotocol.xml +++ b/docs-xml/smbdotconf/protocol/clientmaxprotocol.xml @@ -79,13 +79,16 @@ negotiation phase in the SMB protocol takes care of choosing the appropriate protocol. - The value default refers to the default protocol in each - part of the code, currently NT1 in the client tools and - SMB3_02 in winbindd. + The value default refers to NT1. + + IPC$ connections for DCERPC e.g. in winbindd, are handled by the + option. server max protocol client min protocol +client ipc min protocol +client ipc max protocol default LANMAN1 diff --git a/docs-xml/smbdotconf/protocol/clientminprotocol.xml b/docs-xml/smbdotconf/protocol/clientminprotocol.xml index ac0d460..fb8f87e 100644 --- a/docs-xml/smbdotconf/protocol/clientminprotocol.xml +++ b/docs-xml/smbdotconf/protocol/clientminprotocol.xml @@ -13,10 +13,16 @@ See client max protocol for a full list of available protocols. + + IPC$ connections for DCERPC e.g. in winbindd, are handled by the + option. client max protocol server min protocol +client ipc min protocol +client ipc max protocol + CORE NT1 diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 5c9f6a1..6247f88 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2614,6 +2614,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "server max protocol", "SMB3"); lpcfg_do_global_parameter(lp_ctx, "client min protocol", "CORE"); lpcfg_do_global_parameter(lp_ctx, "client max protocol", "default"); + lpcfg_do_global_parameter(lp_ctx, "client ipc min protocol", "default"); + lpcfg_do_global_parameter(lp_ctx, "client ipc max protocol", "default"); lpcfg_do_global_parameter(lp_ctx, "security", "AUTO"); lpcfg_do_global_parameter(lp_ctx, "EncryptPasswords", "True"); lpcfg_do_global_parameter(lp_ctx, "ReadRaw", "True"); @@ -3319,6 +3321,30 @@ int lpcfg_client_max_protocol(struct loadparm_context *lp_ctx) return client_max_protocol; } +int lpcfg_client_ipc_min_protocol(struct loadparm_context *lp_ctx) +{ + int client_ipc_min_protocol = lpcfg__client_ipc_min_protocol(lp_ctx); + if (client_ipc_min_protocol == PROTOCOL_DEFAULT) { + client_ipc_min_protocol = lpcfg_client_min_protocol(lp_ctx); + } + if (client_ipc_min_protocol < PROTOCOL_NT1) { + return PROTOCOL_NT1; + } + return client_ipc_min_protocol; +} + +int lpcfg_client_ipc_max_protocol(struct loadparm_context *lp_ctx) +{ + int client_ipc_max_protocol = lpcfg__client_ipc_max_protocol(lp_ctx); + if (client_ipc_max_protocol == PROTOCOL_DEFAULT) { + return PROTOCOL_LATEST; + } + if (client_ipc_max_protocol < PROTOCOL_NT1) { + return PROTOCOL_NT1; + } + return client_ipc_max_protocol; +} + bool lpcfg_server_signing_allowed(struct loadparm_context *lp_ctx, bool *mandatory) { bool allowed = true; diff --git a/source3/include/proto.h b/source3/include/proto.h index 3d59690..67af5b7 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -904,6 +904,8 @@ const char *lp_idmap_default_backend (void); int lp_security(void); int lp_client_max_protocol(void); int lp_winbindd_max_protocol(void); +int lp_client_ipc_min_protocol(void); +int lp_client_ipc_max_protocol(void); int lp_smb2_max_credits(void); int lp_cups_encrypt(void); bool lp_widelinks(int ); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 934964f..7ecdd48 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -639,6 +639,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.server_min_protocol = PROTOCOL_LANMAN1; Globals._client_max_protocol = PROTOCOL_DEFAULT; Globals.client_min_protocol = PROTOCOL_CORE; + Globals._client_ipc_max_protocol = PROTOCOL_DEFAULT; + Globals._client_ipc_min_protocol = PROTOCOL_DEFAULT; Globals._security = SEC_AUTO; Globals.encrypt_passwords = true; Globals.client_schannel = Auto; @@ -4445,6 +4447,30 @@ int lp_winbindd_max_protocol(void) return client_max_protocol; } +int lp_client_ipc_min_protocol(void) +{ + int client_ipc_min_protocol = lp__client_ipc_min_protocol(); + if (client_ipc_min_protocol == PROTOCOL_DEFAULT) { + client_ipc_min_protocol = lp_client_min_protocol(); + } + if (client_ipc_min_protocol < PROTOCOL_NT1) { + return PROTOCOL_NT1; + } + return client_ipc_min_protocol; +} + +int lp_client_ipc_max_protocol(void) +{ + int client_ipc_max_protocol = lp__client_ipc_max_protocol(); + if (client_ipc_max_protocol == PROTOCOL_DEFAULT) { + return PROTOCOL_LATEST; + } + if (client_ipc_max_protocol < PROTOCOL_NT1) { + return PROTOCOL_NT1; + } + return client_ipc_max_protocol; +} + struct loadparm_global * get_globals(void) { return &Globals; -- 1.9.1 From e3efc51422f1133c2eedee7b6e8dab30399f7964 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 03:43:58 +0100 Subject: [PATCH 191/323] CVE-2016-2115: docs-xml: add "client ipc signing" option BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- docs-xml/smbdotconf/security/clientipcsigning.xml | 35 +++++++++++++++++++++++ docs-xml/smbdotconf/security/clientsigning.xml | 12 ++++---- lib/param/loadparm.c | 14 +++++++++ source3/include/proto.h | 1 + source3/param/loadparm.c | 14 +++++++++ 5 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 docs-xml/smbdotconf/security/clientipcsigning.xml diff --git a/docs-xml/smbdotconf/security/clientipcsigning.xml b/docs-xml/smbdotconf/security/clientipcsigning.xml new file mode 100644 index 0000000..d976f2d --- /dev/null +++ b/docs-xml/smbdotconf/security/clientipcsigning.xml @@ -0,0 +1,35 @@ + + + This controls whether the client is allowed or required to use SMB signing for IPC$ + connections as DCERPC transport. Possible values + are auto, mandatory + and disabled. + + + The default value is the same as the effective value of + if the effective value of + is + NT1. In any other case the default value is + mandatory. + + Note that the default value will be changed to mandatory + in all cases for Samba 4.5 + + When the effective value of this option is mandatory, SMB signing is required. + + When set to auto, SMB signing is offered, but not enforced and if set + to disabled, SMB signing is not offered either. + + Connections from winbindd to Active Directory Domain Controllers + always enforce signing. + + +client signing + +default + diff --git a/docs-xml/smbdotconf/security/clientsigning.xml b/docs-xml/smbdotconf/security/clientsigning.xml index 2af5ada..8addf8a 100644 --- a/docs-xml/smbdotconf/security/clientsigning.xml +++ b/docs-xml/smbdotconf/security/clientsigning.xml @@ -9,14 +9,16 @@ and disabled. - When set to auto or default, SMB signing is offered, but not - enforced, except in winbindd, where it is enforced to Active - Directory Domain Controllers. + When set to auto or default, SMB signing is offered, but not enforced. When set to mandatory, SMB signing is required and if set - to disabled, SMB signing is not offered either. - + to disabled, SMB signing is not offered either. + + IPC$ connections for DCERPC e.g. in winbindd, are handled by the + option. +client ipc signing + default diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 6247f88..c416368 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2656,6 +2656,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "template homedir", "/home/%D/%U"); lpcfg_do_global_parameter(lp_ctx, "client signing", "default"); + lpcfg_do_global_parameter(lp_ctx, "client ipc signing", "default"); lpcfg_do_global_parameter(lp_ctx, "server signing", "default"); lpcfg_do_global_parameter(lp_ctx, "use spnego", "True"); @@ -3345,6 +3346,19 @@ int lpcfg_client_ipc_max_protocol(struct loadparm_context *lp_ctx) return client_ipc_max_protocol; } +int lpcfg_client_ipc_signing(struct loadparm_context *lp_ctx) +{ + int client_ipc_signing = lpcfg__client_ipc_signing(lp_ctx); + if (client_ipc_signing == SMB_SIGNING_DEFAULT) { + int ipc_min_protocol = lpcfg_client_ipc_min_protocol(lp_ctx); + if (ipc_min_protocol >= PROTOCOL_SMB2_02) { + return SMB_SIGNING_REQUIRED; + } + return lpcfg_client_signing(lp_ctx); + } + return client_ipc_signing; +} + bool lpcfg_server_signing_allowed(struct loadparm_context *lp_ctx, bool *mandatory) { bool allowed = true; diff --git a/source3/include/proto.h b/source3/include/proto.h index 67af5b7..6bdf0a7 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -906,6 +906,7 @@ int lp_client_max_protocol(void); int lp_winbindd_max_protocol(void); int lp_client_ipc_min_protocol(void); int lp_client_ipc_max_protocol(void); +int lp_client_ipc_signing(void); int lp_smb2_max_credits(void); int lp_cups_encrypt(void); bool lp_widelinks(int ); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 7ecdd48..eae5d4a 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -824,6 +824,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_use_spnego = true; Globals.client_signing = SMB_SIGNING_DEFAULT; + Globals._client_ipc_signing = SMB_SIGNING_DEFAULT; Globals.server_signing = SMB_SIGNING_DEFAULT; Globals.defer_sharing_violations = true; @@ -4471,6 +4472,19 @@ int lp_client_ipc_max_protocol(void) return client_ipc_max_protocol; } +int lp_client_ipc_signing(void) +{ + int client_ipc_signing = lp__client_ipc_signing(); + if (client_ipc_signing == SMB_SIGNING_DEFAULT) { + int ipc_min_protocol = lp_client_ipc_min_protocol(); + if (ipc_min_protocol >= PROTOCOL_SMB2_02) { + return SMB_SIGNING_REQUIRED; + } + return lp_client_signing(); + } + return client_ipc_signing; +} + struct loadparm_global * get_globals(void) { return &Globals; -- 1.9.1 From 0575136f857099dda8f7c7309c6571a7e4052903 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:13:11 +0100 Subject: [PATCH 192/323] CVE-2016-2115: s4:libcli/raw: add smbcli_options.min_protocol BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source4/libcli/raw/libcliraw.h | 1 + source4/param/loadparm.c | 1 + 2 files changed, 2 insertions(+) diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 95e6943..8220cd7 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -95,6 +95,7 @@ struct smbcli_options { unsigned int use_spnego:1; unsigned int unicode:1; unsigned int ntstatus_support:1; + int min_protocol; int max_protocol; uint32_t max_xmit; uint16_t max_mux; diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index 71331fb..f53b2dd 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -40,6 +40,7 @@ void lpcfg_smbcli_options(struct loadparm_context *lp_ctx, options->signing = lpcfg_client_signing(lp_ctx); options->request_timeout = SMB_REQUEST_TIMEOUT; options->ntstatus_support = lpcfg_nt_status_support(lp_ctx); + options->min_protocol = lpcfg_client_min_protocol(lp_ctx); options->max_protocol = lpcfg__client_max_protocol(lp_ctx); options->unicode = lpcfg_unicode(lp_ctx); options->use_oplocks = true; -- 1.9.1 From 2e4aa2cc35ff9931923985faeb712f57a811a225 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:14:39 +0100 Subject: [PATCH 193/323] CVE-2016-2115: s4:libcli/smb2: use the configured min_protocol BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source4/libcli/smb2/connect.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 9535380..1a6ae34 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -134,6 +134,7 @@ static void smb2_connect_socket_done(struct composite_context *creq) struct tevent_req *subreq; NTSTATUS status; uint32_t timeout_msec; + enum protocol_types min_protocol; status = smbcli_sock_connect_recv(creq, state, &sock); if (tevent_req_nterror(req, status)) { @@ -146,10 +147,14 @@ static void smb2_connect_socket_done(struct composite_context *creq) } timeout_msec = state->transport->options.request_timeout * 1000; + min_protocol = state->transport->options.min_protocol; + if (min_protocol < PROTOCOL_SMB2_02) { + min_protocol = PROTOCOL_SMB2_02; + } subreq = smbXcli_negprot_send(state, state->ev, state->transport->conn, timeout_msec, - PROTOCOL_SMB2_02, + min_protocol, state->transport->options.max_protocol); if (tevent_req_nomem(subreq, req)) { return; -- 1.9.1 From 8721e867e83895269ac6a204b6f4eb12d17d5e29 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:15:38 +0100 Subject: [PATCH 194/323] CVE-2016-2115: s4:libcli/raw: limit maxprotocol to NT1 in smb_raw_negotiate*() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source4/libcli/raw/rawnegotiate.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 9b0ed38..32e8a91 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -51,6 +51,10 @@ struct tevent_req *smb_raw_negotiate_send(TALLOC_CTX *mem_ctx, } state->transport = transport; + if (maxprotocol > PROTOCOL_NT1) { + maxprotocol = PROTOCOL_NT1; + } + subreq = smbXcli_negprot_send(state, ev, transport->conn, timeout_msec, -- 1.9.1 From 1c67c5924f4c4b51796429987811ea669a940e93 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:15:38 +0100 Subject: [PATCH 195/323] CVE-2016-2115: s4:libcli/raw: pass the minprotocol to smb_raw_negotiate*() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source4/libcli/cliconnect.c | 2 +- source4/libcli/raw/rawnegotiate.c | 7 +++++-- source4/libcli/smb_composite/connect.c | 1 + source4/torture/basic/base.c | 1 + 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 1715192..35d963e 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -77,7 +77,7 @@ NTSTATUS smbcli_negprot(struct smbcli_state *cli, bool unicode, int maxprotocol) return NT_STATUS_NO_MEMORY; } - return smb_raw_negotiate(cli->transport, unicode, maxprotocol); + return smb_raw_negotiate(cli->transport, unicode, PROTOCOL_CORE, maxprotocol); } /* wrapper around smb_raw_sesssetup() */ diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 32e8a91..4b42c26 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -37,6 +37,7 @@ static void smb_raw_negotiate_done(struct tevent_req *subreq); struct tevent_req *smb_raw_negotiate_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct smbcli_transport *transport, + int minprotocol, int maxprotocol) { struct tevent_req *req; @@ -58,7 +59,7 @@ struct tevent_req *smb_raw_negotiate_send(TALLOC_CTX *mem_ctx, subreq = smbXcli_negprot_send(state, ev, transport->conn, timeout_msec, - PROTOCOL_CORE, + minprotocol, maxprotocol); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); @@ -131,7 +132,8 @@ NTSTATUS smb_raw_negotiate_recv(struct tevent_req *req) /* Send a negprot command (sync interface) */ -NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport, bool unicode, int maxprotocol) +NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport, bool unicode, + int minprotocol, int maxprotocol) { NTSTATUS status = NT_STATUS_INTERNAL_ERROR; struct tevent_req *subreq = NULL; @@ -140,6 +142,7 @@ NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport, bool unicode, int subreq = smb_raw_negotiate_send(transport, transport->ev, transport, + minprotocol, maxprotocol); if (subreq == NULL) { return NT_STATUS_NO_MEMORY; diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index d87d5ec..fffa768 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -297,6 +297,7 @@ static NTSTATUS connect_send_negprot(struct composite_context *c, state->subreq = smb_raw_negotiate_send(state, state->transport->ev, state->transport, + state->transport->options.min_protocol, state->transport->options.max_protocol); NT_STATUS_HAVE_NO_MEMORY(state->subreq); tevent_req_set_callback(state->subreq, subreq_handler, c); diff --git a/source4/torture/basic/base.c b/source4/torture/basic/base.c index 081f479..8f51253 100644 --- a/source4/torture/basic/base.c +++ b/source4/torture/basic/base.c @@ -371,6 +371,7 @@ static bool run_negprot_nowait(struct torture_context *tctx) struct tevent_req *req; req = smb_raw_negotiate_send(cli, tctx->ev, cli->transport, + PROTOCOL_CORE, PROTOCOL_NT1); tevent_loop_once(tctx->ev); if (!tevent_req_is_in_progress(req)) { -- 1.9.1 From c70cd6151662ae9b7b1f3edd0e67d20a464ab970 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 28 Mar 2014 13:44:29 +0100 Subject: [PATCH 196/323] CVE-2016-2115: s4:librpc/rpc: make use of "client ipc *" options for ncacn_np BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source4/librpc/rpc/dcerpc_connect.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/source4/librpc/rpc/dcerpc_connect.c b/source4/librpc/rpc/dcerpc_connect.c index 9c5dbeb..8ed1257 100644 --- a/source4/librpc/rpc/dcerpc_connect.c +++ b/source4/librpc/rpc/dcerpc_connect.c @@ -183,6 +183,11 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb_send(TALLOC_CT conn->in.fallback_to_anonymous = false; } + conn->in.options.min_protocol = PROTOCOL_NT1; + conn->in.options.max_protocol = PROTOCOL_NT1; + + conn->in.options.signing = lpcfg_client_ipc_signing(lp_ctx); + /* send smb connect request */ conn_req = smb_composite_connect_send(conn, s->io.conn, s->io.resolve_ctx, @@ -277,6 +282,17 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb2_send( lpcfg_smbcli_options(lp_ctx, &options); + options.min_protocol = lpcfg_client_ipc_min_protocol(lp_ctx); + if (options.min_protocol < PROTOCOL_SMB2_02) { + options.min_protocol = PROTOCOL_SMB2_02; + } + options.max_protocol = lpcfg_client_ipc_max_protocol(lp_ctx); + if (options.max_protocol < PROTOCOL_SMB2_02) { + options.max_protocol = PROTOCOL_SMB2_02; + } + + options.signing = lpcfg_client_ipc_signing(lp_ctx); + /* send smb2 connect request */ subreq = smb2_connect_send(s, c->event_ctx, host, @@ -773,6 +789,7 @@ static void continue_connect(struct composite_context *c, struct pipe_connect_st struct composite_context *ncacn_unix_req; struct composite_context *ncalrpc_req; enum dcerpc_transport_t transport; + enum protocol_types min_ipc_protocol; uint32_t flags; /* dcerpc pipe connect input parameters */ @@ -786,6 +803,11 @@ static void continue_connect(struct composite_context *c, struct pipe_connect_st transport = dcerpc_binding_get_transport(s->binding); flags = dcerpc_binding_get_flags(s->binding); + min_ipc_protocol = lpcfg_client_ipc_min_protocol(s->lp_ctx); + if (min_ipc_protocol >= PROTOCOL_SMB2_02) { + flags |= DCERPC_SMB2; + } + /* connect dcerpc pipe depending on required transport */ switch (transport) { case NCACN_NP: -- 1.9.1 From b916b96d3cd8a51afa0c307dea75e85627ba4ec0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Feb 2016 04:23:58 +0100 Subject: [PATCH 197/323] CVE-2016-2115: s3:winbindd: use lp_client_ipc_{min,max}_protocol() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source3/include/proto.h | 1 - source3/param/loadparm.c | 9 --------- source3/winbindd/winbindd_cm.c | 4 ++-- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 6bdf0a7..0bd0c80 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -903,7 +903,6 @@ const char *lp_idmap_backend(const char *domain_name); const char *lp_idmap_default_backend (void); int lp_security(void); int lp_client_max_protocol(void); -int lp_winbindd_max_protocol(void); int lp_client_ipc_min_protocol(void); int lp_client_ipc_max_protocol(void); int lp_client_ipc_signing(void); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index eae5d4a..8a0ba85 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4439,15 +4439,6 @@ int lp_client_max_protocol(void) return client_max_protocol; } -int lp_winbindd_max_protocol(void) -{ - int client_max_protocol = lp__client_max_protocol(); - if (client_max_protocol == PROTOCOL_DEFAULT) { - return PROTOCOL_LATEST; - } - return client_max_protocol; -} - int lp_client_ipc_min_protocol(void) { int client_ipc_min_protocol = lp__client_ipc_min_protocol(); diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index f593d24..941beed 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -1049,8 +1049,8 @@ static NTSTATUS cm_prepare_connection(struct winbindd_domain *domain, cli_set_timeout(*cli, 10000); /* 10 seconds */ result = smbXcli_negprot((*cli)->conn, (*cli)->timeout, - lp_client_min_protocol(), - lp_winbindd_max_protocol()); + lp_client_ipc_min_protocol(), + lp_client_ipc_max_protocol()); if (!NT_STATUS_IS_OK(result)) { DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result))); -- 1.9.1 From 04abbf8ecf2f0b60a01c2cf5e410b9bbe08c60cd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Dec 2015 13:22:16 +0100 Subject: [PATCH 198/323] CVE-2016-2115: s3:winbindd: use lp_client_ipc_signing() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source3/winbindd/winbindd_cm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 941beed..45e3fad 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -996,7 +996,7 @@ static NTSTATUS cm_prepare_connection(struct winbindd_domain *domain, NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - enum smb_signing_setting smb_sign_client_connections = lp_client_signing(); + enum smb_signing_setting smb_sign_client_connections = lp_client_ipc_signing(); if (smb_sign_client_connections == SMB_SIGNING_DEFAULT) { /* -- 1.9.1 From e9e283d891c3e499c8984b69068fd73efa03810b Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 09:55:37 +0100 Subject: [PATCH 199/323] CVE-2016-2115: s3:libsmb: add signing constant SMB_SIGNING_IPC_DEFAULT SMB_SIGNING_IPC_DEFAULT must be used from s3 client code when opening RPC connections. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- lib/param/loadparm.c | 5 ++++- libcli/smb/smbXcli_base.c | 1 + libcli/smb/smb_constants.h | 1 + source3/libsmb/clientgen.c | 9 +++++++++ source4/smb_server/smb2/negprot.c | 1 + 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index c416368..878744f 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -3393,10 +3393,13 @@ bool lpcfg_server_signing_allowed(struct loadparm_context *lp_ctx, bool *mandato case SMB_SIGNING_DESIRED: case SMB_SIGNING_IF_REQUIRED: break; - case SMB_SIGNING_DEFAULT: case SMB_SIGNING_OFF: allowed = false; break; + case SMB_SIGNING_DEFAULT: + case SMB_SIGNING_IPC_DEFAULT: + smb_panic(__location__); + break; } return allowed; diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index ad6a254..b635c14 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -382,6 +382,7 @@ struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx, conn->desire_signing = true; conn->mandatory_signing = false; break; + case SMB_SIGNING_IPC_DEFAULT: case SMB_SIGNING_REQUIRED: /* always */ conn->allow_signing = true; diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h index 563a574..57915d9 100644 --- a/libcli/smb/smb_constants.h +++ b/libcli/smb/smb_constants.h @@ -95,6 +95,7 @@ enum protocol_types { #define PROTOCOL_LATEST PROTOCOL_SMB3_11 enum smb_signing_setting { + SMB_SIGNING_IPC_DEFAULT = -2, /* Only used in C code */ SMB_SIGNING_DEFAULT = -1, SMB_SIGNING_OFF = 0, SMB_SIGNING_IF_REQUIRED = 1, diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6f28dfa..cfb3b16 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -170,6 +170,15 @@ struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx, use_level_II_oplocks = true; } + if (signing_state == SMB_SIGNING_IPC_DEFAULT) { + /* + * Ensure for IPC/RPC the default is to require + * signing unless explicitly turned off by the + * administrator. + */ + signing_state = lp_client_ipc_signing(); + } + if (signing_state == SMB_SIGNING_DEFAULT) { signing_state = lp_client_signing(); } diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index e654392..addd278 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -147,6 +147,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 switch (signing_setting) { case SMB_SIGNING_DEFAULT: + case SMB_SIGNING_IPC_DEFAULT: smb_panic(__location__); break; case SMB_SIGNING_OFF: -- 1.9.1 From 5b9458ce0600f5eb2e6db369cc27fee23667bdbc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Dec 2015 17:16:04 +0100 Subject: [PATCH 200/323] CVE-2016-2115: s3:libsmb: let SMB_SIGNING_IPC_DEFAULT use "client ipc min/max protocol" We need NT1 => LATEST in order to work against all servers which support DCERPC over ncacn_np. This is a mini step in using SMB2/3 in our client side by default. This gives us a higher chance that SMB signing is supported by the server (as it can't be turned off for SMB2 and higher). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source3/libsmb/cliconnect.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index d1848a2..2c351dd 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -3152,6 +3152,8 @@ fail: struct cli_start_connection_state { struct tevent_context *ev; struct cli_state *cli; + int min_protocol; + int max_protocol; }; static void cli_start_connection_connected(struct tevent_req *subreq); @@ -3181,6 +3183,14 @@ static struct tevent_req *cli_start_connection_send( } state->ev = ev; + if (signing_state == SMB_SIGNING_IPC_DEFAULT) { + state->min_protocol = lp_client_ipc_min_protocol(); + state->max_protocol = lp_client_ipc_max_protocol(); + } else { + state->min_protocol = lp_client_min_protocol(); + state->max_protocol = lp_client_max_protocol(); + } + subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port, 0x20, my_name, signing_state, flags); if (tevent_req_nomem(subreq, req)) { @@ -3206,8 +3216,8 @@ static void cli_start_connection_connected(struct tevent_req *subreq) subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn, state->cli->timeout, - lp_client_min_protocol(), - lp_client_max_protocol()); + state->min_protocol, + state->max_protocol); if (tevent_req_nomem(subreq, req)) { return; } -- 1.9.1 From 375578c14dd1c1c1b28f9ba0c7b58e6b7ab4d122 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:00:09 +0100 Subject: [PATCH 201/323] CVE-2016-2115: net: use SMB_SIGNING_IPC_DEFAULT Use SMB_SIGNING_IPC_DEFAULT for RPC connections. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- source3/utils/net_ads.c | 2 +- source3/utils/net_rpc.c | 2 +- source3/utils/net_util.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index ace5b27..90af09e 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -1953,7 +1953,7 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char * c->opt_user_name, c->opt_workgroup, c->opt_password ? c->opt_password : "", CLI_FULL_CONNECTION_USE_KERBEROS, - SMB_SIGNING_DEFAULT); + SMB_SIGNING_IPC_DEFAULT); if (NT_STATUS_IS_ERR(nt_status)) { d_fprintf(stderr, _("Unable to open a connection to %s to " diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 1de08c4..93caf04 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -7396,7 +7396,7 @@ bool net_rpc_check(struct net_context *c, unsigned flags) return false; status = cli_connect_nb(server_name, &server_ss, 0, 0x20, - lp_netbios_name(), SMB_SIGNING_DEFAULT, + lp_netbios_name(), SMB_SIGNING_IPC_DEFAULT, 0, &cli); if (!NT_STATUS_IS_OK(status)) { return false; diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c index 13a0ef1..de929ff 100644 --- a/source3/utils/net_util.c +++ b/source3/utils/net_util.c @@ -126,7 +126,7 @@ NTSTATUS connect_to_service(struct net_context *c, service_name, service_type, c->opt_user_name, c->opt_workgroup, c->opt_password, flags, - SMB_SIGNING_DEFAULT); + SMB_SIGNING_IPC_DEFAULT); if (!NT_STATUS_IS_OK(nt_status)) { d_fprintf(stderr, _("Could not connect to server %s\n"), server_name); -- 1.9.1 From 7261b1e126e384dd7ff2b0b816083bf35e7048c9 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:01:59 +0100 Subject: [PATCH 202/323] CVE-2016-2115: s3:lib/netapi: use SMB_SIGNING_IPC_DEFAULT Use SMB_SIGNING_IPC_DEFAULT for RPC connections. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- source3/lib/netapi/cm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c index 0e05af8..37632af 100644 --- a/source3/lib/netapi/cm.c +++ b/source3/lib/netapi/cm.c @@ -88,7 +88,7 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx, if (!auth_info) { return WERR_NOMEM; } - auth_info->signing_state = SMB_SIGNING_DEFAULT; + auth_info->signing_state = SMB_SIGNING_IPC_DEFAULT; set_cmdline_auth_info_use_kerberos(auth_info, ctx->use_kerberos); set_cmdline_auth_info_username(auth_info, ctx->username); if (ctx->password) { -- 1.9.1 From 4d0e8f8cc57c81d0625ab5b9ec1f353468af0e7e Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:03:13 +0100 Subject: [PATCH 203/323] CVE-2016-2115: s3:auth_domain: use SMB_SIGNING_IPC_DEFAULT Use SMB_SIGNING_IPC_DEFAULT for RPC connections. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- source3/auth/auth_domain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 0dc6657..1a8cd91 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -89,7 +89,7 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli_ret, /* Attempt connection */ result = cli_full_connection(&cli, lp_netbios_name(), dc_name, dc_ss, 0, - "IPC$", "IPC", "", "", "", 0, SMB_SIGNING_DEFAULT); + "IPC$", "IPC", "", "", "", 0, SMB_SIGNING_IPC_DEFAULT); if (!NT_STATUS_IS_OK(result)) { /* map to something more useful */ -- 1.9.1 From 11aa3ab8b32c00e06755d48f7c01a2e9c983117d Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:03:52 +0100 Subject: [PATCH 204/323] CVE-2016-2115: s3:libnet: use SMB_SIGNING_IPC_DEFAULT Use SMB_SIGNING_IPC_DEFAULT for RPC connections. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- source3/libnet/libnet_join.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 235592c..ef6c995 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -962,7 +962,7 @@ static NTSTATUS libnet_join_connect_dc_ipc(const char *dc, domain, pass, flags, - SMB_SIGNING_DEFAULT); + SMB_SIGNING_IPC_DEFAULT); } /**************************************************************** @@ -1517,7 +1517,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx, machine_domain, machine_password, flags, - SMB_SIGNING_DEFAULT); + SMB_SIGNING_IPC_DEFAULT); if (!NT_STATUS_IS_OK(status)) { status = cli_full_connection(&cli, NULL, @@ -1528,7 +1528,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx, NULL, "", 0, - SMB_SIGNING_DEFAULT); + SMB_SIGNING_IPC_DEFAULT); } if (!NT_STATUS_IS_OK(status)) { -- 1.9.1 From 1ed542ac3bbc3ad5b5c6fc133e4ff5262192b295 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Dec 2015 10:04:35 +0100 Subject: [PATCH 205/323] CVE-2016-2115: s3:libsmb: use SMB_SIGNING_IPC_DEFAULT and lp_client_ipc_{min,max}_protocol() Use SMB_SIGNING_IPC_DEFAULT and lp_client_ipc_{min,max}_protocol() for RPC connections. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- source3/libsmb/passchange.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 4676b72..49b9ad6 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -57,7 +57,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam *err_str = NULL; result = cli_connect_nb(remote_machine, NULL, 0, 0x20, NULL, - SMB_SIGNING_DEFAULT, 0, &cli); + SMB_SIGNING_IPC_DEFAULT, 0, &cli); if (!NT_STATUS_IS_OK(result)) { if (asprintf(err_str, "Unable to connect to SMB server on " "machine %s. Error was : %s.\n", @@ -67,8 +67,9 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam return result; } - result = smbXcli_negprot(cli->conn, cli->timeout, PROTOCOL_CORE, - PROTOCOL_NT1); + result = smbXcli_negprot(cli->conn, cli->timeout, + lp_client_ipc_min_protocol(), + lp_client_ipc_max_protocol()); if (!NT_STATUS_IS_OK(result)) { if (asprintf(err_str, "machine %s rejected the negotiate " -- 1.9.1 From d09ef2258d614fa100b59cd21365c9326d0c24b2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Mar 2016 23:52:30 +0100 Subject: [PATCH 206/323] CVE-2016-2115: docs-xml: always default "client ipc signing" to "mandatory" BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- docs-xml/smbdotconf/security/clientipcsigning.xml | 11 +---------- lib/param/loadparm.c | 6 +----- source3/param/loadparm.c | 6 +----- 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/docs-xml/smbdotconf/security/clientipcsigning.xml b/docs-xml/smbdotconf/security/clientipcsigning.xml index d976f2d..0881c6c 100644 --- a/docs-xml/smbdotconf/security/clientipcsigning.xml +++ b/docs-xml/smbdotconf/security/clientipcsigning.xml @@ -11,16 +11,7 @@ and disabled. - The default value is the same as the effective value of - if the effective value of - is - NT1. In any other case the default value is - mandatory. - - Note that the default value will be changed to mandatory - in all cases for Samba 4.5 - - When the effective value of this option is mandatory, SMB signing is required. + When set to mandatory or default, SMB signing is required. When set to auto, SMB signing is offered, but not enforced and if set to disabled, SMB signing is not offered either. diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 878744f..f6a7cfe 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -3350,11 +3350,7 @@ int lpcfg_client_ipc_signing(struct loadparm_context *lp_ctx) { int client_ipc_signing = lpcfg__client_ipc_signing(lp_ctx); if (client_ipc_signing == SMB_SIGNING_DEFAULT) { - int ipc_min_protocol = lpcfg_client_ipc_min_protocol(lp_ctx); - if (ipc_min_protocol >= PROTOCOL_SMB2_02) { - return SMB_SIGNING_REQUIRED; - } - return lpcfg_client_signing(lp_ctx); + return SMB_SIGNING_REQUIRED; } return client_ipc_signing; } diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 8a0ba85..5023888 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4467,11 +4467,7 @@ int lp_client_ipc_signing(void) { int client_ipc_signing = lp__client_ipc_signing(); if (client_ipc_signing == SMB_SIGNING_DEFAULT) { - int ipc_min_protocol = lp_client_ipc_min_protocol(); - if (ipc_min_protocol >= PROTOCOL_SMB2_02) { - return SMB_SIGNING_REQUIRED; - } - return lp_client_signing(); + return SMB_SIGNING_REQUIRED; } return client_ipc_signing; } -- 1.9.1 From 4f0489add7f3510fc7587b81e01976fdc6f6d8f8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 09:12:18 +0200 Subject: [PATCH 207/323] CVE-2016-2118: s4:rpc_server: make it possible to define a min_auth_level on a presentation context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 60 ++++++++++++++++++++++++++++++++++++++ source4/rpc_server/dcerpc_server.h | 9 ++++++ 2 files changed, 69 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index df0ffc8..264b101 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -510,6 +510,35 @@ static int dcesrv_connection_context_destructor(struct dcesrv_connection_context return 0; } +static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call) +{ + struct dcesrv_connection_context *context = dce_call->context; + + context->min_auth_level = DCERPC_AUTH_LEVEL_NONE; +} + +NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + if (dce_call->context == NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + + dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; + return NT_STATUS_OK; +} + +NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + if (dce_call->context == NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + + dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY; + return NT_STATUS_OK; +} + /* handle a bind request */ @@ -597,6 +626,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) call->context = context; talloc_set_destructor(context, dcesrv_connection_context_destructor); + dcesrv_prepare_context_auth(call); + status = iface->bind(call, iface, if_version); if (!NT_STATUS_IS_OK(status)) { char *uuid_str = GUID_string(call, &uuid); @@ -781,6 +812,8 @@ static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_ call->context = context; talloc_set_destructor(context, dcesrv_connection_context_destructor); + dcesrv_prepare_context_auth(call); + status = iface->bind(call, iface, if_version); if (!NT_STATUS_IS_OK(status)) { /* we don't want to trigger the iface->unbind() hook */ @@ -982,9 +1015,14 @@ done: */ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) { + const struct dcesrv_endpoint *endpoint = call->conn->endpoint; + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(endpoint->ep_description); struct ndr_pull *pull; NTSTATUS status; struct dcesrv_connection_context *context; + uint32_t auth_type = DCERPC_AUTH_TYPE_NONE; + uint32_t auth_level = DCERPC_AUTH_LEVEL_NONE; /* if authenticated, and the mech we use can't do async replies, don't use them... */ if (call->conn->auth_state.gensec_security && @@ -997,6 +1035,28 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return dcesrv_fault(call, DCERPC_FAULT_UNK_IF); } + if (call->conn->auth_state.auth_info != NULL) { + auth_type = call->conn->auth_state.auth_info->auth_type; + auth_level = call->conn->auth_state.auth_info->auth_level; + } + + if (auth_level < context->min_auth_level) { + char *addr; + + addr = tsocket_address_string(call->conn->remote_address, call); + + DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] " + "to [%s] with auth[type=0x%x,level=0x%x] " + "on [%s] from [%s]\n", + __func__, + context->min_auth_level, + context->iface->name, + auth_type, auth_level, + derpc_transport_string_by_transport(transport), + addr)); + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } + pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call); NT_STATUS_HAVE_NO_MEMORY(pull); diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 9a697ce..d65e75e 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -168,6 +168,11 @@ struct dcesrv_connection_context { /* private data for the interface implementation */ void *private_data; + + /* + * the minimum required auth level for this interface + */ + enum dcerpc_AuthLevel min_auth_level; }; @@ -414,5 +419,9 @@ _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call); */ _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call); +_PUBLIC_ NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface); +_PUBLIC_ NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface); #endif /* SAMBA_DCERPC_SERVER_H */ -- 1.9.1 From 17a3b3bc4ce8642a8baf356fc6c4b4e310471a07 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 09:13:00 +0200 Subject: [PATCH 208/323] CVE-2016-2118: s4:rpc_server/drsuapi: require DCERPC_AUTH_LEVEL_PRIVACY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches windows and prevents man in the middle downgrade attacks. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- selftest/knownfail | 2 ++ source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 8 ++++++++ source4/selftest/tests.py | 9 ++++++--- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/selftest/knownfail b/selftest/knownfail index 964e061..daa7f9b 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -97,6 +97,8 @@ ^samba4.rpc.netlogon.*.NetrEnumerateTrustedDomainsEx ^samba4.rpc.netlogon.*.GetPassword ^samba4.rpc.netlogon.*.DatabaseRedo +^samba4.rpc.drsuapi.*ncacn_ip_tcp.*validate # should only work with seal +^samba4.rpc.drsuapi.*ncacn_ip_tcp.*bigendian # should only work with seal ^samba4.base.charset.*.Testing partial surrogate ^samba4.*.base.maximum_allowed # broken until we implement NTCREATEX_OPTIONS_BACKUP_INTENT .*net.api.delshare.* # DelShare isn't implemented yet diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index d331313..3fe6c13 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -39,6 +39,14 @@ DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); \ } while (0) +#define DCESRV_INTERFACE_DRSUAPI_BIND(call, iface) \ + dcesrv_interface_drsuapi_bind(call, iface) +static NTSTATUS dcesrv_interface_drsuapi_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_require_privacy(dce_call, iface); +} + /* drsuapi_DsBind */ diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index f6bbfe74..a1a04bd 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -145,9 +145,9 @@ else: # add tests to this list as they start passing, so we test # that they stay passing ncacn_np_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.netlogon.admin", "rpc.handles", "rpc.samsync", "rpc.samba3-sessionkey", "rpc.samba3-getusername", "rpc.samba3-lsa", "rpc.samba3-bind", "rpc.samba3-netlogon", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] -ncalrpc_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.netlogon.admin", "rpc.drsuapi", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] +ncalrpc_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.netlogon.admin", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"] drs_rpc_tests = smbtorture4_testsuites("drs.rpc") -ncacn_ip_tcp_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.netlogon", "rpc.netlogon.admin", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext", "rpc.samr.passwords.validate"] + drs_rpc_tests +ncacn_ip_tcp_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.drsuapi", "rpc.netlogon", "rpc.netlogon.admin", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext", "rpc.samr.passwords.validate"] + drs_rpc_tests slow_ncacn_np_tests = ["rpc.samlogon", "rpc.samr", "rpc.samr.users", "rpc.samr.large-dc", "rpc.samr.users.privileges", "rpc.samr.passwords", "rpc.samr.passwords.pwdlastset", "rpc.samr.passwords.lockout", "rpc.samr.passwords.badpwdcount"] slow_ncacn_ip_tcp_tests = ["rpc.cracknames"] @@ -197,7 +197,10 @@ for transport in ["ncacn_np", "ncacn_ip_tcp"]: else: raise AssertionError("Invalid transport %r" % transport) for t in tests: - plansmbtorture4testsuite(t, env, ["%s:$SERVER" % transport, '-U$USERNAME%$PASSWORD', '--workgroup=$DOMAIN'], "samba4.%s on %s" % (t, transport)) + bindoptions = '' + if t == 'rpc.cracknames': + bindoptions = 'seal' + plansmbtorture4testsuite(t, env, ["%s:$SERVER[%s]" % (transport,bindoptions), '-U$USERNAME%$PASSWORD', '--workgroup=$DOMAIN'], "samba4.%s on %s with %s" % (t, transport, bindoptions)) # Tests for the DFS referral calls implementation for t in smbtorture4_testsuites("dfs."): -- 1.9.1 From a2024fdfaa9ed93a1fa7774339e8e5edd9e5bb58 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 09:13:00 +0200 Subject: [PATCH 209/323] CVE-2016-2118: s4:rpc_server/backupkey: require DCERPC_AUTH_LEVEL_PRIVACY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is required for the whole interface (which has just one opnum for now). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/backupkey/dcesrv_backupkey.c | 13 ++++++++----- source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c | 12 +++++++----- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey.c b/source4/rpc_server/backupkey/dcesrv_backupkey.c index 5fb49b0..63b9ee9 100644 --- a/source4/rpc_server/backupkey/dcesrv_backupkey.c +++ b/source4/rpc_server/backupkey/dcesrv_backupkey.c @@ -41,6 +41,14 @@ #include #include +#define DCESRV_INTERFACE_BACKUPKEY_BIND(call, iface) \ + dcesrv_interface_backupkey_bind(call, iface) +static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_require_privacy(dce_call, iface); +} + static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *name, @@ -1766,11 +1774,6 @@ static WERROR dcesrv_bkrp_BackupKey(struct dcesrv_call_state *dce_call, return WERR_NOT_SUPPORTED; } - if (!dce_call->conn->auth_state.auth_info || - dce_call->conn->auth_state.auth_info->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { - DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); - } - ldb_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0); diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c b/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c index 90cc4fb..ac12c64 100644 --- a/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c +++ b/source4/rpc_server/backupkey/dcesrv_backupkey_heimdal.c @@ -48,6 +48,13 @@ #include #endif +#define DCESRV_INTERFACE_BACKUPKEY_BIND(call, iface) \ + dcesrv_interface_backupkey_bind(call, iface) +static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_require_privacy(dce_call, iface); +} static const unsigned rsa_with_var_num[] = { 1, 2, 840, 113549, 1, 1, 1 }; /* Equivalent to asn1_oid_id_pkcs1_rsaEncryption*/ @@ -1803,11 +1810,6 @@ static WERROR dcesrv_bkrp_BackupKey(struct dcesrv_call_state *dce_call, return WERR_NOT_SUPPORTED; } - if (!dce_call->conn->auth_state.auth_info || - dce_call->conn->auth_state.auth_info->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { - DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); - } - ldb_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0); -- 1.9.1 From 5c095688ccbf9a6a61ffdedca4cf64363712cd5f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 Mar 2016 22:15:00 +0100 Subject: [PATCH 210/323] CVE-2016-2118: python:tests/dcerpc: use [sign] for dnsserver tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- python/samba/tests/dcerpc/dnsserver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/tests/dcerpc/dnsserver.py b/python/samba/tests/dcerpc/dnsserver.py index 2b421d0..7229877 100644 --- a/python/samba/tests/dcerpc/dnsserver.py +++ b/python/samba/tests/dcerpc/dnsserver.py @@ -27,7 +27,7 @@ class DnsserverTests(RpcInterfaceTestCase): super(DnsserverTests, self).setUp() self.server = env_get_var_value("SERVER_IP") self.zone = env_get_var_value("REALM").lower() - self.conn = dnsserver.dnsserver("ncacn_ip_tcp:%s" % (self.server), + self.conn = dnsserver.dnsserver("ncacn_ip_tcp:%s[sign]" % (self.server), self.get_loadparm(), self.get_credentials()) -- 1.9.1 From cb79ce6ad93ed700dde361f7b106eafe70fda662 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 04:06:04 +0100 Subject: [PATCH 211/323] CVE-2016-2118: s4:rpc_server/dnsserver: require at least DCERPC_AUTH_LEVEL_INTEGRITY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches windows and prevents man in the middle downgrade attacks. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dnsserver/dcerpc_dnsserver.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c index a4b82e5..286da18 100644 --- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c +++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c @@ -27,6 +27,14 @@ #include "librpc/gen_ndr/ndr_dnsserver.h" #include "dnsserver.h" +#define DCESRV_INTERFACE_DNSSERVER_BIND(call, iface) \ + dcesrv_interface_dnsserver_bind(call, iface) +static NTSTATUS dcesrv_interface_dnsserver_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_require_integrity(dce_call, iface); +} + struct dnsserver_state { struct loadparm_context *lp_ctx; struct ldb_context *samdb; -- 1.9.1 From f65ed4c005a7fbf7b4998a0742124cfc2a88439e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 14:49:36 +0100 Subject: [PATCH 212/323] CVE-2016-2118: s3: rpcclient: change the default auth level from DCERPC_AUTH_LEVEL_CONNECT to DCERPC_AUTH_LEVEL_INTEGRITY ncacn_ip_tcp:server should get the same protection as ncacn_np:server if authentication and smb signing is used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher --- source3/rpcclient/rpcclient.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index b4108d9..c32fbc7 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -1071,10 +1071,9 @@ out_free: } } if (pipe_default_auth_type != DCERPC_AUTH_TYPE_NONE) { - /* If neither Integrity or Privacy are requested then - * Use just Connect level */ + /* If nothing is requested then default to integrity */ if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) { - pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT; + pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; } } -- 1.9.1 From c8183ab56ec545361bc0635e40f993e358315832 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Dec 2015 14:49:36 +0100 Subject: [PATCH 213/323] CVE-2016-2118: librpc: change the default auth level from DCERPC_AUTH_LEVEL_CONNECT to DCERPC_AUTH_LEVEL_INTEGRITY ncacn_ip_tcp:server should get the same protection as ncacn_np:server if authentication and smb signing is used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher --- librpc/rpc/binding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/rpc/binding.c b/librpc/rpc/binding.c index d0acd6e..b9ccecd 100644 --- a/librpc/rpc/binding.c +++ b/librpc/rpc/binding.c @@ -591,7 +591,7 @@ _PUBLIC_ void dcerpc_binding_get_auth_info(const struct dcerpc_binding *b, } else if (b->flags & DCERPC_CONNECT) { auth_level = DCERPC_AUTH_LEVEL_CONNECT; } else if (auth_type != DCERPC_AUTH_TYPE_NONE) { - auth_level = DCERPC_AUTH_LEVEL_CONNECT; + auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; } else { auth_level = DCERPC_AUTH_LEVEL_NONE; } -- 1.9.1 From 4597a09740529e1c3542b072e7d82613e28ad9cf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Mar 2016 16:02:25 +0100 Subject: [PATCH 214/323] CVE-2016-2118: s4:librpc: use integrity by default for authenticated binds ncacn_ip_tcp:server should get the same protection as ncacn_np:server if authentication and smb signing is used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher --- source4/librpc/rpc/dcerpc_util.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index 9adaa61..e2e4a64 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -678,15 +678,15 @@ struct composite_context *dcerpc_pipe_auth_send(struct dcerpc_pipe *p, /* Perform an authenticated DCE-RPC bind */ - if (!(conn->flags & (DCERPC_SIGN|DCERPC_SEAL))) { + if (!(conn->flags & (DCERPC_CONNECT|DCERPC_SEAL))) { /* we are doing an authenticated connection, - but not using sign or seal. We must force - the CONNECT dcerpc auth type as a NONE auth - type doesn't allow authentication - information to be passed. + which needs to use [connect], [sign] or [seal]. + If nothing is specified, we default to [sign] now. + This give roughly the same protection as + ncacn_np with smb signing. */ - conn->flags |= DCERPC_CONNECT; + conn->flags |= DCERPC_SIGN; } if (conn->flags & DCERPC_AUTH_SPNEGO) { -- 1.9.1 From cddf12b60e0871af7da43ad11ddf168cb8b4c073 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 17:03:59 +0100 Subject: [PATCH 215/323] CVE-2016-2118: docs-xml: add "allow dcerpc auth level connect" defaulting to "yes" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We sadly need to allow this for now by default. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- .../security/allowdcerpcauthlevelconnect.xml | 29 ++++++++++++++++++++++ lib/param/loadparm.c | 2 ++ source3/param/loadparm.c | 2 ++ 3 files changed, 33 insertions(+) create mode 100644 docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml diff --git a/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml new file mode 100644 index 0000000..27a9733 --- /dev/null +++ b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml @@ -0,0 +1,29 @@ + + + This option controls whether DCERPC services are allowed to + be used with DCERPC_AUTH_LEVEL_CONNECT, which provides authentication, + but no per message integrity nor privacy protection. + + Some interfaces like samr, lsarpc and netlogon have a hard-coded default of + no and epmapper, mgmt and rpcecho have a hard-coded default of + yes. + + + The behavior can be overwritten per interface name (e.g. lsarpc, netlogon, samr, srvsvc, + winreg, wkssvc ...) by using 'allow dcerpc auth level connect:interface = yes' as option. + + This option yields precedence to the implementation specific restrictions. + E.g. the drsuapi and backupkey protocols require DCERPC_AUTH_LEVEL_PRIVACY. + The dnsserver protocol requires DCERPC_AUTH_LEVEL_INTEGRITY. + + + Note the default will very likely change to no for Samba 4.5. + + +yes +no + + diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index f6a7cfe..c47759d9 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2634,6 +2634,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "False"); lpcfg_do_global_parameter(lp_ctx, "client use spnego principal", "False"); + lpcfg_do_global_parameter(lp_ctx, "allow dcerpc auth level connect", "True"); + lpcfg_do_global_parameter(lp_ctx, "UnixExtensions", "True"); lpcfg_do_global_parameter(lp_ctx, "PreferredMaster", "Auto"); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 5023888..c0b4f77 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -697,6 +697,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */ /* Note, that we will also use NTLM2 session security (which is different), if it is available */ + Globals.allow_dcerpc_auth_level_connect = true; /* we need to allow this for now by default */ + Globals.map_to_guest = 0; /* By Default, "Never" */ Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */ Globals.enhanced_browsing = true; -- 1.9.1 From 19007ff12345cc62d20625988600e18ad0574f98 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 02:46:59 +0100 Subject: [PATCH 216/323] CVE-2016-2118: s4:rpc_server: make use of "allow dcerpc auth level connect" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this option turned off we only allow DCERPC_AUTH_LEVEL_{NONE,INTEGRITY,PRIVACY}, this means the reject any request with AUTH_LEVEL_CONNECT with ACCESS_DENIED. We sadly need to keep this enabled by default for now. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 104 +++++++++++++++++++++++++++++++++++++ source4/rpc_server/dcerpc_server.h | 5 ++ 2 files changed, 109 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 264b101..9250f84 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -512,9 +512,29 @@ static int dcesrv_connection_context_destructor(struct dcesrv_connection_context static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call) { + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; + const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint; + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(endpoint->ep_description); struct dcesrv_connection_context *context = dce_call->context; + const struct dcesrv_interface *iface = context->iface; context->min_auth_level = DCERPC_AUTH_LEVEL_NONE; + + if (transport == NCALRPC) { + context->allow_connect = true; + return; + } + + /* + * allow overwrite per interface + * allow dcerpc auth level connect: + */ + context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx); + context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL, + "allow dcerpc auth level connect", + iface->name, + context->allow_connect); } NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call, @@ -539,6 +559,66 @@ NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_cal return NT_STATUS_OK; } +_PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; + const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint; + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(endpoint->ep_description); + struct dcesrv_connection_context *context = dce_call->context; + + if (context == NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + + if (transport == NCALRPC) { + context->allow_connect = true; + return NT_STATUS_OK; + } + + /* + * allow overwrite per interface + * allow dcerpc auth level connect: + */ + context->allow_connect = false; + context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL, + "allow dcerpc auth level connect", + iface->name, + context->allow_connect); + return NT_STATUS_OK; +} + +_PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; + const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint; + enum dcerpc_transport_t transport = + dcerpc_binding_get_transport(endpoint->ep_description); + struct dcesrv_connection_context *context = dce_call->context; + + if (context == NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + + if (transport == NCALRPC) { + context->allow_connect = true; + return NT_STATUS_OK; + } + + /* + * allow overwrite per interface + * allow dcerpc auth level connect: + */ + context->allow_connect = true; + context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL, + "allow dcerpc auth level connect", + iface->name, + context->allow_connect); + return NT_STATUS_OK; +} + /* handle a bind request */ @@ -1040,6 +1120,30 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) auth_level = call->conn->auth_state.auth_info->auth_level; } + switch (auth_level) { + case DCERPC_AUTH_LEVEL_NONE: + case DCERPC_AUTH_LEVEL_INTEGRITY: + case DCERPC_AUTH_LEVEL_PRIVACY: + break; + default: + if (!context->allow_connect) { + char *addr; + + addr = tsocket_address_string(call->conn->remote_address, + call); + + DEBUG(2, ("%s: restrict auth_level_connect access " + "to [%s] with auth[type=0x%x,level=0x%x] " + "on [%s] from [%s]\n", + __func__, context->iface->name, + auth_type, auth_level, + derpc_transport_string_by_transport(transport), + addr)); + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } + break; + } + if (auth_level < context->min_auth_level) { char *addr; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index d65e75e..66cb1f4 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -173,6 +173,7 @@ struct dcesrv_connection_context { * the minimum required auth level for this interface */ enum dcerpc_AuthLevel min_auth_level; + bool allow_connect; }; @@ -423,5 +424,9 @@ _PUBLIC_ NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_sta const struct dcesrv_interface *iface); _PUBLIC_ NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface); +_PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface); +_PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface); #endif /* SAMBA_DCERPC_SERVER_H */ -- 1.9.1 From c5b7fbec8086a617a4e2453beaa6504a0e69ed22 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 09:50:30 +0200 Subject: [PATCH 217/323] CVE-2016-2118: s4:rpc_server/lsa: reject DCERPC_AUTH_LEVEL_CONNECT by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prevents man in the middle downgrade attacks. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/lsa/dcesrv_lsa.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index c55f679..41311ed 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -35,6 +35,14 @@ #include "lib/messaging/irpc.h" #include "libds/common/roles.h" +#define DCESRV_INTERFACE_LSARPC_BIND(call, iface) \ + dcesrv_interface_lsarpc_bind(call, iface) +static NTSTATUS dcesrv_interface_lsarpc_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_reject_connect(dce_call, iface); +} + /* this type allows us to distinguish handle types */ -- 1.9.1 From 445341da62cb9d3cc68f9cb08d61ef6459e87cf7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 09:50:30 +0200 Subject: [PATCH 218/323] CVE-2016-2118: s4:rpc_server/samr: reject DCERPC_AUTH_LEVEL_CONNECT by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prevents man in the middle downgrade attacks. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- selftest/knownfail | 2 ++ source4/rpc_server/samr/dcesrv_samr.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/selftest/knownfail b/selftest/knownfail index daa7f9b..76def93 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -99,6 +99,8 @@ ^samba4.rpc.netlogon.*.DatabaseRedo ^samba4.rpc.drsuapi.*ncacn_ip_tcp.*validate # should only work with seal ^samba4.rpc.drsuapi.*ncacn_ip_tcp.*bigendian # should only work with seal +^samba4.rpc.samr.passwords.validate.*ncacn_ip_tcp.*with.validate # should only work with seal +^samba4.rpc.samr.passwords.validate.*ncacn_ip_tcp.*with.bigendian # should only work with seal ^samba4.base.charset.*.Testing partial surrogate ^samba4.*.base.maximum_allowed # broken until we implement NTCREATEX_OPTIONS_BACKUP_INTENT .*net.api.delshare.* # DelShare isn't implemented yet diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 9f3bd10..c4ed1de 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -41,6 +41,14 @@ #include "lib/util/tsort.h" #include "libds/common/flag_mapping.h" +#define DCESRV_INTERFACE_SAMR_BIND(call, iface) \ + dcesrv_interface_samr_bind(call, iface) +static NTSTATUS dcesrv_interface_samr_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_reject_connect(dce_call, iface); +} + /* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */ #define QUERY_STRING(msg, field, attr) \ -- 1.9.1 From f9bd4b5fe4b58165e9fa1b2e4befd746b18648d2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 13:52:48 +0200 Subject: [PATCH 219/323] CVE-2016-2118: s4:rpc_server/netlogon: reject DCERPC_AUTH_LEVEL_CONNECT by default This prevents man in the middle downgrade attacks. Signed-off-by: Stefan Metzmacher --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 527718d..fd86c36 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -44,6 +44,14 @@ #include "librpc/gen_ndr/ndr_winbind_c.h" #include "lib/socket/netif.h" +#define DCESRV_INTERFACE_NETLOGON_BIND(call, iface) \ + dcesrv_interface_netlogon_bind(call, iface) +static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_reject_connect(dce_call, iface); +} + static struct memcache *global_challenge_table; struct netlogon_server_pipe_state { -- 1.9.1 From 6204fcca08e00c437224f75445385882fb398325 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 19:17:40 +0100 Subject: [PATCH 220/323] CVE-2016-2118: s4:rpc_server/epmapper: allow DCERPC_AUTH_LEVEL_CONNECT by default BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/rpc_server/epmapper/rpc_epmapper.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source4/rpc_server/epmapper/rpc_epmapper.c b/source4/rpc_server/epmapper/rpc_epmapper.c index 62627ce..6b934d7 100644 --- a/source4/rpc_server/epmapper/rpc_epmapper.c +++ b/source4/rpc_server/epmapper/rpc_epmapper.c @@ -24,6 +24,14 @@ #include "librpc/gen_ndr/ndr_epmapper.h" #include "rpc_server/dcerpc_server.h" +#define DCESRV_INTERFACE_EPMAPPER_BIND(call, iface) \ + dcesrv_interface_epmapper_bind(call, iface) +static NTSTATUS dcesrv_interface_epmapper_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_allow_connect(dce_call, iface); +} + typedef uint32_t error_status_t; /* handle types for this module */ -- 1.9.1 From 7f426e6d766064282e0bfad11f81bccd94ed56bf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 19:18:42 +0100 Subject: [PATCH 221/323] CVE-2016-2118: s4:rpc_server/mgmt: allow DCERPC_AUTH_LEVEL_CONNECT by default BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/rpc_server/dcesrv_mgmt.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source4/rpc_server/dcesrv_mgmt.c b/source4/rpc_server/dcesrv_mgmt.c index 8c4eb63..4d3428d 100644 --- a/source4/rpc_server/dcesrv_mgmt.c +++ b/source4/rpc_server/dcesrv_mgmt.c @@ -23,6 +23,14 @@ #include "rpc_server/dcerpc_server.h" #include "librpc/gen_ndr/ndr_mgmt.h" +#define DCESRV_INTERFACE_MGMT_BIND(call, iface) \ + dcesrv_interface_mgmt_bind(call, iface) +static NTSTATUS dcesrv_interface_mgmt_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_allow_connect(dce_call, iface); +} + /* mgmt_inq_if_ids */ -- 1.9.1 From 04331d66829639c5df5c428a7fe36e494fb8ba30 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 19:19:04 +0100 Subject: [PATCH 222/323] CVE-2016-2118: s4:rpc_server/rpcecho: allow DCERPC_AUTH_LEVEL_CONNECT by default BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source4/rpc_server/echo/rpc_echo.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/rpc_server/echo/rpc_echo.c b/source4/rpc_server/echo/rpc_echo.c index 4863c77..49c9e23 100644 --- a/source4/rpc_server/echo/rpc_echo.c +++ b/source4/rpc_server/echo/rpc_echo.c @@ -26,6 +26,13 @@ #include "librpc/gen_ndr/ndr_echo.h" #include "lib/events/events.h" +#define DCESRV_INTERFACE_RPCECHO_BIND(call, iface) \ + dcesrv_interface_rpcecho_bind(call, iface) +static NTSTATUS dcesrv_interface_rpcecho_bind(struct dcesrv_call_state *dce_call, + const struct dcesrv_interface *iface) +{ + return dcesrv_interface_bind_allow_connect(dce_call, iface); +} static NTSTATUS dcesrv_echo_AddOne(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct echo_AddOne *r) { -- 1.9.1 From c0b295808037b6062b8a72f45a5fb97e52e9be8d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Mar 2016 04:40:30 +0100 Subject: [PATCH 223/323] CVE-2016-2118: s3:rpc_server: make use of "allow dcerpc auth level connect" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this option turned off we only allow DCERPC_AUTH_LEVEL_{NONE,INTEGRITY,PRIVACY}, this means the reject any request with AUTH_LEVEL_CONNECT with ACCESS_DENIED. We sadly need to keep this enabled by default for now. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Pair-Programmed-With: Günther Deschner Signed-off-by: Stefan Metzmacher Signed-off-by: Günther Deschner --- source3/rpc_server/rpc_ncacn_np.c | 2 +- source3/rpc_server/rpc_pipes.h | 4 +++ source3/rpc_server/srv_pipe.c | 56 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c index d504847..5514956 100644 --- a/source3/rpc_server/rpc_ncacn_np.c +++ b/source3/rpc_server/rpc_ncacn_np.c @@ -224,7 +224,7 @@ struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx, return NULL; } - context_fns = talloc(p, struct pipe_rpc_fns); + context_fns = talloc_zero(p, struct pipe_rpc_fns); if (context_fns == NULL) { DEBUG(0,("talloc() failed!\n")); TALLOC_FREE(p); diff --git a/source3/rpc_server/rpc_pipes.h b/source3/rpc_server/rpc_pipes.h index e65209a..14b8705 100644 --- a/source3/rpc_server/rpc_pipes.h +++ b/source3/rpc_server/rpc_pipes.h @@ -94,6 +94,10 @@ struct pipe_rpc_fns { uint32_t context_id; struct ndr_syntax_id syntax; + /* + * shall we allow "connect" auth level for this interface ? + */ + bool allow_connect; }; /* diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 4ffaa0d..4902676 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -44,6 +44,7 @@ #include "librpc/ndr/ndr_table.h" #include "auth/gensec/gensec.h" #include "librpc/ndr/ndr_dcerpc.h" +#include "lib/tsocket/tsocket.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -338,6 +339,7 @@ static bool check_bind_req(struct pipes_struct *p, { struct pipe_rpc_fns *context_fns; bool ok; + const char *interface_name = NULL; DEBUG(3,("check_bind_req for %s\n", ndr_interface_name(&abstract->uuid, @@ -359,18 +361,34 @@ static bool check_bind_req(struct pipes_struct *p, return false; } - context_fns = talloc(p, struct pipe_rpc_fns); + context_fns = talloc_zero(p, struct pipe_rpc_fns); if (context_fns == NULL) { DEBUG(0,("check_bind_req: talloc() failed!\n")); return false; } + interface_name = ndr_interface_name(&abstract->uuid, + abstract->if_version); + SMB_ASSERT(interface_name != NULL); + context_fns->next = context_fns->prev = NULL; context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract); context_fns->cmds = rpc_srv_get_pipe_cmds(abstract); context_fns->context_id = context_id; context_fns->syntax = *abstract; + context_fns->allow_connect = lp_allow_dcerpc_auth_level_connect(); + /* + * every interface can be modified to allow "connect" auth_level by + * using a parametric option like: + * allow dcerpc auth level connect: + * e.g. + * allow dcerpc auth level connect:samr = yes + */ + context_fns->allow_connect = lp_parm_bool(-1, + "allow dcerpc auth level connect", + interface_name, context_fns->allow_connect); + /* add to the list of open contexts */ DLIST_ADD( p->contexts, context_fns ); @@ -1174,6 +1192,7 @@ static bool api_pipe_request(struct pipes_struct *p, TALLOC_CTX *frame = talloc_stackframe(); bool ret = False; struct pipe_rpc_fns *pipe_fns; + const char *interface_name = NULL; if (!p->pipe_bound) { DEBUG(1, ("Pipe not bound!\n")); @@ -1194,6 +1213,37 @@ static bool api_pipe_request(struct pipes_struct *p, return false; } + interface_name = ndr_interface_name(&pipe_fns->syntax.uuid, + pipe_fns->syntax.if_version); + SMB_ASSERT(interface_name != NULL); + + switch (p->auth.auth_level) { + case DCERPC_AUTH_LEVEL_NONE: + case DCERPC_AUTH_LEVEL_INTEGRITY: + case DCERPC_AUTH_LEVEL_PRIVACY: + break; + default: + if (!pipe_fns->allow_connect) { + char *addr; + + addr = tsocket_address_string(p->remote_address, frame); + + DEBUG(1, ("%s: restrict auth_level_connect access " + "to [%s] with auth[type=0x%x,level=0x%x] " + "on [%s] from [%s]\n", + __func__, interface_name, + p->auth.auth_type, + p->auth.auth_level, + derpc_transport_string_by_transport(p->transport), + addr)); + + setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED)); + TALLOC_FREE(frame); + return true; + } + break; + } + if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) { DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n")); setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED)); @@ -1209,9 +1259,7 @@ static bool api_pipe_request(struct pipes_struct *p, return false; } - DEBUG(5, ("Requested %s rpc service\n", - ndr_interface_name(&pipe_fns->syntax.uuid, - pipe_fns->syntax.if_version))); + DEBUG(5, ("Requested %s rpc service\n", interface_name)); ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds, &pipe_fns->syntax); -- 1.9.1 From f77d9a1e6b14ea9a63146d794c838d2817378b5c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Aug 2015 09:50:30 +0200 Subject: [PATCH 224/323] CVE-2016-2118: s3:rpc_server/{samr,lsa,netlogon}: reject DCERPC_AUTH_LEVEL_CONNECT by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prevents man in the middle downgrade attacks. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Pair-Programmed-With: Günther Deschner Signed-off-by: Stefan Metzmacher Signed-off-by: Günther Deschner --- selftest/knownfail | 4 ++++ source3/rpc_server/srv_pipe.c | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/selftest/knownfail b/selftest/knownfail index 76def93..1678cd0 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -320,3 +320,7 @@ ^samba4.ldb.simple.ldaps.*SERVER_IP.*tlsverifypeer=ca_and_name\( ^samba4.ldb.simple.ldaps.*SERVER_IP.*tlsverifypeer=as_strict_as_possible\( ^samba4.ldb.simple.ldaps.*SERVER.REALM.*tlsverifypeer=as_strict_as_possible.*fl2008r2dc +# +# we don't allow auth_level_connect anymore... +# +^samba3.blackbox.rpcclient.*ncacn_np.*with.*connect.*rpcclient # we don't allow auth_level_connect anymore diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 4902676..5704323 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -45,6 +45,9 @@ #include "auth/gensec/gensec.h" #include "librpc/ndr/ndr_dcerpc.h" #include "lib/tsocket/tsocket.h" +#include "../librpc/gen_ndr/ndr_samr.h" +#include "../librpc/gen_ndr/ndr_lsa.h" +#include "../librpc/gen_ndr/ndr_netlogon.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -379,6 +382,22 @@ static bool check_bind_req(struct pipes_struct *p, context_fns->allow_connect = lp_allow_dcerpc_auth_level_connect(); /* + * for the samr, lsarpc and netlogon interfaces we don't allow "connect" + * auth_level by default. + */ + ok = ndr_syntax_id_equal(abstract, &ndr_table_samr.syntax_id); + if (ok) { + context_fns->allow_connect = false; + } + ok = ndr_syntax_id_equal(abstract, &ndr_table_lsarpc.syntax_id); + if (ok) { + context_fns->allow_connect = false; + } + ok = ndr_syntax_id_equal(abstract, &ndr_table_netlogon.syntax_id); + if (ok) { + context_fns->allow_connect = false; + } + /* * every interface can be modified to allow "connect" auth_level by * using a parametric option like: * allow dcerpc auth level connect: -- 1.9.1 From 7d2df06a6189396e876b961159a5654a91bfe99c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 26 Mar 2016 08:47:42 +0100 Subject: [PATCH 225/323] CVE-2016-2118: s3:rpc_server/{epmapper,echo}: allow DCERPC_AUTH_LEVEL_CONNECT by default BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- source3/rpc_server/srv_pipe.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 5704323..e6e39df 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -48,6 +48,8 @@ #include "../librpc/gen_ndr/ndr_samr.h" #include "../librpc/gen_ndr/ndr_lsa.h" #include "../librpc/gen_ndr/ndr_netlogon.h" +#include "../librpc/gen_ndr/ndr_epmapper.h" +#include "../librpc/gen_ndr/ndr_echo.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -398,6 +400,18 @@ static bool check_bind_req(struct pipes_struct *p, context_fns->allow_connect = false; } /* + * for the epmapper and echo interfaces we allow "connect" + * auth_level by default. + */ + ok = ndr_syntax_id_equal(abstract, &ndr_table_epmapper.syntax_id); + if (ok) { + context_fns->allow_connect = true; + } + ok = ndr_syntax_id_equal(abstract, &ndr_table_rpcecho.syntax_id); + if (ok) { + context_fns->allow_connect = true; + } + /* * every interface can be modified to allow "connect" auth_level by * using a parametric option like: * allow dcerpc auth level connect: -- 1.9.1 From ad0403f0c6c0269e59d93e771fe4e7c6f554d12d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 17:03:59 +0100 Subject: [PATCH 226/323] CVE-2016-2118: docs-xml: default "allow dcerpc auth level connect" to "no" BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy --- docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml | 6 ++---- lib/param/loadparm.c | 2 +- source3/param/loadparm.c | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml index 27a9733..03531ad 100644 --- a/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml +++ b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml @@ -19,11 +19,9 @@ E.g. the drsuapi and backupkey protocols require DCERPC_AUTH_LEVEL_PRIVACY. The dnsserver protocol requires DCERPC_AUTH_LEVEL_INTEGRITY. - - Note the default will very likely change to no for Samba 4.5. -yes -no +no +yes diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index c47759d9..73d4204 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2634,7 +2634,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "False"); lpcfg_do_global_parameter(lp_ctx, "client use spnego principal", "False"); - lpcfg_do_global_parameter(lp_ctx, "allow dcerpc auth level connect", "True"); + lpcfg_do_global_parameter(lp_ctx, "allow dcerpc auth level connect", "False"); lpcfg_do_global_parameter(lp_ctx, "UnixExtensions", "True"); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index c0b4f77..2ad1c6f8 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -697,7 +697,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */ /* Note, that we will also use NTLM2 session security (which is different), if it is available */ - Globals.allow_dcerpc_auth_level_connect = true; /* we need to allow this for now by default */ + Globals.allow_dcerpc_auth_level_connect = false; /* we don't allow this by default */ Globals.map_to_guest = 0; /* By Default, "Never" */ Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */ -- 1.9.1 From 3761e222c71a3b887d6ecdba185997362868f141 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Feb 2016 22:48:11 +0100 Subject: [PATCH 227/323] CVE-2016-2118: s4:rpc_server/samr: allow _samr_ValidatePassword only with PRIVACY... MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This requires transport encryption. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/samr/dcesrv_samr.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index c4ed1de..69d48b8 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -4321,11 +4321,20 @@ static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call, NTSTATUS status; enum dcerpc_transport_t transport = dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); + enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE; if (transport != NCACN_IP_TCP && transport != NCALRPC) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } + if (dce_call->conn->auth_state.auth_info != NULL) { + auth_level = dce_call->conn->auth_state.auth_info->auth_level; + } + + if (auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { + DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); + } + (*r->out.rep) = talloc_zero(mem_ctx, union samr_ValidatePasswordRep); r2.in.domain_name = NULL; -- 1.9.1 From 8217cf97f42dae72dfe5fd3b8d30584fe75a219c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Feb 2016 22:48:11 +0100 Subject: [PATCH 228/323] CVE-2016-2118: s3:rpc_server/samr: allow _samr_ValidatePassword only with PRIVACY... MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This requires transport encryption. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/samr/srv_samr_nt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c index 7eb06cf..2f6f020 100644 --- a/source3/rpc_server/samr/srv_samr_nt.c +++ b/source3/rpc_server/samr/srv_samr_nt.c @@ -6746,6 +6746,11 @@ NTSTATUS _samr_ValidatePassword(struct pipes_struct *p, return NT_STATUS_ACCESS_DENIED; } + if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { + p->fault_state = DCERPC_FAULT_ACCESS_DENIED; + return NT_STATUS_ACCESS_DENIED; + } + if (r->in.level < 1 || r->in.level > 3) { return NT_STATUS_INVALID_INFO_CLASS; } -- 1.9.1 From 43833cceb08aa6281f9957ddcf62359130d4d67f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Jul 2015 22:46:05 +0200 Subject: [PATCH 229/323] CVE-2015-5370: dcerpc.idl: add DCERPC_{NCACN_PAYLOAD,FRAG}_MAX_SIZE defines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- librpc/idl/dcerpc.idl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl index f7bf595..015eb3d 100644 --- a/librpc/idl/dcerpc.idl +++ b/librpc/idl/dcerpc.idl @@ -532,8 +532,10 @@ interface dcerpc const uint8 DCERPC_PFC_OFFSET = 3; const uint8 DCERPC_DREP_OFFSET = 4; const uint8 DCERPC_FRAG_LEN_OFFSET = 8; + const uint32 DCERPC_FRAG_MAX_SIZE = 5840; const uint8 DCERPC_AUTH_LEN_OFFSET = 10; const uint8 DCERPC_NCACN_PAYLOAD_OFFSET = 16; + const uint32 DCERPC_NCACN_PAYLOAD_MAX_SIZE = 0x400000; /* 4 MByte */ /* little-endian flag */ const uint8 DCERPC_DREP_LE = 0x10; -- 1.9.1 From 810fdf361e3ceaf70f7b200f1b425c4d20820018 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Jun 2015 01:19:57 +0200 Subject: [PATCH 230/323] CVE-2015-5370: librpc/rpc: simplify and harden dcerpc_pull_auth_trailer() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- librpc/rpc/dcerpc_util.c | 63 ++++++++++++++++++++++++++++++++++++------------ librpc/rpc/rpc_common.h | 4 +-- 2 files changed, 49 insertions(+), 18 deletions(-) diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index 696bcda..8f0ebd0 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -83,31 +83,44 @@ uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob) * * @return - A NTSTATUS error code. */ -NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt, +NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, TALLOC_CTX *mem_ctx, - DATA_BLOB *pkt_trailer, + const DATA_BLOB *pkt_trailer, struct dcerpc_auth *auth, - uint32_t *auth_length, + uint32_t *_auth_length, bool auth_data_only) { struct ndr_pull *ndr; enum ndr_err_code ndr_err; - uint32_t data_and_pad; + uint16_t data_and_pad; + uint16_t auth_length; + uint32_t tmp_length; - data_and_pad = pkt_trailer->length - - (DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length); + ZERO_STRUCTP(auth); + if (_auth_length != NULL) { + *_auth_length = 0; + } - /* paranoia check for pad size. This would be caught anyway by - the ndr_pull_advance() a few lines down, but it scared - Jeremy enough for him to call me, so we might as well check - it now, just to prevent someone posting a bogus YouTube - video in the future. - */ - if (data_and_pad > pkt_trailer->length) { - return NT_STATUS_INFO_LENGTH_MISMATCH; + /* Paranoia checks for auth_length. The caller should check this... */ + if (pkt->auth_length > pkt->frag_length) { + return NT_STATUS_INTERNAL_ERROR; + } + tmp_length = DCERPC_NCACN_PAYLOAD_OFFSET; + tmp_length += DCERPC_AUTH_TRAILER_LENGTH; + tmp_length += pkt->auth_length; + if (tmp_length > pkt->frag_length) { + return NT_STATUS_INTERNAL_ERROR; + } + if (pkt_trailer->length > UINT16_MAX) { + return NT_STATUS_INTERNAL_ERROR; } - *auth_length = pkt_trailer->length - data_and_pad; + auth_length = DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length; + if (pkt_trailer->length < auth_length) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + data_and_pad = pkt_trailer->length - auth_length; ndr = ndr_pull_init_blob(pkt_trailer, mem_ctx); if (!ndr) { @@ -127,14 +140,28 @@ NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt, ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(ndr); + ZERO_STRUCTP(auth); return ndr_map_error2ntstatus(ndr_err); } + if (data_and_pad < auth->auth_pad_length) { + DEBUG(1, (__location__ ": ERROR: pad length mismatch. " + "Calculated %u got %u\n", + (unsigned)data_and_pad, + (unsigned)auth->auth_pad_length)); + talloc_free(ndr); + ZERO_STRUCTP(auth); + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + if (auth_data_only && data_and_pad != auth->auth_pad_length) { - DEBUG(1, (__location__ ": WARNING: pad length mismatch. " + DEBUG(1, (__location__ ": ERROR: pad length mismatch. " "Calculated %u got %u\n", (unsigned)data_and_pad, (unsigned)auth->auth_pad_length)); + talloc_free(ndr); + ZERO_STRUCTP(auth); + return NT_STATUS_RPC_PROTOCOL_ERROR; } DEBUG(6,(__location__ ": auth_pad_length %u\n", @@ -143,6 +170,10 @@ NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt, talloc_steal(mem_ctx, auth->credentials.data); talloc_free(ndr); + if (_auth_length != NULL) { + *_auth_length = auth_length; + } + return NT_STATUS_OK; } diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h index b03b9ff..f6434e7 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -187,9 +187,9 @@ const char *dcerpc_default_transport_endpoint(TALLOC_CTX *mem_ctx, * * @return - A NTSTATUS error code. */ -NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt, +NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, TALLOC_CTX *mem_ctx, - DATA_BLOB *pkt_trailer, + const DATA_BLOB *pkt_trailer, struct dcerpc_auth *auth, uint32_t *auth_length, bool auth_data_only); -- 1.9.1 From 17a7a446cf6f7e531886ade770b65fe62994fe1f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 10:24:45 +0200 Subject: [PATCH 231/323] CVE-2015-5370: s3:librpc/rpc: don't call dcerpc_pull_auth_trailer() if auth_length is 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All other paranoia checks are done within dcerpc_pull_auth_trailer() now. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/librpc/rpc/dcerpc_helpers.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index 1193baa..96074a4 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -533,16 +533,8 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, return NT_STATUS_INVALID_PARAMETER; } - /* Paranioa checks for auth_length. */ - if (pkt->auth_length > pkt->frag_length) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - if (((unsigned int)pkt->auth_length - + DCERPC_AUTH_TRAILER_LENGTH < (unsigned int)pkt->auth_length) || - ((unsigned int)pkt->auth_length - + DCERPC_AUTH_TRAILER_LENGTH < DCERPC_AUTH_TRAILER_LENGTH)) { - /* Integer wrap attempt. */ - return NT_STATUS_INFO_LENGTH_MISMATCH; + if (pkt->auth_length == 0) { + return NT_STATUS_INVALID_PARAMETER; } status = dcerpc_pull_auth_trailer(pkt, pkt, pkt_trailer, -- 1.9.1 From d5d5621b31801a6e3d11add8a30c6706a5cb876c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 16:25:48 +0200 Subject: [PATCH 232/323] CVE-2015-5370: s4:librpc/rpc: send a dcerpc_sec_verification_trailer if needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 136 ++++++++++++++++++++++++++++++++++++++++++++ source4/librpc/rpc/dcerpc.h | 5 ++ 2 files changed, 141 insertions(+) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 88a041c..5900c06 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -65,6 +65,8 @@ struct rpc_request { DATA_BLOB request_data; bool ignore_timeout; bool wait_for_sync; + bool verify_bitmask1; + bool verify_pcontext; struct { void (*callback)(struct rpc_request *); @@ -1547,6 +1549,13 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c, return; } + if (req->verify_bitmask1) { + req->p->conn->security_state.verified_bitmask1 = true; + } + if (req->verify_pcontext) { + req->p->verified_pcontext = true; + } + if (!(pkt->drep[0] & DCERPC_DREP_LE)) { req->flags |= DCERPC_PULL_BIGENDIAN; } else { @@ -1571,6 +1580,8 @@ req_done: } } +static NTSTATUS dcerpc_request_prepare_vt(struct rpc_request *req); + /* perform the send side of a async dcerpc request */ @@ -1581,6 +1592,7 @@ static struct rpc_request *dcerpc_request_send(TALLOC_CTX *mem_ctx, DATA_BLOB *stub_data) { struct rpc_request *req; + NTSTATUS status; req = talloc_zero(mem_ctx, struct rpc_request); if (req == NULL) { @@ -1603,6 +1615,12 @@ static struct rpc_request *dcerpc_request_send(TALLOC_CTX *mem_ctx, req->request_data.length = stub_data->length; req->request_data.data = stub_data->data; + status = dcerpc_request_prepare_vt(req); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + DLIST_ADD_END(p->conn->request_queue, req); talloc_set_destructor(req, dcerpc_req_dequeue); @@ -1617,6 +1635,124 @@ static struct rpc_request *dcerpc_request_send(TALLOC_CTX *mem_ctx, return req; } +static NTSTATUS dcerpc_request_prepare_vt(struct rpc_request *req) +{ + struct dcecli_security *sec = &req->p->conn->security_state; + struct dcerpc_sec_verification_trailer *t; + struct dcerpc_sec_vt *c = NULL; + struct ndr_push *ndr = NULL; + enum ndr_err_code ndr_err; + + if (sec->auth_info == NULL) { + return NT_STATUS_OK; + } + + if (sec->auth_info->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { + return NT_STATUS_OK; + } + + t = talloc_zero(req, struct dcerpc_sec_verification_trailer); + if (t == NULL) { + return NT_STATUS_NO_MEMORY; + } + + if (!sec->verified_bitmask1) { + t->commands = talloc_realloc(t, t->commands, + struct dcerpc_sec_vt, + t->count.count + 1); + if (t->commands == NULL) { + return NT_STATUS_NO_MEMORY; + } + c = &t->commands[t->count.count++]; + ZERO_STRUCTP(c); + + c->command = DCERPC_SEC_VT_COMMAND_BITMASK1; + if (req->p->conn->flags & DCERPC_PROPOSE_HEADER_SIGNING) { + c->u.bitmask1 = DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING; + } + req->verify_bitmask1 = true; + } + + if (!req->p->verified_pcontext) { + t->commands = talloc_realloc(t, t->commands, + struct dcerpc_sec_vt, + t->count.count + 1); + if (t->commands == NULL) { + return NT_STATUS_NO_MEMORY; + } + c = &t->commands[t->count.count++]; + ZERO_STRUCTP(c); + + c->command = DCERPC_SEC_VT_COMMAND_PCONTEXT; + c->u.pcontext.abstract_syntax = req->p->syntax; + c->u.pcontext.transfer_syntax = req->p->transfer_syntax; + + req->verify_pcontext = true; + } + + if (!(req->p->conn->flags & DCERPC_HEADER_SIGNING)) { + t->commands = talloc_realloc(t, t->commands, + struct dcerpc_sec_vt, + t->count.count + 1); + if (t->commands == NULL) { + return NT_STATUS_NO_MEMORY; + } + c = &t->commands[t->count.count++]; + ZERO_STRUCTP(c); + + c->command = DCERPC_SEC_VT_COMMAND_HEADER2; + c->u.header2.ptype = DCERPC_PKT_REQUEST; + if (req->p->conn->flags & DCERPC_PUSH_BIGENDIAN) { + c->u.header2.drep[0] = 0; + } else { + c->u.header2.drep[0] = DCERPC_DREP_LE; + } + c->u.header2.drep[1] = 0; + c->u.header2.drep[2] = 0; + c->u.header2.drep[3] = 0; + c->u.header2.call_id = req->call_id; + c->u.header2.context_id = req->p->context_id; + c->u.header2.opnum = req->opnum; + } + + if (t->count.count == 0) { + TALLOC_FREE(t); + return NT_STATUS_OK; + } + + c = &t->commands[t->count.count - 1]; + c->command |= DCERPC_SEC_VT_COMMAND_END; + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer, t); + } + + ndr = ndr_push_init_ctx(req); + if (ndr == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* + * for now we just copy and append + */ + + ndr_err = ndr_push_bytes(ndr, req->request_data.data, + req->request_data.length); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + + ndr_err = ndr_push_dcerpc_sec_verification_trailer(ndr, + NDR_SCALARS | NDR_BUFFERS, + t); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + req->request_data = ndr_push_blob(ndr); + + return NT_STATUS_OK; +} + /* Send a request using the transport */ diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 6385dd0..707e4cc 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -51,6 +51,9 @@ struct dcecli_security { /* get the session key */ NTSTATUS (*session_key)(struct dcecli_connection *, DATA_BLOB *); + + bool verified_bitmask1; + }; /* @@ -126,6 +129,8 @@ struct dcerpc_pipe { */ bool inhibit_timeout_processing; bool timed_out; + + bool verified_pcontext; }; /* default timeout for all rpc requests, in seconds */ -- 1.9.1 From 3b873916ac48e4a36d842564d26053d104bc6b18 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 233/323] CVE-2015-5370: s4:librpc/rpc: maintain dcecli_security->auth_{type,level,context_id} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will simplify the following commits and avoids dereferencing dcecli_security->auth_info. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 3 +++ source4/librpc/rpc/dcerpc.h | 3 +++ source4/librpc/rpc/dcerpc_auth.c | 10 +++++++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 5900c06..1cfc2ca 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -141,6 +141,9 @@ static struct dcecli_connection *dcerpc_connection_init(TALLOC_CTX *mem_ctx, } c->call_id = 1; + c->security_state.auth_type = DCERPC_AUTH_TYPE_NONE; + c->security_state.auth_level = DCERPC_AUTH_LEVEL_NONE; + c->security_state.auth_context_id = 0; c->security_state.auth_info = NULL; c->security_state.session_key = dcerpc_generic_session_key; c->security_state.generic_state = NULL; diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 707e4cc..c7299fe 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -46,6 +46,9 @@ struct dcecli_connection; struct gensec_settings; struct cli_credentials; struct dcecli_security { + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + uint32_t auth_context_id; struct dcerpc_auth *auth_info; struct gensec_security *generic_state; diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index 2d60d38..aec72ca 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -353,14 +353,18 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx, return c; } + sec->auth_type = auth_type; + sec->auth_level = auth_level, + sec->auth_context_id = random(); + sec->auth_info = talloc(p, struct dcerpc_auth); if (composite_nomem(sec->auth_info, c)) return c; - sec->auth_info->auth_type = auth_type; - sec->auth_info->auth_level = auth_level, + sec->auth_info->auth_type = sec->auth_type; + sec->auth_info->auth_level = sec->auth_level, sec->auth_info->auth_pad_length = 0; sec->auth_info->auth_reserved = 0; - sec->auth_info->auth_context_id = random(); + sec->auth_info->auth_context_id = sec->auth_context_id; sec->auth_info->credentials = data_blob(NULL, 0); /* The status value here, from GENSEC is vital to the security -- 1.9.1 From bcbcc439df975e640e9c55a16b6c2bc93b9a283b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 234/323] CVE-2015-5370: s4:librpc/rpc: use auth_context_id = 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In future we want to verify that the auth_context_id from the server is what we expect. As Samba (<= 4.2.3) use a hardcoded value of 1 in responses, we need to use that. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc_auth.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index aec72ca..443c758 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -355,7 +355,12 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx, sec->auth_type = auth_type; sec->auth_level = auth_level, - sec->auth_context_id = random(); + /* + * We use auth_context_id = 1 as some older + * Samba versions (<= 4.2.3) use that value hardcoded + * in a response. + */ + sec->auth_context_id = 1; sec->auth_info = talloc(p, struct dcerpc_auth); if (composite_nomem(sec->auth_info, c)) return c; -- 1.9.1 From 2cd7f5a5084d085bcb87af95fb29a7d0a58d6c95 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 235/323] CVE-2015-5370: s4:librpc/rpc: use a local auth_info variable in ncacn_push_request_sign() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should avoid using the global dcecli_security->auth_info struct for individual requests. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 1cfc2ca..bf9ee0c 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -837,13 +837,13 @@ static NTSTATUS ncacn_push_request_sign(struct dcecli_connection *c, size_t payload_length; enum ndr_err_code ndr_err; size_t hdr_size = DCERPC_REQUEST_LENGTH; + struct dcerpc_auth auth_info = { + .auth_type = c->security_state.auth_type, + .auth_level = c->security_state.auth_level, + .auth_context_id = c->security_state.auth_context_id, + }; - /* non-signed packets are simpler */ - if (c->security_state.auth_info == NULL) { - return ncacn_push_auth(blob, mem_ctx, pkt, NULL); - } - - switch (c->security_state.auth_info->auth_level) { + switch (c->security_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: case DCERPC_AUTH_LEVEL_INTEGRITY: if (sig_size == 0) { @@ -890,21 +890,18 @@ static NTSTATUS ncacn_push_request_sign(struct dcecli_connection *c, ndr_push_align() as that is relative to the start of the whole packet, whereas w2k8 wants it relative to the start of the stub */ - c->security_state.auth_info->auth_pad_length = + auth_info.auth_pad_length = DCERPC_AUTH_PAD_LENGTH(pkt->u.request.stub_and_verifier.length); - ndr_err = ndr_push_zero(ndr, c->security_state.auth_info->auth_pad_length); + ndr_err = ndr_push_zero(ndr, auth_info.auth_pad_length); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } payload_length = pkt->u.request.stub_and_verifier.length + - c->security_state.auth_info->auth_pad_length; - - /* we start without signature, it will appended later */ - c->security_state.auth_info->credentials = data_blob(NULL,0); + auth_info.auth_pad_length; /* add the auth verifier */ - ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, c->security_state.auth_info); + ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth_info); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } @@ -922,7 +919,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcecli_connection *c, dcerpc_set_auth_length(blob, sig_size); /* sign or seal the packet */ - switch (c->security_state.auth_info->auth_level) { + switch (c->security_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: status = gensec_seal_packet(c->security_state.generic_state, mem_ctx, @@ -962,7 +959,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcecli_connection *c, DEBUG(3,("ncacn_push_request_sign: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n", (unsigned) creds2.length, (unsigned) sig_size, - (unsigned) c->security_state.auth_info->auth_pad_length, + (unsigned) auth_info.auth_pad_length, (unsigned) pkt->u.request.stub_and_verifier.length)); dcerpc_set_frag_length(blob, blob->length + creds2.length); dcerpc_set_auth_length(blob, creds2.length); -- 1.9.1 From 34f2032f04c2aba9bd1d7ae6c9e0304222d47586 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 236/323] CVE-2015-5370: s4:librpc/rpc: avoid using hs->p->conn->security_state.auth_info in dcerpc_bh_auth_info() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index bf9ee0c..6ded7db 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -225,12 +225,8 @@ static void dcerpc_bh_auth_info(struct dcerpc_binding_handle *h, return; } - if (hs->p->conn->security_state.auth_info == NULL) { - return; - } - - *auth_type = hs->p->conn->security_state.auth_info->auth_type; - *auth_level = hs->p->conn->security_state.auth_info->auth_level; + *auth_type = hs->p->conn->security_state.auth_type; + *auth_level = hs->p->conn->security_state.auth_level; } struct dcerpc_bh_raw_call_state { -- 1.9.1 From ba497043aa38cea41ca6509194b40afd0214aae2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 237/323] CVE-2015-5370: s4:librpc/rpc: avoid using c->security_state.auth_info in ncacn_pull_request_auth() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 6ded7db..2ecc3fe 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -744,12 +744,7 @@ static NTSTATUS ncacn_pull_request_auth(struct dcecli_connection *c, TALLOC_CTX struct dcerpc_auth auth; uint32_t auth_length; - if (!c->security_state.auth_info || - !c->security_state.generic_state) { - return NT_STATUS_OK; - } - - switch (c->security_state.auth_info->auth_level) { + switch (c->security_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: case DCERPC_AUTH_LEVEL_INTEGRITY: break; @@ -769,6 +764,14 @@ static NTSTATUS ncacn_pull_request_auth(struct dcecli_connection *c, TALLOC_CTX return NT_STATUS_INVALID_LEVEL; } + if (pkt->auth_length == 0) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + if (c->security_state.generic_state == NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + status = dcerpc_pull_auth_trailer(pkt, mem_ctx, &pkt->u.response.stub_and_verifier, &auth, &auth_length, false); @@ -777,7 +780,7 @@ static NTSTATUS ncacn_pull_request_auth(struct dcecli_connection *c, TALLOC_CTX pkt->u.response.stub_and_verifier.length -= auth_length; /* check signature or unseal the packet */ - switch (c->security_state.auth_info->auth_level) { + switch (c->security_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: status = gensec_unseal_packet(c->security_state.generic_state, raw_packet->data + DCERPC_REQUEST_LENGTH, -- 1.9.1 From 088e714838bde36744a26c450677a057db97b284 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 238/323] CVE-2015-5370: s4:librpc/rpc: always use ncacn_pull_request_auth() for DCERPC_PKT_RESPONSE pdus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It handles the case of DCERPC_AUTH_TYPE_NONE just fine and it makes it possible to do some verification in future. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 2ecc3fe..ca964c7 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1464,8 +1464,7 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c, to run the auth routines so that we don't get the sign/seal info out of step with the server */ - if (c->security_state.auth_info && c->security_state.generic_state && - pkt->ptype == DCERPC_PKT_RESPONSE) { + if (pkt->ptype == DCERPC_PKT_RESPONSE) { status = ncacn_pull_request_auth(c, raw_packet->data, raw_packet, pkt); } -- 1.9.1 From 1c04f0150b6f159608268310097f9357b92de299 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 239/323] CVE-2015-5370: s4:librpc/rpc: avoid dereferencing sec->auth_info in dcerpc_request_prepare_vt() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index ca964c7..319741f 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1641,11 +1641,7 @@ static NTSTATUS dcerpc_request_prepare_vt(struct rpc_request *req) struct ndr_push *ndr = NULL; enum ndr_err_code ndr_err; - if (sec->auth_info == NULL) { - return NT_STATUS_OK; - } - - if (sec->auth_info->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { + if (sec->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { return NT_STATUS_OK; } -- 1.9.1 From e00a5837ee22a35c966d9d79f826016065159da6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 240/323] CVE-2015-5370: s4:librpc/rpc: simplify checks if gensec is used in dcerpc_ship_next_request() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 319741f..5113f63 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1776,25 +1776,9 @@ static void dcerpc_ship_next_request(struct dcecli_connection *c) need_async = true; } - if (c->security_state.auth_info && - c->security_state.generic_state) - { - struct gensec_security *gensec = c->security_state.generic_state; - - switch (c->security_state.auth_info->auth_level) { - case DCERPC_AUTH_LEVEL_PRIVACY: - case DCERPC_AUTH_LEVEL_INTEGRITY: - can_async = gensec_have_feature(gensec, + if (c->security_state.auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { + can_async = gensec_have_feature(c->security_state.generic_state, GENSEC_FEATURE_ASYNC_REPLIES); - break; - case DCERPC_AUTH_LEVEL_CONNECT: - case DCERPC_AUTH_LEVEL_NONE: - can_async = true; - break; - default: - can_async = false; - break; - } } if (need_async && !can_async) { @@ -1814,8 +1798,7 @@ static void dcerpc_ship_next_request(struct dcecli_connection *c) request header size */ chunk_size = p->conn->srv_max_recv_frag; chunk_size -= DCERPC_REQUEST_LENGTH; - if (c->security_state.auth_info && - c->security_state.generic_state) { + if (c->security_state.auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { size_t max_payload = chunk_size; max_payload -= DCERPC_AUTH_TRAILER_LENGTH; -- 1.9.1 From 9cfea59df6097ebe2bf1a102e778c86c17850280 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 241/323] CVE-2015-5370: s4:librpc/rpc: avoid using dcecli_security->auth_info and use per request values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now avoid reusing the same auth_info structure for incoming and outgoing values. We need to make sure that the remote server doesn't overwrite our own values. This will trigger some failures with our currently broken server, which will be fixed in the next commits. The broken server requires an dcerpc_auth structure with no credentials in order to do an alter_context request that just creates a presentation context without doing authentication. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- selftest/knownfail | 4 +++ source4/librpc/rpc/dcerpc.c | 29 ++++++++-------- source4/librpc/rpc/dcerpc.h | 6 +++- source4/librpc/rpc/dcerpc_auth.c | 71 +++++++++++++++++++++++----------------- 4 files changed, 66 insertions(+), 44 deletions(-) diff --git a/selftest/knownfail b/selftest/knownfail index 1678cd0..d707983 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -1,3 +1,7 @@ +# These are temporary failures until the next commits fix it again +# +^samba4.rpc.altercontext.*seal # tmp +^samba4.rpc.altercontext.*ncalrpc # tmp # This file contains a list of regular expressions matching the names of # tests that are expected to fail. # diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 5113f63..908fed2 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -144,7 +144,6 @@ static struct dcecli_connection *dcerpc_connection_init(TALLOC_CTX *mem_ctx, c->security_state.auth_type = DCERPC_AUTH_TYPE_NONE; c->security_state.auth_level = DCERPC_AUTH_LEVEL_NONE; c->security_state.auth_context_id = 0; - c->security_state.auth_info = NULL; c->security_state.session_key = dcerpc_generic_session_key; c->security_state.generic_state = NULL; c->flags = 0; @@ -1226,7 +1225,7 @@ struct tevent_req *dcerpc_bind_send(TALLOC_CTX *mem_ctx, /* construct the NDR form of the packet */ status = ncacn_push_auth(&blob, state, &pkt, - p->conn->security_state.auth_info); + p->conn->security_state.tmp_auth_info.out); if (tevent_req_nterror(req, status)) { return tevent_req_post(req, ev); } @@ -1299,6 +1298,7 @@ static void dcerpc_bind_recv_handler(struct rpc_request *subreq, tevent_req_data(req, struct dcerpc_bind_state); struct dcecli_connection *conn = state->p->conn; + struct dcecli_security *sec = &conn->security_state; struct dcerpc_binding *b = NULL; NTSTATUS status; uint32_t flags; @@ -1372,11 +1372,13 @@ static void dcerpc_bind_recv_handler(struct rpc_request *subreq, } /* the bind_ack might contain a reply set of credentials */ - if (conn->security_state.auth_info && pkt->u.bind_ack.auth_info.length) { + if (pkt->auth_length != 0 && sec->tmp_auth_info.in != NULL) { uint32_t auth_length; - status = dcerpc_pull_auth_trailer(pkt, conn, &pkt->u.bind_ack.auth_info, - conn->security_state.auth_info, &auth_length, true); + status = dcerpc_pull_auth_trailer(pkt, sec->tmp_auth_info.mem, + &pkt->u.bind_ack.auth_info, + sec->tmp_auth_info.in, + &auth_length, true); if (tevent_req_nterror(req, status)) { return; } @@ -1426,9 +1428,8 @@ NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p, } /* construct the NDR form of the packet */ - status = ncacn_push_auth(&blob, mem_ctx, - &pkt, - p->conn->security_state.auth_info); + status = ncacn_push_auth(&blob, mem_ctx, &pkt, + p->conn->security_state.tmp_auth_info.out); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -2234,7 +2235,7 @@ struct tevent_req *dcerpc_alter_context_send(TALLOC_CTX *mem_ctx, /* construct the NDR form of the packet */ status = ncacn_push_auth(&blob, state, &pkt, - p->conn->security_state.auth_info); + p->conn->security_state.tmp_auth_info.out); if (tevent_req_nterror(req, status)) { return tevent_req_post(req, ev); } @@ -2307,6 +2308,7 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, tevent_req_data(req, struct dcerpc_alter_context_state); struct dcecli_connection *conn = state->p->conn; + struct dcecli_security *sec = &conn->security_state; NTSTATUS status; /* @@ -2365,12 +2367,13 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, } /* the alter_resp might contain a reply set of credentials */ - if (conn->security_state.auth_info && - pkt->u.alter_resp.auth_info.length) { + if (pkt->auth_length != 0 && sec->tmp_auth_info.in != NULL) { uint32_t auth_length; - status = dcerpc_pull_auth_trailer(pkt, conn, &pkt->u.alter_resp.auth_info, - conn->security_state.auth_info, &auth_length, true); + status = dcerpc_pull_auth_trailer(pkt, sec->tmp_auth_info.mem, + &pkt->u.alter_resp.auth_info, + sec->tmp_auth_info.in, + &auth_length, true); if (tevent_req_nterror(req, status)) { return; } diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index c7299fe..39d28a6 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -49,7 +49,11 @@ struct dcecli_security { enum dcerpc_AuthType auth_type; enum dcerpc_AuthLevel auth_level; uint32_t auth_context_id; - struct dcerpc_auth *auth_info; + struct { + struct dcerpc_auth *out; + struct dcerpc_auth *in; + TALLOC_CTX *mem; + } tmp_auth_info; struct gensec_security *generic_state; /* get the session key */ diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index 443c758..15a843b 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -124,7 +124,8 @@ _PUBLIC_ NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p, struct bind_auth_state { struct dcerpc_pipe *pipe; - DATA_BLOB credentials; + struct dcerpc_auth out_auth_info; + struct dcerpc_auth in_auth_info; bool more_processing; /* Is there anything more to do after the * first bind itself received? */ }; @@ -141,6 +142,12 @@ static void bind_auth_next_step(struct composite_context *c) state = talloc_get_type(c->private_data, struct bind_auth_state); sec = &state->pipe->conn->security_state; + state->out_auth_info = (struct dcerpc_auth) { + .auth_type = sec->auth_type, + .auth_level = sec->auth_level, + .auth_context_id = sec->auth_context_id, + }; + /* The status value here, from GENSEC is vital to the security * of the system. Even if the other end accepts, if GENSEC * claims 'MORE_PROCESSING_REQUIRED' then you must keep @@ -156,16 +163,14 @@ static void bind_auth_next_step(struct composite_context *c) c->status = gensec_update_ev(sec->generic_state, state, state->pipe->conn->event_ctx, - sec->auth_info->credentials, - &state->credentials); + state->in_auth_info.credentials, + &state->out_auth_info.credentials); if (state->pipe->timed_out) { composite_error(c, NT_STATUS_IO_TIMEOUT); return; } state->pipe->inhibit_timeout_processing = false; - data_blob_free(&sec->auth_info->credentials); - if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { more_processing = true; c->status = NT_STATUS_OK; @@ -173,18 +178,21 @@ static void bind_auth_next_step(struct composite_context *c) if (!composite_is_ok(c)) return; - if (state->credentials.length == 0) { + if (state->out_auth_info.credentials.length == 0) { composite_done(c); return; } - sec->auth_info->credentials = state->credentials; + state->in_auth_info = (struct dcerpc_auth) { + .auth_type = DCERPC_AUTH_TYPE_NONE, + }; + sec->tmp_auth_info.in = &state->in_auth_info; + sec->tmp_auth_info.mem = state; + sec->tmp_auth_info.out = &state->out_auth_info; if (!more_processing) { /* NO reply expected, so just send it */ c->status = dcerpc_auth3(state->pipe, state); - data_blob_free(&state->credentials); - sec->auth_info->credentials = data_blob(NULL, 0); if (!composite_is_ok(c)) return; composite_done(c); @@ -197,8 +205,6 @@ static void bind_auth_next_step(struct composite_context *c) state->pipe, &state->pipe->syntax, &state->pipe->transfer_syntax); - data_blob_free(&state->credentials); - sec->auth_info->credentials = data_blob(NULL, 0); if (composite_nomem(subreq, c)) return; tevent_req_set_callback(subreq, bind_auth_recv_alter, c); } @@ -209,6 +215,11 @@ static void bind_auth_recv_alter(struct tevent_req *subreq) struct composite_context *c = tevent_req_callback_data(subreq, struct composite_context); + struct bind_auth_state *state = talloc_get_type(c->private_data, + struct bind_auth_state); + struct dcecli_security *sec = &state->pipe->conn->security_state; + + ZERO_STRUCT(sec->tmp_auth_info); c->status = dcerpc_alter_context_recv(subreq); TALLOC_FREE(subreq); @@ -225,14 +236,15 @@ static void bind_auth_recv_bindreply(struct tevent_req *subreq) struct composite_context); struct bind_auth_state *state = talloc_get_type(c->private_data, struct bind_auth_state); + struct dcecli_security *sec = &state->pipe->conn->security_state; + + ZERO_STRUCT(sec->tmp_auth_info); c->status = dcerpc_bind_recv(subreq); TALLOC_FREE(subreq); if (!composite_is_ok(c)) return; if (state->pipe->conn->flags & DCERPC_HEADER_SIGNING) { - struct dcecli_security *sec = &state->pipe->conn->security_state; - gensec_want_feature(sec->generic_state, GENSEC_FEATURE_SIGN_PKT_HEADER); } @@ -362,15 +374,11 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx, */ sec->auth_context_id = 1; - sec->auth_info = talloc(p, struct dcerpc_auth); - if (composite_nomem(sec->auth_info, c)) return c; - - sec->auth_info->auth_type = sec->auth_type; - sec->auth_info->auth_level = sec->auth_level, - sec->auth_info->auth_pad_length = 0; - sec->auth_info->auth_reserved = 0; - sec->auth_info->auth_context_id = sec->auth_context_id; - sec->auth_info->credentials = data_blob(NULL, 0); + state->out_auth_info = (struct dcerpc_auth) { + .auth_type = sec->auth_type, + .auth_level = sec->auth_level, + .auth_context_id = sec->auth_context_id, + }; /* The status value here, from GENSEC is vital to the security * of the system. Even if the other end accepts, if GENSEC @@ -386,8 +394,8 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx, state->pipe->timed_out = false; c->status = gensec_update_ev(sec->generic_state, state, p->conn->event_ctx, - sec->auth_info->credentials, - &state->credentials); + data_blob_null, + &state->out_auth_info.credentials); if (state->pipe->timed_out) { composite_error(c, NT_STATUS_IO_TIMEOUT); return c; @@ -403,25 +411,28 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx, state->more_processing = NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED); - if (state->credentials.length == 0) { + if (state->out_auth_info.credentials.length == 0) { composite_done(c); return c; } - sec->auth_info->credentials = state->credentials; - if (gensec_have_feature(sec->generic_state, GENSEC_FEATURE_SIGN_PKT_HEADER)) { - if (auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { + if (sec->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { state->pipe->conn->flags |= DCERPC_PROPOSE_HEADER_SIGNING; } } + state->in_auth_info = (struct dcerpc_auth) { + .auth_type = DCERPC_AUTH_TYPE_NONE, + }; + sec->tmp_auth_info.in = &state->in_auth_info; + sec->tmp_auth_info.mem = state; + sec->tmp_auth_info.out = &state->out_auth_info; + /* The first request always is a dcerpc_bind. The subsequent ones * depend on gensec results */ subreq = dcerpc_bind_send(state, p->conn->event_ctx, p, &syntax, &transfer_syntax); - data_blob_free(&state->credentials); - sec->auth_info->credentials = data_blob(NULL, 0); if (composite_nomem(subreq, c)) return c; tevent_req_set_callback(subreq, bind_auth_recv_bindreply, c); -- 1.9.1 From bb856d88c60ed74c06d5558312bca3af14e491cb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 242/323] CVE-2015-5370: s4:librpc/rpc: finally verify the server uses the expected auth_{type,level,context_id} values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 12 ++++++++++++ source4/librpc/rpc/dcerpc_auth.c | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 908fed2..9649249 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -778,6 +778,18 @@ static NTSTATUS ncacn_pull_request_auth(struct dcecli_connection *c, TALLOC_CTX pkt->u.response.stub_and_verifier.length -= auth_length; + if (auth.auth_type != c->security_state.auth_type) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + if (auth.auth_level != c->security_state.auth_level) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + if (auth.auth_context_id != c->security_state.auth_context_id) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + /* check signature or unseal the packet */ switch (c->security_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index 15a843b..d617b07 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -142,6 +142,21 @@ static void bind_auth_next_step(struct composite_context *c) state = talloc_get_type(c->private_data, struct bind_auth_state); sec = &state->pipe->conn->security_state; + if (state->in_auth_info.auth_type != sec->auth_type) { + composite_error(c, NT_STATUS_RPC_PROTOCOL_ERROR); + return; + } + + if (state->in_auth_info.auth_level != sec->auth_level) { + composite_error(c, NT_STATUS_RPC_PROTOCOL_ERROR); + return; + } + + if (state->in_auth_info.auth_context_id != sec->auth_context_id) { + composite_error(c, NT_STATUS_RPC_PROTOCOL_ERROR); + return; + } + state->out_auth_info = (struct dcerpc_auth) { .auth_type = sec->auth_type, .auth_level = sec->auth_level, -- 1.9.1 From bd2fef61a55bfa841bc84ea00f662407643d760e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 243/323] CVE-2015-5370: librpc/rpc: add a dcerpc_verify_ncacn_packet_header() helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- librpc/rpc/dcerpc_util.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ librpc/rpc/rpc_common.h | 5 ++++ 2 files changed, 78 insertions(+) diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index 8f0ebd0..2f81447 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -177,6 +177,79 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, return NT_STATUS_OK; } +/** +* @brief Verify the fields in ncacn_packet header. +* +* @param pkt - The ncacn_packet strcuture +* @param ptype - The expected PDU type +* @param max_auth_info - The maximum size of a possible auth trailer +* @param required_flags - The required flags for the pdu. +* @param optional_flags - The possible optional flags for the pdu. +* +* @return - A NTSTATUS error code. +*/ +NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt, + enum dcerpc_pkt_type ptype, + size_t max_auth_info, + uint8_t required_flags, + uint8_t optional_flags) +{ + if (pkt->rpc_vers != 5) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + if (pkt->rpc_vers_minor != 0) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + if (pkt->auth_length > pkt->frag_length) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + if (pkt->ptype != ptype) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + if (max_auth_info > UINT16_MAX) { + return NT_STATUS_INTERNAL_ERROR; + } + + if (pkt->auth_length > 0) { + size_t max_auth_length; + + if (max_auth_info <= DCERPC_AUTH_TRAILER_LENGTH) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + max_auth_length = max_auth_info - DCERPC_AUTH_TRAILER_LENGTH; + + if (pkt->auth_length > max_auth_length) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + } + + if ((pkt->pfc_flags & required_flags) != required_flags) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + if (pkt->pfc_flags & ~(optional_flags|required_flags)) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + if (pkt->drep[0] & ~DCERPC_DREP_LE) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + if (pkt->drep[1] != 0) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + if (pkt->drep[2] != 0) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + if (pkt->drep[3] != 0) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + return NT_STATUS_OK; +} + struct dcerpc_read_ncacn_packet_state { #if 0 struct { diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h index f6434e7..bd0985a 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -193,6 +193,11 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, struct dcerpc_auth *auth, uint32_t *auth_length, bool auth_data_only); +NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt, + enum dcerpc_pkt_type ptype, + size_t max_auth_info, + uint8_t required_flags, + uint8_t optional_flags); struct tevent_req *dcerpc_read_ncacn_packet_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct tstream_context *stream); -- 1.9.1 From e828f42c5a1527e5ea68d4826490916a204cf7e6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 244/323] CVE-2015-5370: s3:rpc_client: move AS/U hack to the top of cli_pipe_validate_current_pdu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index f642d30..f31a330 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -401,6 +401,19 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, */ *rdata = *pdu; + if ((pkt->ptype == DCERPC_PKT_BIND_ACK) && + !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) { + /* + * TODO: do we still need this hack which was introduced + * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0. + * + * I don't even know what AS/U might be... + */ + DEBUG(5, (__location__ ": bug in server (AS/U?), setting " + "fragment first/last ON.\n")); + pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + } + /* Ensure we have the correct type. */ switch (pkt->ptype) { case DCERPC_PKT_ALTER_RESP: @@ -505,17 +518,6 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, return NT_STATUS_RPC_PROTOCOL_ERROR; } - /* Do this just before return - we don't want to modify any rpc header - data before now as we may have needed to do cryptographic actions on - it before. */ - - if ((pkt->ptype == DCERPC_PKT_BIND_ACK) && - !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) { - DEBUG(5, (__location__ ": bug in server (AS/U?), setting " - "fragment first/last ON.\n")); - pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; - } - return NT_STATUS_OK; } -- 1.9.1 From fd0799b95dc59db4c48a4a7ad61ec9c3c6914962 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 245/323] CVE-2015-5370: s3:rpc_client: remove useless frag_length check in rpc_api_pipe_got_pdu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dcerpc_pull_ncacn_packet() already verifies this. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index f31a330..6e0a7ea 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -881,14 +881,6 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) return; } - if (state->incoming_frag.length != state->pkt->frag_length) { - DEBUG(5, ("Incorrect pdu length %u, expected %u\n", - (unsigned int)state->incoming_frag.length, - (unsigned int)state->pkt->frag_length)); - tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; - } - status = cli_pipe_validate_current_pdu(state, state->cli, state->pkt, &state->incoming_frag, -- 1.9.1 From 0b22b2769184a3c58a7c7e6bf032d2755587dd1d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 246/323] CVE-2015-5370: s4:librpc/rpc: make use of dcerpc_map_ack_reason() in dcerpc_bind_recv_handler() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should give better error messages if the server doesn't support a specific abstract/transfer syntax. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 9649249..549a77d 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1345,13 +1345,21 @@ static void dcerpc_bind_recv_handler(struct rpc_request *subreq, } if ((pkt->ptype != DCERPC_PKT_BIND_ACK) || - (pkt->u.bind_ack.num_results == 0) || - (pkt->u.bind_ack.ctx_list[0].result != 0)) { + (pkt->u.bind_ack.num_results == 0)) { state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR; tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT); return; } + if (pkt->u.bind_ack.ctx_list[0].result != 0) { + status = dcerpc_map_ack_reason(&pkt->u.bind_ack.ctx_list[0]); + DEBUG(2,("dcerpc: bind_ack failed - reason %d - %s\n", + pkt->u.bind_ack.ctx_list[0].reason.value, + nt_errstr(status))); + tevent_req_nterror(req, status); + return; + } + /* * DCE-RPC 1.1 (c706) specifies * CONST_MUST_RCV_FRAG_SIZE as 1432 -- 1.9.1 From d110625af96af4a81a57430a5fcb32f8a46ebee0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 247/323] CVE-2015-5370: s4:librpc/rpc: handle DCERPC_PKT_FAULT before anything else in dcerpc_alter_context_recv_handler() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 549a77d..063ac34 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -2350,17 +2350,6 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, */ tevent_req_defer_callback(req, state->ev); - if (pkt->ptype == DCERPC_PKT_ALTER_RESP && - pkt->u.alter_resp.num_results == 1 && - pkt->u.alter_resp.ctx_list[0].result != 0) { - status = dcerpc_map_ack_reason(&pkt->u.alter_resp.ctx_list[0]); - DEBUG(2,("dcerpc: alter_resp failed - reason %d - %s\n", - pkt->u.alter_resp.ctx_list[0].reason.value, - nt_errstr(status))); - tevent_req_nterror(req, status); - return; - } - if (pkt->ptype == DCERPC_PKT_FAULT) { DEBUG(5,("dcerpc: alter_resp - rpc fault: %s\n", dcerpc_errstr(state, pkt->u.fault.status))); @@ -2378,6 +2367,17 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, return; } + if (pkt->ptype == DCERPC_PKT_ALTER_RESP && + pkt->u.alter_resp.num_results == 1 && + pkt->u.alter_resp.ctx_list[0].result != 0) { + status = dcerpc_map_ack_reason(&pkt->u.alter_resp.ctx_list[0]); + DEBUG(2,("dcerpc: alter_resp failed - reason %d - %s\n", + pkt->u.alter_resp.ctx_list[0].reason.value, + nt_errstr(status))); + tevent_req_nterror(req, status); + return; + } + if (pkt->ptype != DCERPC_PKT_ALTER_RESP || pkt->u.alter_resp.num_results == 0 || pkt->u.alter_resp.ctx_list[0].result != 0) { -- 1.9.1 From 8789eb9f03678867dce5cebce20ec9fb4ee5f02e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 27 Jun 2015 10:31:48 +0200 Subject: [PATCH 248/323] CVE-2015-5370: s4:librpc/rpc: use dcerpc_verify_ncacn_packet_header() to verify BIND_ACK,ALTER_RESP,RESPONSE pdus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 56 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 063ac34..567b4dc 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -743,6 +743,15 @@ static NTSTATUS ncacn_pull_request_auth(struct dcecli_connection *c, TALLOC_CTX struct dcerpc_auth auth; uint32_t auth_length; + status = dcerpc_verify_ncacn_packet_header(pkt, DCERPC_PKT_RESPONSE, + pkt->u.response.stub_and_verifier.length, + 0, /* required_flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + switch (c->security_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: case DCERPC_AUTH_LEVEL_INTEGRITY: @@ -1344,8 +1353,20 @@ static void dcerpc_bind_recv_handler(struct rpc_request *subreq, return; } - if ((pkt->ptype != DCERPC_PKT_BIND_ACK) || - (pkt->u.bind_ack.num_results == 0)) { + status = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_BIND_ACK, + pkt->u.bind_ack.auth_info.length, + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST, + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN); + if (!NT_STATUS_IS_OK(status)) { + state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR; + tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT); + return; + } + + if (pkt->u.bind_ack.num_results != 1) { state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR; tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT); return; @@ -2367,25 +2388,34 @@ static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq, return; } - if (pkt->ptype == DCERPC_PKT_ALTER_RESP && - pkt->u.alter_resp.num_results == 1 && - pkt->u.alter_resp.ctx_list[0].result != 0) { - status = dcerpc_map_ack_reason(&pkt->u.alter_resp.ctx_list[0]); - DEBUG(2,("dcerpc: alter_resp failed - reason %d - %s\n", - pkt->u.alter_resp.ctx_list[0].reason.value, - nt_errstr(status))); - tevent_req_nterror(req, status); + status = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_ALTER_RESP, + pkt->u.alter_resp.auth_info.length, + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST, + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN); + if (!NT_STATUS_IS_OK(status)) { + state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR; + tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT); return; } - if (pkt->ptype != DCERPC_PKT_ALTER_RESP || - pkt->u.alter_resp.num_results == 0 || - pkt->u.alter_resp.ctx_list[0].result != 0) { + if (pkt->u.alter_resp.num_results != 1) { state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR; tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT); return; } + if (pkt->u.alter_resp.ctx_list[0].result != 0) { + status = dcerpc_map_ack_reason(&pkt->u.alter_resp.ctx_list[0]); + DEBUG(2,("dcerpc: alter_resp failed - reason %d - %s\n", + pkt->u.alter_resp.ctx_list[0].reason.value, + nt_errstr(status))); + tevent_req_nterror(req, status); + return; + } + /* the alter_resp might contain a reply set of credentials */ if (pkt->auth_length != 0 && sec->tmp_auth_info.in != NULL) { uint32_t auth_length; -- 1.9.1 From ac59a27a2956c92204b83dd7ff91da4368367927 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2015 14:08:46 +0200 Subject: [PATCH 249/323] CVE-2015-5370: s4:librpc/rpc: protect dcerpc_request_recv_data() against too large payloads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should only allow a combined payload of a response of at max 4 MBytes. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 567b4dc..60d5b8d 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1569,6 +1569,15 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c, length = pkt->u.response.stub_and_verifier.length; + if (req->payload.length + length > DCERPC_NCACN_PAYLOAD_MAX_SIZE) { + DEBUG(2,("Unexpected total payload 0x%X > 0x%X dcerpc response\n", + (unsigned)req->payload.length + length, + DCERPC_NCACN_PAYLOAD_MAX_SIZE)); + req->fault_code = DCERPC_FAULT_OTHER; + req->status = NT_STATUS_NET_WRITE_FAULT; + goto req_done; + } + if (length > 0) { req->payload.data = talloc_realloc(req, req->payload.data, -- 1.9.1 From 10fafafa500102c01cac821ce88e5721e3b961ed Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 250/323] CVE-2015-5370: s4:rpc_server: make use of talloc_zero() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/common/reply.c | 4 ++-- source4/rpc_server/dcerpc_server.c | 32 ++++++++++++++++---------------- source4/rpc_server/handles.c | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index 93bce7a..6d23fa9 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -118,7 +118,7 @@ NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) ZERO_STRUCT(zeros); pkt.u.fault._pad = data_blob_const(zeros, sizeof(zeros)); - rep = talloc(call, struct data_blob_list_item); + rep = talloc_zero(call, struct data_blob_list_item); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -206,7 +206,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) struct data_blob_list_item *rep; struct ncacn_packet pkt; - rep = talloc(call, struct data_blob_list_item); + rep = talloc_zero(call, struct data_blob_list_item); NT_STATUS_HAVE_NO_MEMORY(rep); length = MIN(chunk_size, stub.length); diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 9250f84..ad0f1df 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -269,7 +269,7 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, /* check if this endpoint exists */ if ((ep=find_endpoint(dce_ctx, binding))==NULL) { - ep = talloc(dce_ctx, struct dcesrv_endpoint); + ep = talloc_zero(dce_ctx, struct dcesrv_endpoint); if (!ep) { return NT_STATUS_NO_MEMORY; } @@ -278,7 +278,7 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, add_ep = true; /* add mgmt interface */ - ifl = talloc(ep, struct dcesrv_if_list); + ifl = talloc_zero(ep, struct dcesrv_if_list); if (!ifl) { return NT_STATUS_NO_MEMORY; } @@ -297,7 +297,7 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, } /* talloc a new interface list element */ - ifl = talloc(ep, struct dcesrv_if_list); + ifl = talloc_zero(ep, struct dcesrv_if_list); if (!ifl) { return NT_STATUS_NO_MEMORY; } @@ -474,7 +474,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) pkt.u.bind_nak.versions = &version; pkt.u.bind_nak._pad = data_blob_null; - rep = talloc(call, struct data_blob_list_item); + rep = talloc_zero(call, struct data_blob_list_item); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -682,7 +682,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) if (iface) { /* add this context to the list of available context_ids */ - struct dcesrv_connection_context *context = talloc(call->conn, + struct dcesrv_connection_context *context = talloc_zero(call->conn, struct dcesrv_connection_context); if (context == NULL) { return dcesrv_bind_nak(call, 0); @@ -771,7 +771,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.u.bind_ack.secondary_address = ""; } pkt.u.bind_ack.num_results = 1; - pkt.u.bind_ack.ctx_list = talloc(call, struct dcerpc_ack_ctx); + pkt.u.bind_ack.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx); if (!pkt.u.bind_ack.ctx_list) { talloc_free(call->context); call->context = NULL; @@ -789,7 +789,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return dcesrv_bind_nak(call, 0); } - rep = talloc(call, struct data_blob_list_item); + rep = talloc_zero(call, struct data_blob_list_item); if (!rep) { talloc_free(call->context); call->context = NULL; @@ -868,7 +868,7 @@ static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_ } /* add this context to the list of available context_ids */ - context = talloc(call->conn, struct dcesrv_connection_context); + context = talloc_zero(call->conn, struct dcesrv_connection_context); if (context == NULL) { return NT_STATUS_NO_MEMORY; } @@ -940,7 +940,7 @@ static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, pkt.u.alter_resp.assoc_group_id = 0; } pkt.u.alter_resp.num_results = 1; - pkt.u.alter_resp.ctx_list = talloc_array(call, struct dcerpc_ack_ctx, 1); + pkt.u.alter_resp.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx); if (!pkt.u.alter_resp.ctx_list) { return NT_STATUS_NO_MEMORY; } @@ -961,7 +961,7 @@ static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, return dcesrv_fault(call, 0); } - rep = talloc(call, struct data_blob_list_item); + rep = talloc_zero(call, struct data_blob_list_item); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -1392,7 +1392,7 @@ _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, return NT_STATUS_INTERNAL_ERROR; } - dce_ctx = talloc(mem_ctx, struct dcesrv_context); + dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context); NT_STATUS_HAVE_NO_MEMORY(dce_ctx); if (uid_wrapper_enabled()) { @@ -1617,7 +1617,7 @@ static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn) struct dcesrv_sock_reply_state *substate; struct tevent_req *subreq; - substate = talloc(call, struct dcesrv_sock_reply_state); + substate = talloc_zero(call, struct dcesrv_sock_reply_state); if (!substate) { dcesrv_terminate_connection(dce_conn, "no memory"); return; @@ -1892,7 +1892,7 @@ static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, NTSTATUS status; const char *endpoint; - dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context); + dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context); NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); /* remember the endpoint of this socket */ @@ -1948,7 +1948,7 @@ static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx), endpoint); - dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context); + dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context); NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); /* remember the endpoint of this socket */ @@ -1982,7 +1982,7 @@ static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx, return NT_STATUS_INVALID_PARAMETER; } - dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context); + dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context); NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); /* remember the endpoint of this socket */ @@ -2020,7 +2020,7 @@ static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct port = atoi(endpoint); } - dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context); + dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context); NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); /* remember the endpoint of this socket */ diff --git a/source4/rpc_server/handles.c b/source4/rpc_server/handles.c index be9f16c..f99ee1d 100644 --- a/source4/rpc_server/handles.c +++ b/source4/rpc_server/handles.c @@ -46,7 +46,7 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_contex sid = &context->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; - h = talloc(context->assoc_group, struct dcesrv_handle); + h = talloc_zero(context->assoc_group, struct dcesrv_handle); if (!h) { return NULL; } -- 1.9.1 From 7bf94936fb1c81f18942e960a881bab3deebb47b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 251/323] CVE-2015-5370: s4:rpc_server: no authentication is indicated by pkt->auth_length == 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pkt->u.*.auth_info.length is not the correct thing to check. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- selftest/knownfail | 4 ---- source4/rpc_server/dcesrv_auth.c | 28 +++++++++++++++++++--------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/selftest/knownfail b/selftest/knownfail index d707983..1678cd0 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -1,7 +1,3 @@ -# These are temporary failures until the next commits fix it again -# -^samba4.rpc.altercontext.*seal # tmp -^samba4.rpc.altercontext.*ncalrpc # tmp # This file contains a list of regular expressions matching the names of # tests that are expected to fail. # diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 52fe26f..beccc78 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -46,7 +46,7 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) NTSTATUS status; uint32_t auth_length; - if (pkt->u.bind.auth_info.length == 0) { + if (pkt->auth_length == 0) { dce_conn->auth_state.auth_info = NULL; return true; } @@ -119,10 +119,15 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe NTSTATUS status; bool want_header_signing = false; - if (!call->conn->auth_state.gensec_security) { + if (call->pkt.auth_length == 0) { return NT_STATUS_OK; } + /* We can't work without an existing gensec state */ + if (!call->conn->auth_state.gensec_security) { + return NT_STATUS_INTERNAL_ERROR; + } + if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) { dce_conn->auth_state.client_hdr_signing = true; want_header_signing = true; @@ -198,10 +203,16 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) NTSTATUS status; uint32_t auth_length; - /* We can't work without an existing gensec state, and an new blob to feed it */ - if (!dce_conn->auth_state.auth_info || - !dce_conn->auth_state.gensec_security || - pkt->u.auth3.auth_info.length == 0) { + if (pkt->auth_length == 0) { + return false; + } + + if (!dce_conn->auth_state.auth_info) { + return false; + } + + /* We can't work without an existing gensec state */ + if (!dce_conn->auth_state.gensec_security) { return false; } @@ -247,7 +258,7 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) uint32_t auth_length; /* on a pure interface change there is no auth blob */ - if (pkt->u.alter.auth_info.length == 0) { + if (pkt->auth_length == 0) { return true; } @@ -282,8 +293,7 @@ NTSTATUS dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct ncacn_pack /* on a pure interface change there is no auth_info structure setup */ - if (!call->conn->auth_state.auth_info || - dce_conn->auth_state.auth_info->credentials.length == 0) { + if (call->pkt.auth_length == 0) { return NT_STATUS_OK; } -- 1.9.1 From eaa3b0f1fc41c8641bd503b628ebd4c970ecceab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 252/323] CVE-2015-5370: s4:rpc_server: check the result of dcerpc_pull_auth_trailer() in dcesrv_auth_bind() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcesrv_auth.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index beccc78..c3ba40c 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -59,6 +59,10 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.bind.auth_info, dce_conn->auth_state.auth_info, &auth_length, false); + if (!NT_STATUS_IS_OK(status)) { + return false; + } + server_credentials = cli_credentials_init(call); if (!server_credentials) { -- 1.9.1 From 8059f3611da2f152e0f85d38c56644f5cfa98cac Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 11:03:58 +0200 Subject: [PATCH 253/323] CVE-2015-5370: s4:rpc_server: maintain dcesrv_auth->auth_{type,level,context_id} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will simplify checks in the following commits and avoids derefencing dcesrv_auth->auth_info which is not always arround. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.h | 17 +++++++++++++++-- source4/rpc_server/dcesrv_auth.c | 15 +++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 66cb1f4..c525c31 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -146,6 +146,9 @@ struct dcesrv_handle { /* hold the authentication state information */ struct dcesrv_auth { + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + uint32_t auth_context_id; struct dcerpc_auth *auth_info; struct gensec_security *gensec_security; struct auth_session_info *session_info; @@ -205,8 +208,15 @@ struct dcesrv_connection { DATA_BLOB partial_input; - /* the current authentication state */ - struct dcesrv_auth auth_state; + /* This can be removed in master... */ + struct { + struct dcerpc_auth *auth_info; + struct gensec_security *gensec_security; + struct auth_session_info *session_info; + NTSTATUS (*session_key)(struct dcesrv_connection *, DATA_BLOB *session_key); + bool client_hdr_signing; + bool hdr_signing; + } _unused_auth_state; /* the event_context that will be used for this connection */ struct tevent_context *event_ctx; @@ -238,6 +248,9 @@ struct dcesrv_connection { const struct tsocket_address *local_address; const struct tsocket_address *remote_address; + + /* the current authentication state */ + struct dcesrv_auth auth_state; }; diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index c3ba40c..03231a5 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -47,6 +47,9 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) uint32_t auth_length; if (pkt->auth_length == 0) { + auth->auth_type = DCERPC_AUTH_TYPE_NONE; + auth->auth_level = DCERPC_AUTH_LEVEL_NONE; + auth->auth_context_id = 0; dce_conn->auth_state.auth_info = NULL; return true; } @@ -63,6 +66,10 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) return false; } + auth->auth_type = dce_conn->auth_state.auth_info->auth_type; + auth->auth_level = dce_conn->auth_state.auth_info->auth_level; + auth->auth_context_id = dce_conn->auth_state.auth_info->auth_context_id; + server_credentials = cli_credentials_init(call); if (!server_credentials) { @@ -100,12 +107,12 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) } } - status = gensec_start_mech_by_authtype(auth->gensec_security, auth->auth_info->auth_type, - auth->auth_info->auth_level); + status = gensec_start_mech_by_authtype(auth->gensec_security, auth->auth_type, + auth->auth_level); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("Failed to start GENSEC mechanism for DCERPC server: auth_type=%d, auth_level=%d: %s\n", - (int)auth->auth_info->auth_type, - (int)auth->auth_info->auth_level, + (int)auth->auth_type, + (int)auth->auth_level, nt_errstr(status))); return false; } -- 1.9.1 From 4ca4d53c2acd0cd7160958b8be97780e2b96a281 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 10 Mar 2016 16:02:31 +0100 Subject: [PATCH 254/323] CVE-2015-5370: s4:rpc_server: make use of dce_call->conn->auth_state.auth_* in dcesrv_request() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index ad0f1df..5eb287b 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1101,8 +1101,6 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) struct ndr_pull *pull; NTSTATUS status; struct dcesrv_connection_context *context; - uint32_t auth_type = DCERPC_AUTH_TYPE_NONE; - uint32_t auth_level = DCERPC_AUTH_LEVEL_NONE; /* if authenticated, and the mech we use can't do async replies, don't use them... */ if (call->conn->auth_state.gensec_security && @@ -1115,12 +1113,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return dcesrv_fault(call, DCERPC_FAULT_UNK_IF); } - if (call->conn->auth_state.auth_info != NULL) { - auth_type = call->conn->auth_state.auth_info->auth_type; - auth_level = call->conn->auth_state.auth_info->auth_level; - } - - switch (auth_level) { + switch (call->conn->auth_state.auth_level) { case DCERPC_AUTH_LEVEL_NONE: case DCERPC_AUTH_LEVEL_INTEGRITY: case DCERPC_AUTH_LEVEL_PRIVACY: @@ -1136,7 +1129,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) "to [%s] with auth[type=0x%x,level=0x%x] " "on [%s] from [%s]\n", __func__, context->iface->name, - auth_type, auth_level, + call->conn->auth_state.auth_type, + call->conn->auth_state.auth_level, derpc_transport_string_by_transport(transport), addr)); return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); @@ -1144,7 +1138,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) break; } - if (auth_level < context->min_auth_level) { + if (call->conn->auth_state.auth_level < context->min_auth_level) { char *addr; addr = tsocket_address_string(call->conn->remote_address, call); @@ -1155,7 +1149,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) __func__, context->min_auth_level, context->iface->name, - auth_type, auth_level, + call->conn->auth_state.auth_type, + call->conn->auth_state.auth_level, derpc_transport_string_by_transport(transport), addr)); return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); -- 1.9.1 From 5f50d4cac8eed5bff60c81ab028ee6719f76e809 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 255/323] CVE-2015-5370: s4:rpc_server/lsa: make use of dce_call->conn->auth_state.auth_{level,type} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/lsa/lsa_lookup.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source4/rpc_server/lsa/lsa_lookup.c b/source4/rpc_server/lsa/lsa_lookup.c index 9a8fdfb..f4da0b48 100644 --- a/source4/rpc_server/lsa/lsa_lookup.c +++ b/source4/rpc_server/lsa/lsa_lookup.c @@ -718,7 +718,7 @@ NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call, { enum dcerpc_transport_t transport = dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); - struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info; + const struct dcesrv_auth *auth = &dce_call->conn->auth_state; struct lsa_policy_state *policy_state; struct lsa_LookupSids2 q; NTSTATUS status; @@ -731,8 +731,8 @@ NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call, * We don't have policy handles on this call. So this must be restricted * to crypto connections only. */ - if (auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL || - auth_info->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { + if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL || + auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } @@ -946,7 +946,7 @@ NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX { enum dcerpc_transport_t transport = dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); - struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info; + const struct dcesrv_auth *auth = &dce_call->conn->auth_state; struct lsa_policy_state *policy_state; struct lsa_LookupNames3 q; NTSTATUS status; @@ -959,8 +959,8 @@ NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX * We don't have policy handles on this call. So this must be restricted * to crypto connections only. */ - if (auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL || - auth_info->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { + if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL || + auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } -- 1.9.1 From cd29203b429667cbf8f32ed5b6f8e84b1a04d999 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 256/323] CVE-2015-5370: s4:rpc_server/samr: make use of dce_call->conn->auth_state.auth_level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/samr/dcesrv_samr.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 69d48b8..423fcf0 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -4321,17 +4321,12 @@ static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call, NTSTATUS status; enum dcerpc_transport_t transport = dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); - enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE; if (transport != NCACN_IP_TCP && transport != NCALRPC) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } - if (dce_call->conn->auth_state.auth_info != NULL) { - auth_level = dce_call->conn->auth_state.auth_info->auth_level; - } - - if (auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { + if (dce_call->conn->auth_state.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); } -- 1.9.1 From 803e34e5efd3c42b2755c82a2762f3c7db17997a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 257/323] CVE-2015-5370: s4:rpc_server/netlogon: make use of dce_call->conn->auth_state.auth_{level,type} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index fd86c36..7a92a6d 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -536,7 +536,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_ca /* * If schannel is required for this call test that it actually is available. */ -static NTSTATUS schannel_check_required(struct dcerpc_auth *auth_info, +static NTSTATUS schannel_check_required(const struct dcesrv_auth *auth_info, const char *computer_name, bool integrity, bool privacy) { @@ -572,12 +572,11 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc struct netlogon_creds_CredentialState **creds_out) { NTSTATUS nt_status; - struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info; int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx); bool schannel_global_required = (schannel == true); if (schannel_global_required) { - nt_status = schannel_check_required(auth_info, + nt_status = schannel_check_required(&dce_call->conn->auth_state, computer_name, true, false); if (!NT_STATUS_IS_OK(nt_status)) { @@ -1010,13 +1009,7 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal break; case 6: - if (dce_call->conn->auth_state.auth_info == NULL) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (dce_call->conn->auth_state.auth_info->auth_level != - DCERPC_AUTH_LEVEL_PRIVACY) - { + if (dce_call->conn->auth_state.auth_level < DCERPC_AUTH_LEVEL_PRIVACY) { return NT_STATUS_INVALID_PARAMETER; } @@ -1076,8 +1069,7 @@ static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, return nt_status; } - if (!dce_call->conn->auth_state.auth_info || - dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { + if (dce_call->conn->auth_state.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { return NT_STATUS_ACCESS_DENIED; } return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds); -- 1.9.1 From fc784ca4b54addff473c6e91ce8d536f1da899cf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 258/323] CVE-2015-5370: s4:rpc_server: correctly maintain dcesrv_connection->max_{recv,xmit}_frag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These values are controlled by the client but only in a range between 2048 and 5840 (including these values in 8 byte steps). recv and xmit result always in same min value. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/common/reply.c | 2 +- source4/rpc_server/dcerpc_server.c | 32 ++++++++++++++++++++++++-------- source4/rpc_server/dcerpc_server.h | 3 ++- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index 6d23fa9..5473237 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -183,7 +183,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) /* we can write a full max_recv_frag size, minus the dcerpc request header size */ - chunk_size = call->conn->cli_max_recv_frag; + chunk_size = call->conn->max_xmit_frag; chunk_size -= DCERPC_REQUEST_LENGTH; if (call->conn->auth_state.auth_info && call->conn->auth_state.gensec_security) { diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 5eb287b..1393aa7 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -408,6 +408,8 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->msg_ctx = msg_ctx; p->server_id = server_id; p->state_flags = state_flags; + p->max_recv_frag = 5840; + p->max_xmit_frag = 5840; *_p = p; return NT_STATUS_OK; @@ -633,6 +635,24 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32_t context_id; const struct dcesrv_interface *iface; uint32_t extra_flags = 0; + uint16_t max_req = 0; + uint16_t max_rep = 0; + + /* max_recv_frag and max_xmit_frag result always in the same value! */ + max_req = MIN(call->pkt.u.bind.max_xmit_frag, + call->pkt.u.bind.max_recv_frag); + /* + * The values are between 2048 and 5840 tested against Windows 2012R2 + * via ncacn_ip_tcp on port 135. + */ + max_req = MAX(2048, max_req); + max_rep = MIN(max_req, call->conn->max_recv_frag); + /* They are truncated to an 8 byte boundary. */ + max_rep &= 0xFFF8; + + /* max_recv_frag and max_xmit_frag result always in the same value! */ + call->conn->max_recv_frag = max_rep; + call->conn->max_xmit_frag = max_rep; /* if provided, check the assoc_group is valid @@ -722,10 +742,6 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } } - if (call->conn->cli_max_recv_frag == 0) { - call->conn->cli_max_recv_frag = MIN(0x2000, call->pkt.u.bind.max_recv_frag); - } - if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) && (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) { call->context->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED; @@ -749,8 +765,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_BIND_ACK; pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags; - pkt.u.bind_ack.max_xmit_frag = call->conn->cli_max_recv_frag; - pkt.u.bind_ack.max_recv_frag = 0x2000; + pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag; + pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag; /* make it possible for iface->bind() to specify the assoc_group_id @@ -932,8 +948,8 @@ static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, } } pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags; - pkt.u.alter_resp.max_xmit_frag = 0x2000; - pkt.u.alter_resp.max_recv_frag = 0x2000; + pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag; + pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag; if (result == 0) { pkt.u.alter_resp.assoc_group_id = call->context->assoc_group->id; } else { diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index c525c31..603a55d 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -204,7 +204,8 @@ struct dcesrv_connection { struct dcesrv_call_state *call_list; /* the maximum size the client wants to receive */ - uint32_t cli_max_recv_frag; + uint16_t max_recv_frag; + uint16_t max_xmit_frag; DATA_BLOB partial_input; -- 1.9.1 From 33c6392954e0336a85c19944b4f7c082e5f52d88 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 259/323] CVE-2015-5370: s4:rpc_server: avoid ZERO_STRUCT() in dcesrv_fault() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/common/reply.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index 5473237..b187e20 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -101,10 +101,10 @@ NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) { struct ncacn_packet pkt; struct data_blob_list_item *rep; - uint8_t zeros[4]; + static const uint8_t zeros[4] = { 0, }; NTSTATUS status; - /* setup a bind_ack */ + /* setup a fault */ dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; @@ -114,8 +114,6 @@ NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) pkt.u.fault.context_id = 0; pkt.u.fault.cancel_count = 0; pkt.u.fault.status = fault_code; - - ZERO_STRUCT(zeros); pkt.u.fault._pad = data_blob_const(zeros, sizeof(zeros)); rep = talloc_zero(call, struct data_blob_list_item); -- 1.9.1 From c1b914d0012ae1a6e305a2e32b5116860eca9c2c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 260/323] CVE-2015-5370: s4:rpc_server: set alloc_hint = 24 in dcesrv_fault() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches a Windows 2012R2 server. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/common/reply.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index b187e20..e4150e6 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -110,7 +110,7 @@ NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_FAULT; pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; - pkt.u.fault.alloc_hint = 0; + pkt.u.fault.alloc_hint = 24; pkt.u.fault.context_id = 0; pkt.u.fault.cancel_count = 0; pkt.u.fault.status = fault_code; -- 1.9.1 From 93aa11f9f7d5ae17855999416e2d489ded6a11b2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 261/323] CVE-2015-5370: s4:rpc_server: fill context_id in dcesrv_fault() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This depends on the type of the incoming pdu. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/common/reply.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index e4150e6..77d8d79 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -111,7 +111,20 @@ NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) pkt.ptype = DCERPC_PKT_FAULT; pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; pkt.u.fault.alloc_hint = 24; - pkt.u.fault.context_id = 0; + switch (call->pkt.ptype) { + case DCERPC_PKT_REQUEST: + pkt.u.fault.context_id = call->pkt.u.request.context_id; + break; + default: + pkt.u.fault.context_id = 0; + break; + } + if (fault_code == DCERPC_NCA_S_PROTO_ERROR) { + /* + * context_id = 0 is forced on protocol errors. + */ + pkt.u.fault.context_id = 0; + } pkt.u.fault.cancel_count = 0; pkt.u.fault.status = fault_code; pkt.u.fault._pad = data_blob_const(zeros, sizeof(zeros)); -- 1.9.1 From 928fc2520b3a81edf71b0c93ac8ca4a51db5e2d6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 262/323] CVE-2015-5370: s4:rpc_server: split out a dcesrv_fault_with_flags() helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/common/reply.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index 77d8d79..d72cb47 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -97,7 +97,9 @@ void dcesrv_init_hdr(struct ncacn_packet *pkt, bool bigendian) /* return a dcerpc fault */ -NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) +NTSTATUS dcesrv_fault_with_flags(struct dcesrv_call_state *call, + uint32_t fault_code, + uint8_t extra_flags) { struct ncacn_packet pkt; struct data_blob_list_item *rep; @@ -109,7 +111,7 @@ NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_FAULT; - pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags; pkt.u.fault.alloc_hint = 24; switch (call->pkt.ptype) { case DCERPC_PKT_REQUEST: @@ -153,7 +155,10 @@ NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) return NT_STATUS_OK; } - +NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) +{ + return dcesrv_fault_with_flags(call, fault_code, 0); +} _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) { -- 1.9.1 From 742105e7ed69151b7d712e1331102250f14a3358 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 263/323] CVE-2015-5370: s4:rpc_server: add some padding to dcesrv_bind_nak() responses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches Windows 2012R2. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 1393aa7..8a0df18 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -462,6 +462,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) struct dcerpc_bind_nak_version version; struct data_blob_list_item *rep; NTSTATUS status; + static const uint8_t _pad[3] = { 0, }; /* setup a bind_nak */ dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); @@ -474,7 +475,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) version.rpc_vers_minor = 0; pkt.u.bind_nak.num_versions = 1; pkt.u.bind_nak.versions = &version; - pkt.u.bind_nak._pad = data_blob_null; + pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad)); rep = talloc_zero(call, struct data_blob_list_item); if (!rep) { -- 1.9.1 From 2d4845e762d4e9ac501c6f0f1030ee98e9332f97 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 264/323] CVE-2015-5370: s4:rpc_server: return the correct secondary_address in dcesrv_bind() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For now we still force \\PIPE\\ in upper case, we may be able to remove this and change it in our idl files later. But for now we better behave like a windows server without changing too much. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 8a0df18..57b76bf 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -638,6 +638,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32_t extra_flags = 0; uint16_t max_req = 0; uint16_t max_rep = 0; + const char *ep_prefix = ""; + const char *endpoint = NULL; /* max_recv_frag and max_xmit_frag result always in the same value! */ max_req = MIN(call->pkt.u.bind.max_xmit_frag, @@ -782,10 +784,31 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } if (iface) { - /* FIXME: Use pipe name as specified by endpoint instead of interface name */ - pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "\\PIPE\\%s", iface->name); - } else { - pkt.u.bind_ack.secondary_address = ""; + endpoint = dcerpc_binding_get_string_option( + call->conn->endpoint->ep_description, + "endpoint"); + } + + if (endpoint == NULL) { + endpoint = ""; + } + + if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) { + /* + * TODO: check if this is really needed + * + * Or if we should fix this in our idl files. + */ + ep_prefix = "\\PIPE\\"; + endpoint += 6; + } + + pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s", + ep_prefix, + endpoint); + if (pkt.u.bind_ack.secondary_address == NULL) { + TALLOC_FREE(call->context); + return NT_STATUS_NO_MEMORY; } pkt.u.bind_ack.num_results = 1; pkt.u.bind_ack.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx); -- 1.9.1 From 1992d1b6f1d9dece2049e9d473958216f8506345 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 265/323] CVE-2015-5370: s4:rpc_server: make dcesrv_process_ncacn_packet() static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 57b76bf..97bad0e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1282,9 +1282,9 @@ _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(stru /* process some input to a dcerpc endpoint server. */ -NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, - struct ncacn_packet *pkt, - DATA_BLOB blob) +static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, + struct ncacn_packet *pkt, + DATA_BLOB blob) { NTSTATUS status; struct dcesrv_call_state *call; -- 1.9.1 From 1e58527bfd335d901d1a3d0315022cf8fcca17a1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 266/323] CVE-2015-5370: s4:rpc_server: add infrastructure to terminate a connection after a response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BIND_NAK or FAULT may mark a connection as to be terminated. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 60 +++++++++++++++++++++++++++++++++++++- source4/rpc_server/dcerpc_server.h | 3 ++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 97bad0e..03adc9d 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1637,6 +1637,7 @@ struct dcesrv_sock_reply_state { }; static void dcesrv_sock_reply_done(struct tevent_req *subreq); +static void dcesrv_call_terminate_step1(struct tevent_req *subreq); static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn) { @@ -1663,7 +1664,7 @@ static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn) DLIST_REMOVE(call->replies, rep); - if (call->replies == NULL) { + if (call->replies == NULL && call->terminate_reason == NULL) { substate->call = call; } @@ -1683,6 +1684,20 @@ static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn) substate); } + if (call->terminate_reason != NULL) { + struct tevent_req *subreq; + + subreq = tevent_queue_wait_send(call, + dce_conn->event_ctx, + dce_conn->send_queue); + if (!subreq) { + dcesrv_terminate_connection(dce_conn, __location__); + return; + } + tevent_req_set_callback(subreq, dcesrv_call_terminate_step1, + call); + } + DLIST_REMOVE(call->conn->call_list, call); call->list = DCESRV_LIST_NONE; } @@ -1710,8 +1725,51 @@ static void dcesrv_sock_reply_done(struct tevent_req *subreq) } } +static void dcesrv_call_terminate_step2(struct tevent_req *subreq); + +static void dcesrv_call_terminate_step1(struct tevent_req *subreq) +{ + struct dcesrv_call_state *call = tevent_req_callback_data(subreq, + struct dcesrv_call_state); + bool ok; + struct timeval tv; + + /* make sure we stop send queue before removing subreq */ + tevent_queue_stop(call->conn->send_queue); + + ok = tevent_queue_wait_recv(subreq); + TALLOC_FREE(subreq); + if (!ok) { + dcesrv_terminate_connection(call->conn, __location__); + return; + } + + /* disconnect after 200 usecs */ + tv = timeval_current_ofs_usec(200); + subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv); + if (subreq == NULL) { + dcesrv_terminate_connection(call->conn, __location__); + return; + } + tevent_req_set_callback(subreq, dcesrv_call_terminate_step2, + call); +} + +static void dcesrv_call_terminate_step2(struct tevent_req *subreq) +{ + struct dcesrv_call_state *call = tevent_req_callback_data(subreq, + struct dcesrv_call_state); + bool ok; + ok = tevent_wakeup_recv(subreq); + TALLOC_FREE(subreq); + if (!ok) { + dcesrv_terminate_connection(call->conn, __location__); + return; + } + dcesrv_terminate_connection(call->conn, call->terminate_reason); +} struct dcesrv_socket_context { const struct dcesrv_endpoint *endpoint; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 603a55d..6c52cb0 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -130,6 +130,9 @@ struct dcesrv_call_state { /* this is used by the boilerplate code to generate DCERPC faults */ uint32_t fault_code; + + /* the reason why we terminate the connection after sending a response */ + const char *terminate_reason; }; #define DCESRV_HANDLE_ANY 255 -- 1.9.1 From ec6e29c46e32175ad91f13ef787a8e8c64ee1472 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 267/323] CVE-2015-5370: s4:rpc_server: verify the protocol headers before processing pdus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On protocol errors we should send BIND_NAK or FAULT and mark the connection as to be terminated. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 106 +++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 03adc9d..435bb72 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -452,6 +452,18 @@ static void dcesrv_call_set_list(struct dcesrv_call_state *call, } } +static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call, + const char *reason) +{ + if (call->conn->terminate != NULL) { + return; + } + + call->terminate_reason = talloc_strdup(call, reason); + if (call->terminate_reason == NULL) { + call->terminate_reason = __location__; + } +} /* return a dcerpc bind_nak @@ -464,6 +476,12 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) NTSTATUS status; static const uint8_t _pad[3] = { 0, }; + /* + * We add the call to the pending_call_list + * in order to defer the termination. + */ + dcesrv_call_disconnect_after(call, "dcesrv_bind_nak"); + /* setup a bind_nak */ dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); pkt.auth_length = 0; @@ -501,6 +519,19 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) return NT_STATUS_OK; } +static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call, + uint32_t fault_code) +{ + /* + * We add the call to the pending_call_list + * in order to defer the termination. + */ + dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect"); + + return dcesrv_fault_with_flags(call, fault_code, + DCERPC_PFC_FLAG_DID_NOT_EXECUTE); +} + static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c) { DLIST_REMOVE(c->conn->contexts, c); @@ -641,6 +672,23 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) const char *ep_prefix = ""; const char *endpoint = NULL; + status = dcerpc_verify_ncacn_packet_header(&call->pkt, + DCERPC_PKT_BIND, + call->pkt.u.bind.auth_info.length, + 0, /* required flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + return dcesrv_bind_nak(call, + DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED); + } + /* max_recv_frag and max_xmit_frag result always in the same value! */ max_req = MIN(call->pkt.u.bind.max_xmit_frag, call->pkt.u.bind.max_recv_frag); @@ -864,6 +912,24 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) */ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) { + NTSTATUS status; + + status = dcerpc_verify_ncacn_packet_header(&call->pkt, + DCERPC_PKT_AUTH3, + call->pkt.u.auth3.auth_info.length, + 0, /* required flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } + /* handle the auth3 in the auth code */ if (!dcesrv_auth_auth3(call)) { return dcesrv_fault(call, DCERPC_FAULT_OTHER); @@ -1033,6 +1099,22 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) NTSTATUS status; uint32_t context_id; + status = dcerpc_verify_ncacn_packet_header(&call->pkt, + DCERPC_PKT_ALTER, + call->pkt.u.alter.auth_info.length, + 0, /* required flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } + /* handle any authentication that is being requested */ if (!dcesrv_auth_alter(call)) { /* TODO: work out the right reject code */ @@ -1310,9 +1392,27 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, /* we have to check the signing here, before combining the pdus */ - if (call->pkt.ptype == DCERPC_PKT_REQUEST && - !dcesrv_auth_request(call, &blob)) { - return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + if (call->pkt.ptype == DCERPC_PKT_REQUEST) { + status = dcerpc_verify_ncacn_packet_header(&call->pkt, + DCERPC_PKT_REQUEST, + call->pkt.u.request.stub_and_verifier.length, + 0, /* required_flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + DCERPC_PFC_FLAG_PENDING_CANCEL | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); + } + + if (!dcesrv_auth_request(call, &blob)) { + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } } /* see if this is a continued packet */ -- 1.9.1 From bc4110aff43c98332a7dd336acb4574ed5cd1080 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 268/323] CVE-2015-5370: s4:rpc_server: ensure that the message ordering doesn't violate the spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first pdu is always a BIND. REQUEST pdus are only allowed once the authentication is finished. A simple anonymous authentication is finished after the BIND. Real authentication may need additional ALTER or AUTH3 exchanges. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 41 ++++++++++++++++++++++++++++++++++++-- source4/rpc_server/dcerpc_server.h | 8 ++++++++ source4/rpc_server/dcesrv_auth.c | 12 +++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 435bb72..76adb18 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -408,6 +408,7 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->msg_ctx = msg_ctx; p->server_id = server_id; p->state_flags = state_flags; + p->allow_bind = true; p->max_recv_frag = 5840; p->max_xmit_frag = 5840; @@ -459,6 +460,11 @@ static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call, return; } + call->conn->allow_bind = false; + call->conn->allow_alter = false; + call->conn->allow_auth3 = false; + call->conn->allow_request = false; + call->terminate_reason = talloc_strdup(call, reason); if (call->terminate_reason == NULL) { call->terminate_reason = __location__; @@ -914,6 +920,10 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) { NTSTATUS status; + if (!call->conn->allow_auth3) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } + status = dcerpc_verify_ncacn_packet_header(&call->pkt, DCERPC_PKT_AUTH3, call->pkt.u.auth3.auth_info.length, @@ -1099,6 +1109,10 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) NTSTATUS status; uint32_t context_id; + if (!call->conn->allow_alter) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } + status = dcerpc_verify_ncacn_packet_header(&call->pkt, DCERPC_PKT_ALTER, call->pkt.u.alter.auth_info.length, @@ -1224,6 +1238,10 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) NTSTATUS status; struct dcesrv_connection_context *context; + if (!call->conn->allow_request) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } + /* if authenticated, and the mech we use can't do async replies, don't use them... */ if (call->conn->auth_state.gensec_security && !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) { @@ -1390,9 +1408,22 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, talloc_set_destructor(call, dcesrv_call_dequeue); + if (call->conn->allow_bind) { + /* + * Only one bind is possible per connection + */ + call->conn->allow_bind = false; + return dcesrv_bind(call); + } + /* we have to check the signing here, before combining the pdus */ if (call->pkt.ptype == DCERPC_PKT_REQUEST) { + if (!call->conn->allow_request) { + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); + } + status = dcerpc_verify_ncacn_packet_header(&call->pkt, DCERPC_PKT_REQUEST, call->pkt.u.request.stub_and_verifier.length, @@ -1488,7 +1519,8 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, switch (call->pkt.ptype) { case DCERPC_PKT_BIND: - status = dcesrv_bind(call); + status = dcesrv_bind_nak(call, + DCERPC_BIND_NAK_REASON_NOT_SPECIFIED); break; case DCERPC_PKT_AUTH3: status = dcesrv_auth3(call); @@ -1500,7 +1532,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, status = dcesrv_request(call); break; default: - status = NT_STATUS_INVALID_PARAMETER; + status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); break; } @@ -1674,6 +1706,11 @@ static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, cons srv_conn = talloc_get_type(dce_conn->transport.private_data, struct stream_connection); + dce_conn->allow_bind = false; + dce_conn->allow_auth3 = false; + dce_conn->allow_alter = false; + dce_conn->allow_request = false; + if (dce_conn->pending_call_list == NULL) { char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason); diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 6c52cb0..2627f75 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -255,6 +255,14 @@ struct dcesrv_connection { /* the current authentication state */ struct dcesrv_auth auth_state; + + /* + * remember which pdu types are allowed + */ + bool allow_bind; + bool allow_auth3; + bool allow_alter; + bool allow_request; }; diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 03231a5..f5086ac 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -130,7 +130,11 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe NTSTATUS status; bool want_header_signing = false; + dce_conn->allow_alter = true; + dce_conn->allow_auth3 = true; + if (call->pkt.auth_length == 0) { + dce_conn->allow_request = true; return NT_STATUS_OK; } @@ -161,6 +165,7 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status))); return status; } + dce_conn->allow_request = true; if (!gensec_have_feature(dce_conn->auth_state.gensec_security, GENSEC_FEATURE_SIGN_PKT_HEADER)) @@ -246,6 +251,8 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status))); return false; } + dce_conn->allow_request = true; + /* Now that we are authenticated, go back to the generic session key... */ dce_conn->auth_state.session_key = dcesrv_generic_session_key; return true; @@ -325,6 +332,7 @@ NTSTATUS dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct ncacn_pack DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status))); return status; } + dce_conn->allow_request = true; /* Now that we are authenticated, got back to the generic session key... */ dce_conn->auth_state.session_key = dcesrv_generic_session_key; @@ -352,6 +360,10 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) uint32_t auth_length; size_t hdr_size = DCERPC_REQUEST_LENGTH; + if (!dce_conn->allow_request) { + return false; + } + if (!dce_conn->auth_state.auth_info || !dce_conn->auth_state.gensec_security) { if (pkt->auth_length != 0) { -- 1.9.1 From e429dd690d75403dd7549c558f30a4ef5f9f12c5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 269/323] CVE-2015-5370: s4:rpc_server: maintain in and out struct dcerpc_auth per dcesrv_call_state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should not use one "global" per connection variable to hold the incoming and outgoing auth_info. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/common/reply.c | 2 +- source4/rpc_server/dcerpc_server.c | 8 +- source4/rpc_server/dcerpc_server.h | 7 +- source4/rpc_server/dcesrv_auth.c | 149 ++++++++++++++++++++----------------- 4 files changed, 94 insertions(+), 72 deletions(-) diff --git a/source4/rpc_server/common/reply.c b/source4/rpc_server/common/reply.c index d72cb47..f8b8d5d 100644 --- a/source4/rpc_server/common/reply.c +++ b/source4/rpc_server/common/reply.c @@ -201,7 +201,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) request header size */ chunk_size = call->conn->max_xmit_frag; chunk_size -= DCERPC_REQUEST_LENGTH; - if (call->conn->auth_state.auth_info && + if (call->conn->auth_state.auth_finished && call->conn->auth_state.gensec_security) { size_t max_payload = chunk_size; diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 76adb18..0345b14 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -891,7 +891,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } status = ncacn_push_auth(&rep->blob, call, &pkt, - call->conn->auth_state.auth_info); + call->out_auth_info); if (!NT_STATUS_IS_OK(status)) { talloc_free(call->context); call->context = NULL; @@ -924,6 +924,10 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); } + if (call->conn->auth_state.auth_finished) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } + status = dcerpc_verify_ncacn_packet_header(&call->pkt, DCERPC_PKT_AUTH3, call->pkt.u.auth3.auth_info.length, @@ -1082,7 +1086,7 @@ static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, return NT_STATUS_NO_MEMORY; } - status = ncacn_push_auth(&rep->blob, call, &pkt, call->conn->auth_state.auth_info); + status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 2627f75..cd0b0e4 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -133,6 +133,11 @@ struct dcesrv_call_state { /* the reason why we terminate the connection after sending a response */ const char *terminate_reason; + + /* temporary auth_info fields */ + struct dcerpc_auth in_auth_info; + struct dcerpc_auth _out_auth_info; + struct dcerpc_auth *out_auth_info; }; #define DCESRV_HANDLE_ANY 255 @@ -152,12 +157,12 @@ struct dcesrv_auth { enum dcerpc_AuthType auth_type; enum dcerpc_AuthLevel auth_level; uint32_t auth_context_id; - struct dcerpc_auth *auth_info; struct gensec_security *gensec_security; struct auth_session_info *session_info; NTSTATUS (*session_key)(struct dcesrv_connection *, DATA_BLOB *session_key); bool client_hdr_signing; bool hdr_signing; + bool auth_finished; }; struct dcesrv_connection_context { diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index f5086ac..565c373 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -50,25 +50,19 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) auth->auth_type = DCERPC_AUTH_TYPE_NONE; auth->auth_level = DCERPC_AUTH_LEVEL_NONE; auth->auth_context_id = 0; - dce_conn->auth_state.auth_info = NULL; return true; } - dce_conn->auth_state.auth_info = talloc(dce_conn, struct dcerpc_auth); - if (!dce_conn->auth_state.auth_info) { - return false; - } - status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.bind.auth_info, - dce_conn->auth_state.auth_info, + &call->in_auth_info, &auth_length, false); if (!NT_STATUS_IS_OK(status)) { return false; } - auth->auth_type = dce_conn->auth_state.auth_info->auth_type; - auth->auth_level = dce_conn->auth_state.auth_info->auth_level; - auth->auth_context_id = dce_conn->auth_state.auth_info->auth_context_id; + auth->auth_type = call->in_auth_info.auth_type; + auth->auth_level = call->in_auth_info.auth_level; + auth->auth_context_id = call->in_auth_info.auth_context_id; server_credentials = cli_credentials_init(call); @@ -134,6 +128,7 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe dce_conn->allow_auth3 = true; if (call->pkt.auth_length == 0) { + dce_conn->auth_state.auth_finished = true; dce_conn->allow_request = true; return NT_STATUS_OK; } @@ -152,10 +147,17 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe want_header_signing = false; } + call->_out_auth_info = (struct dcerpc_auth) { + .auth_type = dce_conn->auth_state.auth_type, + .auth_level = dce_conn->auth_state.auth_level, + .auth_context_id = dce_conn->auth_state.auth_context_id, + }; + call->out_auth_info = &call->_out_auth_info; + status = gensec_update_ev(dce_conn->auth_state.gensec_security, call, call->event_ctx, - dce_conn->auth_state.auth_info->credentials, - &dce_conn->auth_state.auth_info->credentials); + call->in_auth_info.credentials, + &call->out_auth_info->credentials); if (NT_STATUS_IS_OK(status)) { status = gensec_session_info(dce_conn->auth_state.gensec_security, @@ -165,6 +167,7 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status))); return status; } + dce_conn->auth_state.auth_finished = true; dce_conn->allow_request = true; if (!gensec_have_feature(dce_conn->auth_state.gensec_security, @@ -184,9 +187,6 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe dce_conn->auth_state.session_key = dcesrv_generic_session_key; return NT_STATUS_OK; } else if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - dce_conn->auth_state.auth_info->auth_pad_length = 0; - dce_conn->auth_state.auth_info->auth_reserved = 0; - if (!gensec_have_feature(dce_conn->auth_state.gensec_security, GENSEC_FEATURE_SIGN_PKT_HEADER)) { @@ -223,7 +223,7 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) return false; } - if (!dce_conn->auth_state.auth_info) { + if (dce_conn->auth_state.auth_finished) { return false; } @@ -233,16 +233,23 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) } status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.auth3.auth_info, - dce_conn->auth_state.auth_info, &auth_length, true); + &call->in_auth_info, &auth_length, true); if (!NT_STATUS_IS_OK(status)) { return false; } + call->_out_auth_info = (struct dcerpc_auth) { + .auth_type = dce_conn->auth_state.auth_type, + .auth_level = dce_conn->auth_state.auth_level, + .auth_context_id = dce_conn->auth_state.auth_context_id, + }; + call->out_auth_info = &call->_out_auth_info; + /* Pass the extra data we got from the client down to gensec for processing */ status = gensec_update_ev(dce_conn->auth_state.gensec_security, call, call->event_ctx, - dce_conn->auth_state.auth_info->credentials, - &dce_conn->auth_state.auth_info->credentials); + call->in_auth_info.credentials, + &call->out_auth_info->credentials); if (NT_STATUS_IS_OK(status)) { status = gensec_session_info(dce_conn->auth_state.gensec_security, dce_conn, @@ -251,6 +258,7 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status))); return false; } + dce_conn->auth_state.auth_finished = true; dce_conn->allow_request = true; /* Now that we are authenticated, go back to the generic session key... */ @@ -277,22 +285,23 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) /* on a pure interface change there is no auth blob */ if (pkt->auth_length == 0) { + if (!dce_conn->auth_state.auth_finished) { + return false; + } return true; } - /* We can't work without an existing gensec state */ - if (!dce_conn->auth_state.gensec_security) { + if (dce_conn->auth_state.auth_finished) { return false; } - dce_conn->auth_state.auth_info = talloc(dce_conn, struct dcerpc_auth); - if (!dce_conn->auth_state.auth_info) { + /* We can't work without an existing gensec state */ + if (!dce_conn->auth_state.gensec_security) { return false; } status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.alter.auth_info, - dce_conn->auth_state.auth_info, - &auth_length, true); + &call->in_auth_info, &auth_length, true); if (!NT_STATUS_IS_OK(status)) { return false; } @@ -316,13 +325,20 @@ NTSTATUS dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct ncacn_pack } if (!call->conn->auth_state.gensec_security) { - return NT_STATUS_INVALID_PARAMETER; + return NT_STATUS_INTERNAL_ERROR; } + call->_out_auth_info = (struct dcerpc_auth) { + .auth_type = dce_conn->auth_state.auth_type, + .auth_level = dce_conn->auth_state.auth_level, + .auth_context_id = dce_conn->auth_state.auth_context_id, + }; + call->out_auth_info = &call->_out_auth_info; + status = gensec_update_ev(dce_conn->auth_state.gensec_security, call, call->event_ctx, - dce_conn->auth_state.auth_info->credentials, - &dce_conn->auth_state.auth_info->credentials); + call->in_auth_info.credentials, + &call->out_auth_info->credentials); if (NT_STATUS_IS_OK(status)) { status = gensec_session_info(dce_conn->auth_state.gensec_security, @@ -332,14 +348,13 @@ NTSTATUS dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct ncacn_pack DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status))); return status; } + dce_conn->auth_state.auth_finished = true; dce_conn->allow_request = true; /* Now that we are authenticated, got back to the generic session key... */ dce_conn->auth_state.session_key = dcesrv_generic_session_key; return NT_STATUS_OK; } else if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - dce_conn->auth_state.auth_info->auth_pad_length = 0; - dce_conn->auth_state.auth_info->auth_reserved = 0; return NT_STATUS_OK; } @@ -355,7 +370,6 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) { struct ncacn_packet *pkt = &call->pkt; struct dcesrv_connection *dce_conn = call->conn; - struct dcerpc_auth auth; NTSTATUS status; uint32_t auth_length; size_t hdr_size = DCERPC_REQUEST_LENGTH; @@ -364,19 +378,11 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) return false; } - if (!dce_conn->auth_state.auth_info || - !dce_conn->auth_state.gensec_security) { - if (pkt->auth_length != 0) { - return false; - } - return true; - } - if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { hdr_size += 16; } - switch (dce_conn->auth_state.auth_info->auth_level) { + switch (dce_conn->auth_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: case DCERPC_AUTH_LEVEL_INTEGRITY: break; @@ -396,36 +402,41 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) return false; } + if (!dce_conn->auth_state.gensec_security) { + return false; + } + status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.request.stub_and_verifier, - &auth, &auth_length, false); + &call->in_auth_info, &auth_length, false); if (!NT_STATUS_IS_OK(status)) { return false; } - if (auth.auth_type != dce_conn->auth_state.auth_info->auth_type) { + if (call->in_auth_info.auth_type != dce_conn->auth_state.auth_type) { return false; } - if (auth.auth_level != dce_conn->auth_state.auth_info->auth_level) { + if (call->in_auth_info.auth_level != dce_conn->auth_state.auth_level) { return false; } - if (auth.auth_context_id != dce_conn->auth_state.auth_info->auth_context_id) { + if (call->in_auth_info.auth_context_id != dce_conn->auth_state.auth_context_id) { return false; } pkt->u.request.stub_and_verifier.length -= auth_length; /* check signature or unseal the packet */ - switch (dce_conn->auth_state.auth_info->auth_level) { + switch (dce_conn->auth_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: status = gensec_unseal_packet(dce_conn->auth_state.gensec_security, full_packet->data + hdr_size, pkt->u.request.stub_and_verifier.length, full_packet->data, - full_packet->length-auth.credentials.length, - &auth.credentials); + full_packet->length- + call->in_auth_info.credentials.length, + &call->in_auth_info.credentials); memcpy(pkt->u.request.stub_and_verifier.data, full_packet->data + hdr_size, pkt->u.request.stub_and_verifier.length); @@ -436,8 +447,9 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) pkt->u.request.stub_and_verifier.data, pkt->u.request.stub_and_verifier.length, full_packet->data, - full_packet->length-auth.credentials.length, - &auth.credentials); + full_packet->length- + call->in_auth_info.credentials.length, + &call->in_auth_info.credentials); break; case DCERPC_AUTH_LEVEL_CONNECT: @@ -451,10 +463,10 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) } /* remove the indicated amount of padding */ - if (pkt->u.request.stub_and_verifier.length < auth.auth_pad_length) { + if (pkt->u.request.stub_and_verifier.length < call->in_auth_info.auth_pad_length) { return false; } - pkt->u.request.stub_and_verifier.length -= auth.auth_pad_length; + pkt->u.request.stub_and_verifier.length -= call->in_auth_info.auth_pad_length; return NT_STATUS_IS_OK(status); } @@ -474,13 +486,7 @@ bool dcesrv_auth_response(struct dcesrv_call_state *call, uint32_t payload_length; DATA_BLOB creds2; - /* non-signed packets are simple */ - if (dce_conn->auth_state.auth_info == NULL) { - status = ncacn_push_auth(blob, call, pkt, NULL); - return NT_STATUS_IS_OK(status); - } - - switch (dce_conn->auth_state.auth_info->auth_level) { + switch (dce_conn->auth_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: case DCERPC_AUTH_LEVEL_INTEGRITY: if (sig_size == 0) { @@ -505,6 +511,10 @@ bool dcesrv_auth_response(struct dcesrv_call_state *call, return false; } + if (!dce_conn->auth_state.gensec_security) { + return false; + } + ndr = ndr_push_init_ctx(call); if (!ndr) { return false; @@ -519,28 +529,31 @@ bool dcesrv_auth_response(struct dcesrv_call_state *call, return false; } + call->_out_auth_info = (struct dcerpc_auth) { + .auth_type = dce_conn->auth_state.auth_type, + .auth_level = dce_conn->auth_state.auth_level, + .auth_context_id = dce_conn->auth_state.auth_context_id, + }; + call->out_auth_info = &call->_out_auth_info; + /* pad to 16 byte multiple in the payload portion of the packet. This matches what w2k3 does. Note that we can't use ndr_push_align() as that is relative to the start of the whole packet, whereas w2k8 wants it relative to the start of the stub */ - dce_conn->auth_state.auth_info->auth_pad_length = + call->out_auth_info->auth_pad_length = DCERPC_AUTH_PAD_LENGTH(pkt->u.response.stub_and_verifier.length); - ndr_err = ndr_push_zero(ndr, - dce_conn->auth_state.auth_info->auth_pad_length); + ndr_err = ndr_push_zero(ndr, call->out_auth_info->auth_pad_length); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return false; } payload_length = pkt->u.response.stub_and_verifier.length + - dce_conn->auth_state.auth_info->auth_pad_length; - - /* we start without signature, it will appended later */ - dce_conn->auth_state.auth_info->credentials = data_blob(NULL, 0); + call->out_auth_info->auth_pad_length; /* add the auth verifier */ ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, - dce_conn->auth_state.auth_info); + call->out_auth_info); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return false; } @@ -558,7 +571,7 @@ bool dcesrv_auth_response(struct dcesrv_call_state *call, dcerpc_set_auth_length(blob, sig_size); /* sign or seal the packet */ - switch (dce_conn->auth_state.auth_info->auth_level) { + switch (dce_conn->auth_state.auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: status = gensec_seal_packet(dce_conn->auth_state.gensec_security, call, @@ -591,7 +604,7 @@ bool dcesrv_auth_response(struct dcesrv_call_state *call, if (creds2.length != sig_size) { DEBUG(3,("dcesrv_auth_response: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n", (unsigned)creds2.length, (uint32_t)sig_size, - (unsigned)dce_conn->auth_state.auth_info->auth_pad_length, + (unsigned)call->out_auth_info->auth_pad_length, (unsigned)pkt->u.response.stub_and_verifier.length)); dcerpc_set_frag_length(blob, blob->length + creds2.length); dcerpc_set_auth_length(blob, creds2.length); -- 1.9.1 From 20d5f4c3666cd34a10dd38671f48ebe7a8ba7413 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 270/323] CVE-2015-5370: s4:rpc_server: make sure alter_context and auth3 can't change auth_{type,level,context_id} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcesrv_auth.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 565c373..afa584b 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -238,6 +238,18 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) return false; } + if (call->in_auth_info.auth_type != dce_conn->auth_state.auth_type) { + return false; + } + + if (call->in_auth_info.auth_level != dce_conn->auth_state.auth_level) { + return false; + } + + if (call->in_auth_info.auth_context_id != dce_conn->auth_state.auth_context_id) { + return false; + } + call->_out_auth_info = (struct dcerpc_auth) { .auth_type = dce_conn->auth_state.auth_type, .auth_level = dce_conn->auth_state.auth_level, @@ -306,6 +318,18 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call) return false; } + if (call->in_auth_info.auth_type != dce_conn->auth_state.auth_type) { + return false; + } + + if (call->in_auth_info.auth_level != dce_conn->auth_state.auth_level) { + return false; + } + + if (call->in_auth_info.auth_context_id != dce_conn->auth_state.auth_context_id) { + return false; + } + return true; } -- 1.9.1 From fd47f3541a5dbe8413c2795654f813557ddacd49 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 271/323] CVE-2015-5370: s4:rpc_server: let invalid request fragments disconnect the connection with a protocol error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 0345b14..d07710e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1456,33 +1456,34 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, struct dcesrv_call_state *call2 = call; uint32_t alloc_size; - /* we only allow fragmented requests, no other packet types */ - if (call->pkt.ptype != DCERPC_PKT_REQUEST) { - return dcesrv_fault(call2, DCERPC_FAULT_OTHER); - } - /* this is a continuation of an existing call - find the call then tack it on the end */ call = dcesrv_find_fragmented_call(dce_conn, call2->pkt.call_id); if (!call) { - return dcesrv_fault(call2, DCERPC_FAULT_OTHER); + return dcesrv_fault_disconnect(call2, + DCERPC_NCA_S_PROTO_ERROR); } if (call->pkt.ptype != call2->pkt.ptype) { /* trying to play silly buggers are we? */ - return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR); + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); } if (memcmp(call->pkt.drep, call2->pkt.drep, sizeof(pkt->drep)) != 0) { - return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR); + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); } if (call->pkt.call_id != call2->pkt.call_id) { - return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR); + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); } if (call->pkt.u.request.context_id != call2->pkt.u.request.context_id) { - return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR); + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); } if (call->pkt.u.request.opnum != call2->pkt.u.request.opnum) { - return dcesrv_fault(call2, DCERPC_NCA_S_PROTO_ERROR); + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); } alloc_size = call->pkt.u.request.stub_and_verifier.length + -- 1.9.1 From 2370eb6f01e3532e7f2ad607401e56df575ce6bf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 272/323] CVE-2015-5370: s4:rpc_server: remove pointless dcesrv_find_context() from dcesrv_bind() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BIND is the first pdu, which means the list of contexts is always empty. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index d07710e..e10f8ea 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -726,12 +726,6 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } context_id = call->pkt.u.bind.ctx_list[0].context_id; - - /* you can't bind twice on one context */ - if (dcesrv_find_context(call->conn, context_id) != NULL) { - return dcesrv_bind_nak(call, 0); - } - if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.if_version; uuid = call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid; -- 1.9.1 From f858ab770f6bf83400f3f414266ec4be526b6b3c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 273/323] CVE-2015-5370: s4:rpc_server: don't derefence an empty ctx_list array in dcesrv_alter() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index e10f8ea..a81d784 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1105,7 +1105,7 @@ static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) { NTSTATUS status; - uint32_t context_id; + const struct dcerpc_ctx_list *ctx = NULL; if (!call->conn->allow_alter) { return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); @@ -1135,12 +1135,18 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) DCERPC_BIND_REASON_ASYNTAX); } - context_id = call->pkt.u.alter.ctx_list[0].context_id; + if (call->pkt.u.alter.num_contexts < 1) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } + ctx = &call->pkt.u.alter.ctx_list[0]; + if (ctx->num_transfer_syntaxes < 1) { + return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); + } /* see if they are asking for a new interface */ - call->context = dcesrv_find_context(call->conn, context_id); + call->context = dcesrv_find_context(call->conn, ctx->context_id); if (!call->context) { - status = dcesrv_alter_new_context(call, context_id); + status = dcesrv_alter_new_context(call, ctx->context_id); if (!NT_STATUS_IS_OK(status)) { return dcesrv_alter_resp(call, DCERPC_BIND_PROVIDER_REJECT, -- 1.9.1 From d2b608584ee6657c22bd573daf3f7bb7d99211ea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 274/323] CVE-2015-5370: s4:rpc_server: changing an existing presentation context via alter_context is a protocol error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a81d784..aaf1d47 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1152,6 +1152,27 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) DCERPC_BIND_PROVIDER_REJECT, DCERPC_BIND_REASON_ASYNTAX); } + } else { + bool ok; + + ok = ndr_syntax_id_equal(&ctx->abstract_syntax, + &call->context->iface->syntax_id); + if (!ok) { + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); + } + + if (ctx->num_transfer_syntaxes != 1) { + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); + } + + ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[0], + &ndr_transfer_syntax_ndr); + if (!ok) { + return dcesrv_fault_disconnect(call, + DCERPC_NCA_S_PROTO_ERROR); + } } if (call->pkt.u.alter.assoc_group_id != 0 && -- 1.9.1 From f143f90f829b49ffb08f753e40d4b64e0f251706 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 275/323] CVE-2015-5370: s4:rpc_server: fix the order of error checking in dcesrv_alter() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The basically matches Windows 2012R2, it's not 100% but it's enough for our raw protocol tests to pass. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index aaf1d47..26e52a2 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1106,6 +1106,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) { NTSTATUS status; const struct dcerpc_ctx_list *ctx = NULL; + bool auth_ok = false; if (!call->conn->allow_alter) { return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); @@ -1127,12 +1128,12 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); } - /* handle any authentication that is being requested */ - if (!dcesrv_auth_alter(call)) { - /* TODO: work out the right reject code */ - return dcesrv_alter_resp(call, - DCERPC_BIND_PROVIDER_REJECT, - DCERPC_BIND_REASON_ASYNTAX); + auth_ok = dcesrv_auth_alter(call); + if (!auth_ok) { + if (call->in_auth_info.auth_type == DCERPC_AUTH_TYPE_NONE) { + return dcesrv_fault_disconnect(call, + DCERPC_FAULT_ACCESS_DENIED); + } } if (call->pkt.u.alter.num_contexts < 1) { @@ -1186,6 +1187,17 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) DCERPC_BIND_REASON_ASYNTAX); } + /* handle any authentication that is being requested */ + if (!auth_ok) { + if (call->in_auth_info.auth_type != + call->conn->auth_state.auth_type) + { + return dcesrv_fault_disconnect(call, + DCERPC_FAULT_SEC_PKG_ERROR); + } + return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED); + } + return dcesrv_alter_resp(call, DCERPC_BIND_ACK_RESULT_ACCEPTANCE, DCERPC_BIND_ACK_REASON_NOT_SPECIFIED); -- 1.9.1 From 13df607274e0786f401747ce1d97864cff39eb5e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 276/323] CVE-2015-5370: s4:rpc_server: failing authentication should generate a SEC_PKG_ERROR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 26e52a2..5c5aca6 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1066,13 +1066,7 @@ static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, status = dcesrv_auth_alter_ack(call, &pkt); if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) - || NT_STATUS_EQUAL(status, NT_STATUS_LOGON_FAILURE) - || NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) - || NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) { - return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); - } - return dcesrv_fault(call, 0); + return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR); } rep = talloc_zero(call, struct data_blob_list_item); -- 1.9.1 From c3488f55b07d5cc7da78dde445e5df336034fc33 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 16:18:45 +0200 Subject: [PATCH 277/323] CVE-2015-5370: s4:rpc_server: let a failing auth3 mark the authentication as invalid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following requests will generate a fault with ACCESS_DENIED. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 2 +- source4/rpc_server/dcerpc_server.h | 1 + source4/rpc_server/dcesrv_auth.c | 11 +++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 5c5aca6..bd73061 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -940,7 +940,7 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) /* handle the auth3 in the auth code */ if (!dcesrv_auth_auth3(call)) { - return dcesrv_fault(call, DCERPC_FAULT_OTHER); + call->conn->auth_state.auth_invalid = true; } talloc_free(call); diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index cd0b0e4..595fad6 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -163,6 +163,7 @@ struct dcesrv_auth { bool client_hdr_signing; bool hdr_signing; bool auth_finished; + bool auth_invalid; }; struct dcesrv_connection_context { diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index afa584b..f3de2c3 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -275,6 +275,13 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call) /* Now that we are authenticated, go back to the generic session key... */ dce_conn->auth_state.session_key = dcesrv_generic_session_key; + + if (call->out_auth_info->credentials.length != 0) { + + DEBUG(4, ("GENSEC produced output token (len=%u) at bind_auth3\n", + (unsigned)call->out_auth_info->credentials.length)); + return false; + } return true; } else { DEBUG(4, ("GENSEC mech rejected the incoming authentication at bind_auth3: %s\n", @@ -402,6 +409,10 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) return false; } + if (dce_conn->auth_state.auth_invalid) { + return false; + } + if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { hdr_size += 16; } -- 1.9.1 From b9760d55a665f805a4854b18419545c217920cd4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jun 2015 08:10:46 +0200 Subject: [PATCH 278/323] CVE-2015-5370: s4:rpc_server: disconnect after a failing dcesrv_auth_request() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index bd73061..b8df792 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1473,6 +1473,13 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, } if (!dcesrv_auth_request(call, &blob)) { + /* + * We don't use dcesrv_fault_disconnect() + * here, because we don't want to set + * DCERPC_PFC_FLAG_DID_NOT_EXECUTE + */ + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - failed"); return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); } } -- 1.9.1 From dc87807741168249323055034f290716be573223 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2015 13:55:27 +0200 Subject: [PATCH 279/323] CVE-2015-5370: s4:rpc_server: give the correct reject reasons for invalid auth_level values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 17 ++++++++++++++--- source4/rpc_server/dcesrv_auth.c | 24 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index b8df792..87aae45 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -805,9 +805,20 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) /* handle any authentication that is being requested */ if (!dcesrv_auth_bind(call)) { - talloc_free(call->context); - call->context = NULL; - return dcesrv_bind_nak(call, DCERPC_BIND_REASON_INVALID_AUTH_TYPE); + struct dcesrv_auth *auth = &call->conn->auth_state; + + TALLOC_FREE(call->context); + + if (auth->auth_level != DCERPC_AUTH_LEVEL_NONE) { + /* + * We only give INVALID_AUTH_TYPE if the auth_level was + * valid. + */ + return dcesrv_bind_nak(call, + DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE); + } + return dcesrv_bind_nak(call, + DCERPC_BIND_NAK_REASON_NOT_SPECIFIED); } /* setup a bind_ack */ diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index f3de2c3..2b3f8b0 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -60,6 +60,30 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) return false; } + switch (call->in_auth_info.auth_level) { + case DCERPC_AUTH_LEVEL_CONNECT: + case DCERPC_AUTH_LEVEL_CALL: + case DCERPC_AUTH_LEVEL_PACKET: + case DCERPC_AUTH_LEVEL_INTEGRITY: + case DCERPC_AUTH_LEVEL_PRIVACY: + /* + * We evaluate auth_type only if auth_level was valid + */ + break; + default: + /* + * Setting DCERPC_AUTH_LEVEL_NONE, + * gives the caller a chance to decide what + * reject_reason to use + * + * Note: DCERPC_AUTH_LEVEL_NONE == 1 + */ + auth->auth_type = DCERPC_AUTH_TYPE_NONE; + auth->auth_level = DCERPC_AUTH_LEVEL_NONE; + auth->auth_context_id = 0; + return false; + } + auth->auth_type = call->in_auth_info.auth_type; auth->auth_level = call->in_auth_info.auth_level; auth->auth_context_id = call->in_auth_info.auth_context_id; -- 1.9.1 From b7a1caaa319bceea3e264d64670b369da2d8bc18 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 17:21:05 +0200 Subject: [PATCH 280/323] CVE-2015-5370: s4:rpc_server: check frag_length for requests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note this is not the negotiated fragment size, but a hardcoded maximum. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 87aae45..80d4ee8 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1483,6 +1483,21 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, DCERPC_NCA_S_PROTO_ERROR); } + if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) { + /* + * We don't use dcesrv_fault_disconnect() + * here, because we don't want to set + * DCERPC_PFC_FLAG_DID_NOT_EXECUTE + * + * Note that we don't check against the negotiated + * max_recv_frag, but a hard coded value. + */ + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - frag_length too large"); + return dcesrv_fault(call, + DCERPC_NCA_S_PROTO_ERROR); + } + if (!dcesrv_auth_request(call, &blob)) { /* * We don't use dcesrv_fault_disconnect() -- 1.9.1 From e967b6bfb61c8336cac751d556bdd03ac2a3d912 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Jun 2015 14:18:09 +0200 Subject: [PATCH 281/323] CVE-2015-5370: s4:rpc_server: limit allocation and alloc_hint to 4 MByte MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 45 +++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 80d4ee8..50fe5c0 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1514,7 +1514,9 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, if (call->pkt.ptype == DCERPC_PKT_REQUEST && !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { struct dcesrv_call_state *call2 = call; - uint32_t alloc_size; + size_t available; + size_t alloc_size; + size_t alloc_hint; /* this is a continuation of an existing call - find the call then tack it on the end */ @@ -1546,18 +1548,43 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, DCERPC_NCA_S_PROTO_ERROR); } + /* + * Up to 4 MByte are allowed by all fragments + */ + available = DCERPC_NCACN_PAYLOAD_MAX_SIZE; + if (call->pkt.u.request.stub_and_verifier.length > available) { + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - current payload too large"); + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } + available -= call->pkt.u.request.stub_and_verifier.length; + if (call2->pkt.u.request.alloc_hint > available) { + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - alloc hint too large"); + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } + if (call2->pkt.u.request.stub_and_verifier.length > available) { + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - new payload too large"); + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } + alloc_hint = call->pkt.u.request.stub_and_verifier.length + + call2->pkt.u.request.alloc_hint; + /* allocate at least 1 byte */ + alloc_hint = MAX(alloc_hint, 1); alloc_size = call->pkt.u.request.stub_and_verifier.length + call2->pkt.u.request.stub_and_verifier.length; - if (call->pkt.u.request.alloc_hint > alloc_size) { - alloc_size = call->pkt.u.request.alloc_hint; - } + alloc_size = MAX(alloc_size, alloc_hint); call->pkt.u.request.stub_and_verifier.data = talloc_realloc(call, call->pkt.u.request.stub_and_verifier.data, uint8_t, alloc_size); if (!call->pkt.u.request.stub_and_verifier.data) { - return dcesrv_fault(call2, DCERPC_FAULT_OTHER); + TALLOC_FREE(call2); + return dcesrv_fault_with_flags(call, + DCERPC_FAULT_OUT_OF_RESOURCES, + DCERPC_PFC_FLAG_DID_NOT_EXECUTE); } memcpy(call->pkt.u.request.stub_and_verifier.data + call->pkt.u.request.stub_and_verifier.length, @@ -1575,6 +1602,14 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, just put it on the incoming_fragmented_call_list and wait for the rest */ if (call->pkt.ptype == DCERPC_PKT_REQUEST && !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) { + /* + * Up to 4 MByte are allowed by all fragments + */ + if (call->pkt.u.request.alloc_hint > DCERPC_NCACN_PAYLOAD_MAX_SIZE) { + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - initial alloc hint too large"); + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST); return NT_STATUS_OK; } -- 1.9.1 From 24dc4076bd70a561d9450544ba01a2b978ce8291 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Jul 2015 05:01:26 +0200 Subject: [PATCH 282/323] CVE-2015-5370: s4:rpc_server: only allow one fragmented call_id at a time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's a protocol error if the client doesn't send all fragments of a request in one go. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 142 +++++++++++++++++++++---------------- 1 file changed, 80 insertions(+), 62 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 50fe5c0..ad3b02f 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1430,6 +1430,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, { NTSTATUS status; struct dcesrv_call_state *call; + struct dcesrv_call_state *existing = NULL; call = talloc_zero(dce_conn, struct dcesrv_call_state); if (!call) { @@ -1498,6 +1499,54 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, DCERPC_NCA_S_PROTO_ERROR); } + if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) { + /* only one request is possible in the fragmented list */ + if (dce_conn->incoming_fragmented_call_list != NULL) { + TALLOC_FREE(call); + call = dce_conn->incoming_fragmented_call_list; + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - " + "existing fragmented call"); + return dcesrv_fault(call, + DCERPC_NCA_S_PROTO_ERROR); + } + } else { + const struct dcerpc_request *nr = &call->pkt.u.request; + const struct dcerpc_request *er = NULL; + int cmp; + + existing = dcesrv_find_fragmented_call(dce_conn, + call->pkt.call_id); + if (existing == NULL) { + dcesrv_call_disconnect_after(call, + "dcesrv_auth_request - " + "no existing fragmented call"); + return dcesrv_fault(call, + DCERPC_NCA_S_PROTO_ERROR); + } + er = &existing->pkt.u.request; + + if (call->pkt.ptype != existing->pkt.ptype) { + /* trying to play silly buggers are we? */ + return dcesrv_fault_disconnect(existing, + DCERPC_NCA_S_PROTO_ERROR); + } + cmp = memcmp(call->pkt.drep, existing->pkt.drep, + sizeof(pkt->drep)); + if (cmp != 0) { + return dcesrv_fault_disconnect(existing, + DCERPC_NCA_S_PROTO_ERROR); + } + if (nr->context_id != er->context_id) { + return dcesrv_fault_disconnect(existing, + DCERPC_NCA_S_PROTO_ERROR); + } + if (nr->opnum != er->opnum) { + return dcesrv_fault_disconnect(existing, + DCERPC_NCA_S_PROTO_ERROR); + } + } + if (!dcesrv_auth_request(call, &blob)) { /* * We don't use dcesrv_fault_disconnect() @@ -1511,91 +1560,60 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, } /* see if this is a continued packet */ - if (call->pkt.ptype == DCERPC_PKT_REQUEST && - !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { - struct dcesrv_call_state *call2 = call; + if (existing != NULL) { + struct dcerpc_request *er = &existing->pkt.u.request; + const struct dcerpc_request *nr = &call->pkt.u.request; size_t available; size_t alloc_size; size_t alloc_hint; - /* this is a continuation of an existing call - find the call - then tack it on the end */ - call = dcesrv_find_fragmented_call(dce_conn, call2->pkt.call_id); - if (!call) { - return dcesrv_fault_disconnect(call2, - DCERPC_NCA_S_PROTO_ERROR); - } - - if (call->pkt.ptype != call2->pkt.ptype) { - /* trying to play silly buggers are we? */ - return dcesrv_fault_disconnect(call, - DCERPC_NCA_S_PROTO_ERROR); - } - if (memcmp(call->pkt.drep, call2->pkt.drep, sizeof(pkt->drep)) != 0) { - return dcesrv_fault_disconnect(call, - DCERPC_NCA_S_PROTO_ERROR); - } - if (call->pkt.call_id != call2->pkt.call_id) { - return dcesrv_fault_disconnect(call, - DCERPC_NCA_S_PROTO_ERROR); - } - if (call->pkt.u.request.context_id != call2->pkt.u.request.context_id) { - return dcesrv_fault_disconnect(call, - DCERPC_NCA_S_PROTO_ERROR); - } - if (call->pkt.u.request.opnum != call2->pkt.u.request.opnum) { - return dcesrv_fault_disconnect(call, - DCERPC_NCA_S_PROTO_ERROR); - } - /* * Up to 4 MByte are allowed by all fragments */ available = DCERPC_NCACN_PAYLOAD_MAX_SIZE; - if (call->pkt.u.request.stub_and_verifier.length > available) { - dcesrv_call_disconnect_after(call, - "dcesrv_auth_request - current payload too large"); - return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + if (er->stub_and_verifier.length > available) { + dcesrv_call_disconnect_after(existing, + "dcesrv_auth_request - existing payload too large"); + return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED); } - available -= call->pkt.u.request.stub_and_verifier.length; - if (call2->pkt.u.request.alloc_hint > available) { - dcesrv_call_disconnect_after(call, + available -= er->stub_and_verifier.length; + if (nr->alloc_hint > available) { + dcesrv_call_disconnect_after(existing, "dcesrv_auth_request - alloc hint too large"); - return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED); } - if (call2->pkt.u.request.stub_and_verifier.length > available) { - dcesrv_call_disconnect_after(call, + if (nr->stub_and_verifier.length > available) { + dcesrv_call_disconnect_after(existing, "dcesrv_auth_request - new payload too large"); - return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED); } - alloc_hint = call->pkt.u.request.stub_and_verifier.length + - call2->pkt.u.request.alloc_hint; + alloc_hint = er->stub_and_verifier.length + nr->alloc_hint; /* allocate at least 1 byte */ alloc_hint = MAX(alloc_hint, 1); - alloc_size = call->pkt.u.request.stub_and_verifier.length + - call2->pkt.u.request.stub_and_verifier.length; + alloc_size = er->stub_and_verifier.length + + nr->stub_and_verifier.length; alloc_size = MAX(alloc_size, alloc_hint); - call->pkt.u.request.stub_and_verifier.data = - talloc_realloc(call, - call->pkt.u.request.stub_and_verifier.data, + er->stub_and_verifier.data = + talloc_realloc(existing, + er->stub_and_verifier.data, uint8_t, alloc_size); - if (!call->pkt.u.request.stub_and_verifier.data) { - TALLOC_FREE(call2); - return dcesrv_fault_with_flags(call, + if (er->stub_and_verifier.data == NULL) { + TALLOC_FREE(call); + return dcesrv_fault_with_flags(existing, DCERPC_FAULT_OUT_OF_RESOURCES, DCERPC_PFC_FLAG_DID_NOT_EXECUTE); } - memcpy(call->pkt.u.request.stub_and_verifier.data + - call->pkt.u.request.stub_and_verifier.length, - call2->pkt.u.request.stub_and_verifier.data, - call2->pkt.u.request.stub_and_verifier.length); - call->pkt.u.request.stub_and_verifier.length += - call2->pkt.u.request.stub_and_verifier.length; + memcpy(er->stub_and_verifier.data + + er->stub_and_verifier.length, + nr->stub_and_verifier.data, + nr->stub_and_verifier.length); + er->stub_and_verifier.length += nr->stub_and_verifier.length; - call->pkt.pfc_flags |= (call2->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST); + existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST); - talloc_free(call2); + TALLOC_FREE(call); + call = existing; } /* this may not be the last pdu in the chain - if its isn't then -- 1.9.1 From 9582fc939a7b4d4b7de916ecb2443fdb684e577b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 10:18:13 +0200 Subject: [PATCH 283/323] CVE-2015-5370: s4:rpc_server: the assoc_group is relative to the connection (association) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All presentation contexts of a connection use the same association group. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 76 +++++++------------------------ source4/rpc_server/dcerpc_server.h | 4 ++ source4/rpc_server/handles.c | 8 ++-- source4/rpc_server/remote/dcesrv_remote.c | 8 ++-- 4 files changed, 29 insertions(+), 67 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index ad3b02f..46d16b4 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -42,9 +42,6 @@ #include "lib/util/samba_modules.h" #include "librpc/gen_ndr/ndr_dcerpc.h" -/* this is only used when the client asks for an unknown interface */ -#define DUMMY_ASSOC_GROUP 0x0FFFFFFF - extern const struct dcesrv_interface dcesrv_mgmt_interface; @@ -74,7 +71,7 @@ static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_c assoc_group = dcesrv_assoc_group_find(dce_ctx, id); if (assoc_group == NULL) { - DEBUG(0,(__location__ ": Failed to find assoc_group 0x%08x\n", id)); + DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id)); return NULL; } return talloc_reference(mem_ctx, assoc_group); @@ -714,10 +711,16 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) /* if provided, check the assoc_group is valid */ - if (call->pkt.u.bind.assoc_group_id != 0 && - lpcfg_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","assoc group checking", true) && - dcesrv_assoc_group_find(call->conn->dce_ctx, call->pkt.u.bind.assoc_group_id) == NULL) { - return dcesrv_bind_nak(call, 0); + if (call->pkt.u.bind.assoc_group_id != 0) { + call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn, + call->conn->dce_ctx, + call->pkt.u.bind.assoc_group_id); + } else { + call->conn->assoc_group = dcesrv_assoc_group_new(call->conn, + call->conn->dce_ctx); + } + if (call->conn->assoc_group == NULL) { + return dcesrv_bind_nak(call, 0); } if (call->pkt.u.bind.num_contexts < 1 || @@ -761,17 +764,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) context->conn = call->conn; context->iface = iface; context->context_id = context_id; - if (call->pkt.u.bind.assoc_group_id != 0) { - context->assoc_group = dcesrv_assoc_group_reference(context, - call->conn->dce_ctx, - call->pkt.u.bind.assoc_group_id); - } else { - context->assoc_group = dcesrv_assoc_group_new(context, call->conn->dce_ctx); - } - if (context->assoc_group == NULL) { - talloc_free(context); - return dcesrv_bind_nak(call, 0); - } + /* legacy for openchange dcesrv_mapiproxy.c */ + context->assoc_group = call->conn->assoc_group; context->private_data = NULL; DLIST_ADD(call->conn->contexts, context); call->context = context; @@ -829,18 +823,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags; pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag; pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag; - - /* - make it possible for iface->bind() to specify the assoc_group_id - This helps the openchange mapiproxy plugin to work correctly. - - metze - */ - if (call->context) { - pkt.u.bind_ack.assoc_group_id = call->context->assoc_group->id; - } else { - pkt.u.bind_ack.assoc_group_id = DUMMY_ASSOC_GROUP; - } + pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id; if (iface) { endpoint = dcerpc_binding_get_string_option( @@ -1000,18 +983,8 @@ static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_ context->conn = call->conn; context->iface = iface; context->context_id = context_id; - if (call->pkt.u.alter.assoc_group_id != 0) { - context->assoc_group = dcesrv_assoc_group_reference(context, - call->conn->dce_ctx, - call->pkt.u.alter.assoc_group_id); - } else { - context->assoc_group = dcesrv_assoc_group_new(context, call->conn->dce_ctx); - } - if (context->assoc_group == NULL) { - talloc_free(context); - call->context = NULL; - return NT_STATUS_NO_MEMORY; - } + /* legacy for openchange dcesrv_mapiproxy.c */ + context->assoc_group = call->conn->assoc_group; context->private_data = NULL; DLIST_ADD(call->conn->contexts, context); call->context = context; @@ -1059,11 +1032,7 @@ static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags; pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag; pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag; - if (result == 0) { - pkt.u.alter_resp.assoc_group_id = call->context->assoc_group->id; - } else { - pkt.u.alter_resp.assoc_group_id = 0; - } + pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id; pkt.u.alter_resp.num_results = 1; pkt.u.alter_resp.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx); if (!pkt.u.alter_resp.ctx_list) { @@ -1181,17 +1150,6 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) } } - if (call->pkt.u.alter.assoc_group_id != 0 && - lpcfg_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","assoc group checking", true) && - call->pkt.u.alter.assoc_group_id != call->context->assoc_group->id) { - DEBUG(0,(__location__ ": Failed attempt to use new assoc_group in alter context (0x%08x 0x%08x)\n", - call->context->assoc_group->id, call->pkt.u.alter.assoc_group_id)); - /* TODO: can they ask for a new association group? */ - return dcesrv_alter_resp(call, - DCERPC_BIND_PROVIDER_REJECT, - DCERPC_BIND_REASON_ASYNTAX); - } - /* handle any authentication that is being requested */ if (!auth_ok) { if (call->in_auth_info.auth_type != diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 595fad6..7e8b18a 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -170,6 +170,7 @@ struct dcesrv_connection_context { struct dcesrv_connection_context *next, *prev; uint32_t context_id; + /* TODO: remove this legacy (for openchange) in master */ struct dcesrv_assoc_group *assoc_group; /* the connection this is on */ @@ -269,6 +270,9 @@ struct dcesrv_connection { bool allow_auth3; bool allow_alter; bool allow_request; + + /* the association group the connection belongs to */ + struct dcesrv_assoc_group *assoc_group; }; diff --git a/source4/rpc_server/handles.c b/source4/rpc_server/handles.c index f99ee1d..820da49 100644 --- a/source4/rpc_server/handles.c +++ b/source4/rpc_server/handles.c @@ -46,7 +46,7 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_contex sid = &context->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; - h = talloc_zero(context->assoc_group, struct dcesrv_handle); + h = talloc_zero(context->conn->assoc_group, struct dcesrv_handle); if (!h) { return NULL; } @@ -56,12 +56,12 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_contex talloc_free(h); return NULL; } - h->assoc_group = context->assoc_group; + h->assoc_group = context->conn->assoc_group; h->iface = context->iface; h->wire_handle.handle_type = handle_type; h->wire_handle.uuid = GUID_random(); - DLIST_ADD(context->assoc_group->handles, h); + DLIST_ADD(context->conn->assoc_group->handles, h); talloc_set_destructor(h, dcesrv_handle_destructor); @@ -87,7 +87,7 @@ _PUBLIC_ struct dcesrv_handle *dcesrv_handle_fetch( return dcesrv_handle_new(context, handle_type); } - for (h=context->assoc_group->handles; h; h=h->next) { + for (h=context->conn->assoc_group->handles; h; h=h->next) { if (h->wire_handle.handle_type == p->handle_type && GUID_equal(&p->uuid, &h->wire_handle.uuid)) { if (handle_type != DCESRV_HANDLE_ANY && diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index be4bd12..3eb0ad4 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -117,9 +117,9 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct } /* If we already have a remote association group ID, then use that */ - if (dce_call->context->assoc_group->proxied_id != 0) { + if (dce_call->conn->assoc_group->proxied_id != 0) { status = dcerpc_binding_set_assoc_group_id(b, - dce_call->context->assoc_group->proxied_id); + dce_call->conn->assoc_group->proxied_id); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("dcerpc_binding_set_assoc_group_id() - %s'\n", nt_errstr(status))); @@ -148,8 +148,8 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct return status; } - if (dce_call->context->assoc_group->proxied_id == 0) { - dce_call->context->assoc_group->proxied_id = + if (dce_call->conn->assoc_group->proxied_id == 0) { + dce_call->conn->assoc_group->proxied_id = dcerpc_binding_get_assoc_group_id(priv->c_pipe->binding); } -- 1.9.1 From fc9ba79a0770442dd3d32db159e6c746ef103240 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Jul 2015 10:18:13 +0200 Subject: [PATCH 284/323] CVE-2015-5370: s4:rpc_server: reject DCERPC_PFC_FLAG_PENDING_CANCEL with DCERPC_FAULT_NO_CALL_ACTIVE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/rpc_server/dcerpc_server.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 46d16b4..8c69351 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1468,6 +1468,10 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, return dcesrv_fault(call, DCERPC_NCA_S_PROTO_ERROR); } + if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) { + return dcesrv_fault_disconnect(call, + DCERPC_FAULT_NO_CALL_ACTIVE); + } } else { const struct dcerpc_request *nr = &call->pkt.u.request; const struct dcerpc_request *er = NULL; -- 1.9.1 From f835c217e3880bfa25fc336ab09d0b4e975a3f5d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 28 Jun 2015 01:19:57 +0200 Subject: [PATCH 285/323] CVE-2015-5370: librpc/rpc: don't allow pkt->auth_length == 0 in dcerpc_pull_auth_trailer() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All callers should have already checked that. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- librpc/rpc/dcerpc_util.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index 2f81447..43e1b7f 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -102,6 +102,11 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, } /* Paranoia checks for auth_length. The caller should check this... */ + if (pkt->auth_length == 0) { + return NT_STATUS_INTERNAL_ERROR; + } + + /* Paranoia checks for auth_length. The caller should check this... */ if (pkt->auth_length > pkt->frag_length) { return NT_STATUS_INTERNAL_ERROR; } -- 1.9.1 From f4a638b7a1e7143efa456a50b935dbbe04ab47da Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 9 Jul 2015 07:59:24 +0200 Subject: [PATCH 286/323] CVE-2015-5370: s3:librpc/rpc: remove auth trailer and possible padding within dcerpc_check_auth() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This simplifies the callers a lot. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/librpc/rpc/dcerpc.h | 5 ++--- source3/librpc/rpc/dcerpc_helpers.c | 31 ++++++++++++++++++++----------- source3/rpc_client/cli_pipe.c | 33 ++++++++++----------------------- source3/rpc_server/srv_pipe.c | 17 +---------------- 4 files changed, 33 insertions(+), 53 deletions(-) diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h index e7d66b7..0a82e7e 100644 --- a/source3/librpc/rpc/dcerpc.h +++ b/source3/librpc/rpc/dcerpc.h @@ -83,8 +83,7 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, struct ncacn_packet *pkt, DATA_BLOB *pkt_trailer, - size_t header_size, - DATA_BLOB *raw_pkt, - size_t *pad_len); + uint8_t header_size, + DATA_BLOB *raw_pkt); #endif /* __S3_DCERPC_H__ */ diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index 96074a4..bb1da46 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -481,19 +481,18 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, * * @param auth The auth data for the connection * @param pkt The actual ncacn_packet -* @param pkt_trailer The stub_and_verifier part of the packet +* @param pkt_trailer [in][out] The stub_and_verifier part of the packet, +* the auth_trailer and padding will be removed. * @param header_size The header size * @param raw_pkt The whole raw packet data blob -* @param pad_len [out] The padding length used in the packet * * @return A NTSTATUS error code */ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, struct ncacn_packet *pkt, DATA_BLOB *pkt_trailer, - size_t header_size, - DATA_BLOB *raw_pkt, - size_t *pad_len) + uint8_t header_size, + DATA_BLOB *raw_pkt) { struct gensec_security *gensec_security; NTSTATUS status; @@ -502,6 +501,14 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, DATA_BLOB full_pkt; DATA_BLOB data; + /* + * These check should be done in the caller. + */ + SMB_ASSERT(raw_pkt->length == pkt->frag_length); + SMB_ASSERT(header_size <= pkt->frag_length); + SMB_ASSERT(pkt_trailer->length < pkt->frag_length); + SMB_ASSERT((pkt_trailer->length + header_size) <= pkt->frag_length); + switch (auth->auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: DEBUG(10, ("Requested Privacy.\n")); @@ -515,7 +522,6 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, if (pkt->auth_length != 0) { break; } - *pad_len = 0; return NT_STATUS_OK; case DCERPC_AUTH_LEVEL_NONE: @@ -524,7 +530,6 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, "authenticated connection!\n")); return NT_STATUS_INVALID_PARAMETER; } - *pad_len = 0; return NT_STATUS_OK; default: @@ -543,10 +548,11 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, return status; } + pkt_trailer->length -= auth_length; data = data_blob_const(raw_pkt->data + header_size, - pkt_trailer->length - auth_length); - full_pkt = data_blob_const(raw_pkt->data, - raw_pkt->length - auth_info.credentials.length); + pkt_trailer->length); + full_pkt = data_blob_const(raw_pkt->data, raw_pkt->length); + full_pkt.length -= auth_info.credentials.length; switch (auth->auth_type) { case DCERPC_AUTH_TYPE_NONE: @@ -571,10 +577,13 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, * pkt_trailer actually has a copy of the raw data, and they * are still both used in later calls */ if (auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { + if (pkt_trailer->length != data.length) { + return NT_STATUS_INVALID_PARAMETER; + } memcpy(pkt_trailer->data, data.data, data.length); } - *pad_len = auth_info.auth_pad_length; + pkt_trailer->length -= auth_info.auth_pad_length; data_blob_free(&auth_info.credentials); return NT_STATUS_OK; } diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 6e0a7ea..0fb848f 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -391,9 +391,9 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, DATA_BLOB *rdata, DATA_BLOB *reply_pdu) { - struct dcerpc_response *r; + const struct dcerpc_response *r = NULL; + DATA_BLOB tmp_stub = data_blob_null; NTSTATUS ret = NT_STATUS_OK; - size_t pad_len = 0; /* * Point the return values at the real data including the RPC @@ -427,37 +427,24 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, r = &pkt->u.response; + tmp_stub.data = r->stub_and_verifier.data; + tmp_stub.length = r->stub_and_verifier.length; + /* Here's where we deal with incoming sign/seal. */ ret = dcerpc_check_auth(cli->auth, pkt, - &r->stub_and_verifier, + &tmp_stub, DCERPC_RESPONSE_LENGTH, - pdu, &pad_len); + pdu); if (!NT_STATUS_IS_OK(ret)) { return ret; } - if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - /* Point the return values at the NDR data. */ - rdata->data = r->stub_and_verifier.data; - - if (pkt->auth_length) { - /* We've already done integer wrap tests in - * dcerpc_check_auth(). */ - rdata->length = r->stub_and_verifier.length - - pad_len - - DCERPC_AUTH_TRAILER_LENGTH - - pkt->auth_length; - } else { - rdata->length = r->stub_and_verifier.length; - } + *rdata = tmp_stub; - DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n", + DEBUG(10, ("Got pdu len %lu, data_len %lu\n", (long unsigned int)pdu->length, - (long unsigned int)rdata->length, - (unsigned int)pad_len)); + (long unsigned int)rdata->length)); /* * If this is the first reply, and the allocation hint is diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index e6e39df..e5c7063 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1437,7 +1437,6 @@ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth, { NTSTATUS status; size_t hdr_size = DCERPC_REQUEST_LENGTH; - size_t pad_len; DEBUG(10, ("Checking request auth.\n")); @@ -1448,25 +1447,11 @@ static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth, /* in case of sealing this function will unseal the data in place */ status = dcerpc_check_auth(auth, pkt, &pkt->u.request.stub_and_verifier, - hdr_size, raw_pkt, - &pad_len); + hdr_size, raw_pkt); if (!NT_STATUS_IS_OK(status)) { return status; } - - /* remove padding and auth trailer, - * this way the caller will get just the data */ - if (pkt->auth_length) { - size_t trail_len = pad_len - + DCERPC_AUTH_TRAILER_LENGTH - + pkt->auth_length; - if (pkt->u.request.stub_and_verifier.length < trail_len) { - return NT_STATUS_INFO_LENGTH_MISMATCH; - } - pkt->u.request.stub_and_verifier.length -= trail_len; - } - return NT_STATUS_OK; } -- 1.9.1 From 1c226e10cbcf3c53e6ad02a95c4d3b440579fc01 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 9 Jul 2015 07:59:24 +0200 Subject: [PATCH 287/323] CVE-2015-5370: s3:librpc/rpc: let dcerpc_check_auth() auth_{type,level} against the expected values. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/librpc/rpc/dcerpc_helpers.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index bb1da46..054647c 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -548,6 +548,14 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, return status; } + if (auth_info.auth_type != auth->auth_type) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (auth_info.auth_level != auth->auth_level) { + return NT_STATUS_INVALID_PARAMETER; + } + pkt_trailer->length -= auth_length; data = data_blob_const(raw_pkt->data + header_size, pkt_trailer->length); -- 1.9.1 From f03954bc9c4f712449de4f28a59518e94a902691 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 288/323] CVE-2015-5370: s3:rpc_client: make use of dcerpc_pull_auth_trailer() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The does much more validation than dcerpc_pull_dcerpc_auth(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 0fb848f..9269f24 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1807,17 +1807,15 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) return; default: - /* Paranoid lenght checks */ - if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH - + pkt->auth_length) { - tevent_req_nterror(req, - NT_STATUS_INFO_LENGTH_MISMATCH); + if (pkt->auth_length == 0) { + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); return; } + /* get auth credentials */ - status = dcerpc_pull_dcerpc_auth(talloc_tos(), - &pkt->u.bind_ack.auth_info, - &auth, false); + status = dcerpc_pull_auth_trailer(pkt, talloc_tos(), + &pkt->u.bind_ack.auth_info, + &auth, NULL, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to pull dcerpc auth: %s.\n", nt_errstr(status))); -- 1.9.1 From 18008685cb960d6516d5c7f1fe8bc6df380b707d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 289/323] CVE-2015-5370: s3:rpc_client: make use of dcerpc_verify_ncacn_packet_header() in cli_pipe_validate_current_pdu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 111 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 96 insertions(+), 15 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 9269f24..56e5d17 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -416,17 +416,89 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, /* Ensure we have the correct type. */ switch (pkt->ptype) { - case DCERPC_PKT_ALTER_RESP: + case DCERPC_PKT_BIND_NAK: + DEBUG(1, (__location__ ": Bind NACK received from %s!\n", + rpccli_pipe_txt(talloc_tos(), cli))); + + ret = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_BIND_NAK, + 0, /* max_auth_info */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST, + 0); /* optional flags */ + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(1, (__location__ ": Connection to %s got an unexpected " + "RPC packet type - %u, expected %u: %s\n", + rpccli_pipe_txt(talloc_tos(), cli), + pkt->ptype, expected_pkt_type, + nt_errstr(ret))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + return ret; + } + + /* Use this for now... */ + return NT_STATUS_NETWORK_ACCESS_DENIED; + case DCERPC_PKT_BIND_ACK: + ret = dcerpc_verify_ncacn_packet_header(pkt, + expected_pkt_type, + pkt->u.bind_ack.auth_info.length, + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST, + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(1, (__location__ ": Connection to %s got an unexpected " + "RPC packet type - %u, expected %u: %s\n", + rpccli_pipe_txt(talloc_tos(), cli), + pkt->ptype, expected_pkt_type, + nt_errstr(ret))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + return ret; + } - /* Client code never receives this kind of packets */ break; + case DCERPC_PKT_ALTER_RESP: + ret = dcerpc_verify_ncacn_packet_header(pkt, + expected_pkt_type, + pkt->u.alter_resp.auth_info.length, + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST, + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(1, (__location__ ": Connection to %s got an unexpected " + "RPC packet type - %u, expected %u: %s\n", + rpccli_pipe_txt(talloc_tos(), cli), + pkt->ptype, expected_pkt_type, + nt_errstr(ret))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + return ret; + } + + break; case DCERPC_PKT_RESPONSE: r = &pkt->u.response; + ret = dcerpc_verify_ncacn_packet_header(pkt, + expected_pkt_type, + r->stub_and_verifier.length, + 0, /* required_flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(1, (__location__ ": Connection to %s got an unexpected " + "RPC packet type - %u, expected %u: %s\n", + rpccli_pipe_txt(talloc_tos(), cli), + pkt->ptype, expected_pkt_type, + nt_errstr(ret))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + return ret; + } + tmp_stub.data = r->stub_and_verifier.data; tmp_stub.length = r->stub_and_verifier.length; @@ -436,6 +508,12 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, DCERPC_RESPONSE_LENGTH, pdu); if (!NT_STATUS_IS_OK(ret)) { + DEBUG(1, (__location__ ": Connection to %s got an unexpected " + "RPC packet type - %u, expected %u: %s\n", + rpccli_pipe_txt(talloc_tos(), cli), + pkt->ptype, expected_pkt_type, + nt_errstr(ret))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); return ret; } @@ -465,14 +543,24 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, break; - case DCERPC_PKT_BIND_NAK: - DEBUG(1, (__location__ ": Bind NACK received from %s!\n", - rpccli_pipe_txt(talloc_tos(), cli))); - /* Use this for now... */ - return NT_STATUS_NETWORK_ACCESS_DENIED; - case DCERPC_PKT_FAULT: + ret = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_FAULT, + 0, /* max_auth_info */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST, + DCERPC_PFC_FLAG_DID_NOT_EXECUTE); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(1, (__location__ ": Connection to %s got an unexpected " + "RPC packet type - %u, expected %u: %s\n", + rpccli_pipe_txt(talloc_tos(), cli), + pkt->ptype, expected_pkt_type, + nt_errstr(ret))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + return ret; + } + DEBUG(1, (__location__ ": RPC fault code %s received " "from %s!\n", dcerpc_errstr(talloc_tos(), @@ -489,13 +577,6 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, return NT_STATUS_RPC_PROTOCOL_ERROR; } - if (pkt->ptype != expected_pkt_type) { - DEBUG(3, (__location__ ": Connection to %s got an unexpected " - "RPC packet type - %u, not %u\n", - rpccli_pipe_txt(talloc_tos(), cli), - pkt->ptype, expected_pkt_type)); - return NT_STATUS_RPC_PROTOCOL_ERROR; - } if (pkt->call_id != call_id) { DEBUG(3, (__location__ ": Connection to %s got an unexpected " -- 1.9.1 From a1af2e11ceeacc7cfc8e7555c85dd7338683135c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jul 2015 14:48:38 +0200 Subject: [PATCH 290/323] CVE-2015-5370: s3:rpc_client: protect rpc_api_pipe_got_pdu() against too large payloads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 56e5d17..26f709d 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -990,6 +990,11 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) return; } + if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } + /* Now copy the data portion out of the pdu into rbuf. */ if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) { if (!data_blob_realloc(NULL, &state->reply_pdu, -- 1.9.1 From 525e9e2a52524076bad11c1a64794bcec80eeefb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 22:51:18 +0200 Subject: [PATCH 291/323] CVE-2015-5370: s3:rpc_client: verify auth_{type,level} in rpc_pipe_bind_step_one_done() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 26f709d..1d1ccad 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1908,6 +1908,21 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) tevent_req_nterror(req, status); return; } + + if (auth.auth_type != pauth->auth_type) { + DEBUG(0, (__location__ " Auth type %u mismatch expected %u.\n", + auth.auth_type, pauth->auth_type)); + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); + return; + } + + if (auth.auth_level != pauth->auth_level) { + DEBUG(0, (__location__ " Auth level %u mismatch expected %u.\n", + auth.auth_level, pauth->auth_level)); + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); + return; + } + break; } -- 1.9.1 From 5c06e67169526a8594fcf26d68c89d237b00cbeb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 292/323] CVE-2015-5370: s3:rpc_server: make use of dcerpc_pull_auth_trailer() in api_pipe_{bind_req,alter_context,bind_auth3}() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 62 +++++++++---------------------------------- 1 file changed, 13 insertions(+), 49 deletions(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index e5c7063..82bc3df 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -733,25 +733,12 @@ static bool api_pipe_bind_req(struct pipes_struct *p, * Check if this is an authenticated bind request. */ if (pkt->auth_length) { - /* Quick length check. Won't catch a bad auth footer, - * prevents overrun. */ - - if (pkt->frag_length < RPC_HEADER_LEN + - DCERPC_AUTH_TRAILER_LENGTH + - pkt->auth_length) { - DEBUG(0,("api_pipe_bind_req: auth_len (%u) " - "too long for fragment %u.\n", - (unsigned int)pkt->auth_length, - (unsigned int)pkt->frag_length)); - goto err_exit; - } - /* * Decode the authentication verifier. */ - status = dcerpc_pull_dcerpc_auth(pkt, - &pkt->u.bind.auth_info, - &auth_info, p->endian); + status = dcerpc_pull_auth_trailer(pkt, pkt, + &pkt->u.bind.auth_info, + &auth_info, NULL, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n")); goto err_exit; @@ -910,23 +897,13 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) goto err; } - /* Ensure there's enough data for an authenticated request. */ - if (pkt->frag_length < RPC_HEADER_LEN - + DCERPC_AUTH_TRAILER_LENGTH - + pkt->auth_length) { - DEBUG(1,("api_pipe_ntlmssp_auth_process: auth_len " - "%u is too large.\n", - (unsigned int)pkt->auth_length)); - goto err; - } - /* * Decode the authentication verifier response. */ - status = dcerpc_pull_dcerpc_auth(pkt, - &pkt->u.auth3.auth_info, - &auth_info, p->endian); + status = dcerpc_pull_auth_trailer(pkt, pkt, + &pkt->u.auth3.auth_info, + &auth_info, NULL, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to unmarshall dcerpc_auth.\n")); goto err; @@ -1034,34 +1011,21 @@ static bool api_pipe_alter_context(struct pipes_struct *p, * Check if this is an authenticated alter context request. */ if (pkt->auth_length) { - /* Quick length check. Won't catch a bad auth footer, - * prevents overrun. */ - - if (pkt->frag_length < RPC_HEADER_LEN + - DCERPC_AUTH_TRAILER_LENGTH + - pkt->auth_length) { - DEBUG(0,("api_pipe_alter_context: auth_len (%u) " - "too long for fragment %u.\n", - (unsigned int)pkt->auth_length, - (unsigned int)pkt->frag_length )); + /* We can only finish if the pipe is unbound for now */ + if (p->pipe_bound) { + DEBUG(0, (__location__ ": Pipe already bound, " + "Altering Context not yet supported!\n")); goto err_exit; } - status = dcerpc_pull_dcerpc_auth(pkt, - &pkt->u.bind.auth_info, - &auth_info, p->endian); + status = dcerpc_pull_auth_trailer(pkt, pkt, + &pkt->u.bind.auth_info, + &auth_info, NULL, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n")); goto err_exit; } - /* We can only finish if the pipe is unbound for now */ - if (p->pipe_bound) { - DEBUG(0, (__location__ ": Pipe already bound, " - "Altering Context not yet supported!\n")); - goto err_exit; - } - if (auth_info.auth_type != p->auth.auth_type) { DEBUG(0, ("Auth type mismatch! Client sent %d, " "but auth was started as type %d!\n", -- 1.9.1 From 68d13c8d3cefb8b0f24b569da43efdb69b615cf8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 12:38:55 +0100 Subject: [PATCH 293/323] CVE-2015-5370: s3:rpc_server: let a failing sec_verification_trailer mark the connection as broken BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher --- source3/rpc_server/srv_pipe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 82bc3df..610105c 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1243,6 +1243,7 @@ static bool api_pipe_request(struct pipes_struct *p, if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) { DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n")); + set_incoming_fault(p); setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED)); data_blob_free(&p->out_data.rdata); TALLOC_FREE(frame); -- 1.9.1 From e4b653c51693808acc8012b7adab576041e01742 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 294/323] CVE-2015-5370: s3:rpc_server: just call pipe_auth_generic_bind() in api_pipe_bind_req() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pipe_auth_generic_bind() does all the required checks already and an explicit DCERPC_AUTH_TYPE_NONE is not supported. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 45 ++++++------------------------------------- 1 file changed, 6 insertions(+), 39 deletions(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 610105c..07046d4 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -500,6 +500,7 @@ static bool pipe_auth_generic_bind(struct pipes_struct *p, p->auth.auth_ctx = gensec_security; p->auth.auth_type = auth_info->auth_type; + p->auth.auth_level = auth_info->auth_level; if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) { p->auth.client_hdr_signing = true; @@ -626,7 +627,6 @@ static bool api_pipe_bind_req(struct pipes_struct *p, { struct dcerpc_auth auth_info = {0}; uint16_t assoc_gid; - unsigned int auth_type = DCERPC_AUTH_TYPE_NONE; NTSTATUS status; struct ndr_syntax_id id; uint8_t pfc_flags = 0; @@ -744,47 +744,14 @@ static bool api_pipe_bind_req(struct pipes_struct *p, goto err_exit; } - auth_type = auth_info.auth_type; - - /* Work out if we have to sign or seal etc. */ - switch (auth_info.auth_level) { - case DCERPC_AUTH_LEVEL_INTEGRITY: - p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; - break; - case DCERPC_AUTH_LEVEL_PRIVACY: - p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY; - break; - case DCERPC_AUTH_LEVEL_CONNECT: - p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT; - break; - default: - DEBUG(0, ("Unexpected auth level (%u).\n", - (unsigned int)auth_info.auth_level )); + if (!pipe_auth_generic_bind(p, pkt, + &auth_info, &auth_resp)) { goto err_exit; } - - switch (auth_type) { - case DCERPC_AUTH_TYPE_NONE: - break; - - default: - if (!pipe_auth_generic_bind(p, pkt, - &auth_info, &auth_resp)) { - goto err_exit; - } - break; - } - } - - if (auth_type == DCERPC_AUTH_TYPE_NONE) { - /* Unauthenticated bind request. */ - /* We're finished - no more packets. */ + } else { p->auth.auth_type = DCERPC_AUTH_TYPE_NONE; - /* We must set the pipe auth_level here also. */ p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE; p->pipe_bound = True; - /* The session key was initialized from the SMB - * session in make_internal_rpc_pipe_p */ } ZERO_STRUCT(u.bind_ack); @@ -836,8 +803,8 @@ static bool api_pipe_bind_req(struct pipes_struct *p, if (auth_resp.length) { status = dcerpc_push_dcerpc_auth(pkt, - auth_type, - auth_info.auth_level, + p->auth.auth_type, + p->auth.auth_level, 0, 1, /* auth_context_id */ &auth_resp, -- 1.9.1 From 6742e38f40ed57335dc3f114421d79c26e1ec2b9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 295/323] CVE-2015-5370: s3:rpc_server: don't ignore failures of dcerpc_push_ncacn_packet() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 07046d4..ea9d50d 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -798,6 +798,7 @@ static bool api_pipe_bind_req(struct pipes_struct *p, if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n", nt_errstr(status))); + goto err_exit; } if (auth_resp.length) { @@ -1058,6 +1059,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n", nt_errstr(status))); + goto err_exit; } if (auth_resp.length) { -- 1.9.1 From 7ba34134c517007021c77ea74a01f525556f23e0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 296/323] CVE-2015-5370: s3:rpc_server: don't allow auth3 if the authentication was already finished MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ea9d50d..2926f06 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -860,8 +860,15 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__)); + /* We can only finish if the pipe is unbound for now */ + if (p->pipe_bound) { + DEBUG(0, (__location__ ": Pipe already bound, " + "AUTH3 not supported!\n")); + goto err; + } + if (pkt->auth_length == 0) { - DEBUG(1, ("No auth field sent for bind request!\n")); + DEBUG(1, ("No auth field sent for auth3 request!\n")); goto err; } -- 1.9.1 From d967a018c55512b55d1c67605757d0a643a68723 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Jul 2015 16:18:45 +0200 Subject: [PATCH 297/323] CVE-2015-5370: s3:rpc_server: let a failing auth3 mark the authentication as invalid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 2926f06..a37cb3f 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -926,7 +926,7 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) return true; err: - + p->pipe_bound = false; TALLOC_FREE(p->auth.auth_ctx); return false; } -- 1.9.1 From 59f2d96757a3cf7bd22f326eb683cbacf23b7c24 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 298/323] CVE-2015-5370: s3:rpc_server: make sure auth_level isn't changed by alter_context or auth3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index a37cb3f..96bf212 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -896,6 +896,13 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) goto err; } + if (auth_info.auth_level != p->auth.auth_level) { + DEBUG(1, ("Auth level mismatch! Client sent %d, " + "but auth was started as level %d!\n", + auth_info.auth_level, p->auth.auth_level)); + goto err; + } + gensec_security = p->auth.auth_ctx; status = auth_generic_server_step(gensec_security, @@ -1008,6 +1015,13 @@ static bool api_pipe_alter_context(struct pipes_struct *p, goto err_exit; } + if (auth_info.auth_level != p->auth.auth_level) { + DEBUG(0, ("Auth level mismatch! Client sent %d, " + "but auth was started as level %d!\n", + auth_info.auth_level, p->auth.auth_level)); + goto err_exit; + } + gensec_security = p->auth.auth_ctx; status = auth_generic_server_step(gensec_security, pkt, -- 1.9.1 From 3f117476b6bcfe983e4988d29bd09e71f1f342ef Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Jul 2015 09:15:39 +0200 Subject: [PATCH 299/323] CVE-2015-5370: s3:rpc_server: ensure that the message ordering doesn't violate the spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first pdu is always a BIND. REQUEST pdus are only allowed once the authentication is finished. A simple anonymous authentication is finished after the BIND. Real authentication may need additional ALTER or AUTH3 exchanges. Pair-Programmed-With: Stefan Metzmacher BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Jeremy Allison Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/rpc_handles.c | 1 + source3/rpc_server/rpc_pipes.h | 7 ++++++ source3/rpc_server/srv_pipe.c | 46 ++++++++++++++++++++++++++++++++++------ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/source3/rpc_server/rpc_handles.c b/source3/rpc_server/rpc_handles.c index 4e2edc6..62b545c 100644 --- a/source3/rpc_server/rpc_handles.c +++ b/source3/rpc_server/rpc_handles.c @@ -69,6 +69,7 @@ int make_base_pipes_struct(TALLOC_CTX *mem_ctx, p->msg_ctx = msg_ctx; p->transport = transport; p->endian = endian; + p->allow_bind = true; p->remote_address = tsocket_address_copy(remote_address, p); if (p->remote_address == NULL) { diff --git a/source3/rpc_server/rpc_pipes.h b/source3/rpc_server/rpc_pipes.h index 14b8705..d44ee92 100644 --- a/source3/rpc_server/rpc_pipes.h +++ b/source3/rpc_server/rpc_pipes.h @@ -131,6 +131,13 @@ struct pipes_struct { bool pipe_bound; /* + * States we can be in. + */ + bool allow_alter; + bool allow_bind; + bool allow_auth3; + + /* * Set the DCERPC_FAULT to return. */ int fault_state; diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 96bf212..3b36a2a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -282,6 +282,9 @@ static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt) p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE; p->auth.auth_type = DCERPC_AUTH_TYPE_NONE; p->pipe_bound = False; + p->allow_bind = false; + p->allow_alter = false; + p->allow_auth3 = false; return True; } @@ -636,11 +639,11 @@ static bool api_pipe_bind_req(struct pipes_struct *p, DATA_BLOB auth_blob = data_blob_null; const struct ndr_interface_table *table; - /* No rebinds on a bound pipe - use alter context. */ - if (p->pipe_bound) { - DEBUG(2,("Rejecting bind request on bound rpc connection\n")); + if (!p->allow_bind) { + DEBUG(2,("Pipe not in allow bind state\n")); return setup_bind_nak(p, pkt); } + p->allow_bind = false; if (pkt->u.bind.num_contexts == 0) { DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n")); @@ -722,7 +725,6 @@ static bool api_pipe_bind_req(struct pipes_struct *p, bind_ack_ctx.reason.value = 0; bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0]; } else { - p->pipe_bound = False; /* Rejection reason: abstract syntax not supported */ bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT; bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX; @@ -751,7 +753,6 @@ static bool api_pipe_bind_req(struct pipes_struct *p, } else { p->auth.auth_type = DCERPC_AUTH_TYPE_NONE; p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE; - p->pipe_bound = True; } ZERO_STRUCT(u.bind_ack); @@ -838,6 +839,22 @@ static bool api_pipe_bind_req(struct pipes_struct *p, p->out_data.current_pdu_sent = 0; TALLOC_FREE(auth_blob.data); + + if (bind_ack_ctx.result == 0) { + p->allow_alter = true; + p->allow_auth3 = true; + if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) { + status = pipe_auth_verify_final(p); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("pipe_auth_verify_final failed: %s\n", + nt_errstr(status))); + goto err_exit; + } + } + } else { + goto err_exit; + } + return True; err_exit: @@ -860,6 +877,11 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__)); + if (!p->allow_auth3) { + DEBUG(1, ("Pipe not in allow auth3 state.\n")); + goto err; + } + /* We can only finish if the pipe is unbound for now */ if (p->pipe_bound) { DEBUG(0, (__location__ ": Pipe already bound, " @@ -934,6 +956,10 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) err: p->pipe_bound = false; + p->allow_bind = false; + p->allow_alter = false; + p->allow_auth3 = false; + TALLOC_FREE(p->auth.auth_ctx); return false; } @@ -957,6 +983,11 @@ static bool api_pipe_alter_context(struct pipes_struct *p, DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__)); + if (!p->allow_alter) { + DEBUG(1, ("Pipe not in allow alter state.\n")); + goto err_exit; + } + if (pkt->u.bind.assoc_group_id != 0) { assoc_gid = pkt->u.bind.assoc_group_id; } else { @@ -982,7 +1013,6 @@ static bool api_pipe_alter_context(struct pipes_struct *p, bind_ack_ctx.reason.value = 0; bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0]; } else { - p->pipe_bound = False; /* Rejection reason: abstract syntax not supported */ bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT; bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX; @@ -1383,6 +1413,10 @@ void set_incoming_fault(struct pipes_struct *p) p->in_data.pdu.length = 0; p->fault_state = DCERPC_FAULT_CANT_PERFORM; + p->allow_alter = false; + p->allow_auth3 = false; + p->pipe_bound = false; + DEBUG(10, ("Setting fault state\n")); } -- 1.9.1 From 911d413779886895c9f78aff33abdfc9680e581e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 16:06:59 +0200 Subject: [PATCH 300/323] CVE-2015-5370: s3:rpc_server: use 'alter' instead of 'bind' for variables in api_pipe_alter_context() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 3b36a2a..3b746cf 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -976,7 +976,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, uint16_t assoc_gid; NTSTATUS status; union dcerpc_payload u; - struct dcerpc_ack_ctx bind_ack_ctx; + struct dcerpc_ack_ctx alter_ack_ctx; DATA_BLOB auth_resp = data_blob_null; DATA_BLOB auth_blob = data_blob_null; struct gensec_security *gensec_security; @@ -988,8 +988,8 @@ static bool api_pipe_alter_context(struct pipes_struct *p, goto err_exit; } - if (pkt->u.bind.assoc_group_id != 0) { - assoc_gid = pkt->u.bind.assoc_group_id; + if (pkt->u.alter.assoc_group_id != 0) { + assoc_gid = pkt->u.alter.assoc_group_id; } else { assoc_gid = 0x53f0; } @@ -999,24 +999,24 @@ static bool api_pipe_alter_context(struct pipes_struct *p, */ /* If the requested abstract synt uuid doesn't match our client pipe, - reject the bind_ack & set the transfer interface synt to all 0's, + reject the alter_ack & set the transfer interface synt to all 0's, ver 0 (observed when NT5 attempts to bind to abstract interfaces unknown to NT4) Needed when adding entries to a DACL from NT5 - SK */ if (check_bind_req(p, - &pkt->u.bind.ctx_list[0].abstract_syntax, - &pkt->u.bind.ctx_list[0].transfer_syntaxes[0], - pkt->u.bind.ctx_list[0].context_id)) { + &pkt->u.alter.ctx_list[0].abstract_syntax, + &pkt->u.alter.ctx_list[0].transfer_syntaxes[0], + pkt->u.alter.ctx_list[0].context_id)) { - bind_ack_ctx.result = 0; - bind_ack_ctx.reason.value = 0; - bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0]; + alter_ack_ctx.result = 0; + alter_ack_ctx.reason.value = 0; + alter_ack_ctx.syntax = pkt->u.alter.ctx_list[0].transfer_syntaxes[0]; } else { /* Rejection reason: abstract syntax not supported */ - bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT; - bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX; - bind_ack_ctx.syntax = ndr_syntax_id_null; + alter_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT; + alter_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX; + alter_ack_ctx.syntax = ndr_syntax_id_null; } /* @@ -1031,7 +1031,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, } status = dcerpc_pull_auth_trailer(pkt, pkt, - &pkt->u.bind.auth_info, + &pkt->u.alter.auth_info, &auth_info, NULL, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n")); @@ -1088,7 +1088,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, u.alter_resp.secondary_address_size = 1; u.alter_resp.num_results = 1; - u.alter_resp.ctx_list = &bind_ack_ctx; + u.alter_resp.ctx_list = &alter_ack_ctx; /* NOTE: We leave the auth_info empty so we can calculate the padding * later and then append the auth_info --simo */ @@ -1108,7 +1108,7 @@ static bool api_pipe_alter_context(struct pipes_struct *p, &u, &p->out_data.frag); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n", + DEBUG(0, ("Failed to marshall alter_resp packet. (%s)\n", nt_errstr(status))); goto err_exit; } -- 1.9.1 From 47bf5aad3bf1497152fb081d12a424c94c6d944e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 16:06:59 +0200 Subject: [PATCH 301/323] CVE-2015-5370: s3:rpc_server: verify presentation context arrays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 3b746cf..a1304d3 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -646,7 +646,12 @@ static bool api_pipe_bind_req(struct pipes_struct *p, p->allow_bind = false; if (pkt->u.bind.num_contexts == 0) { - DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n")); + DEBUG(1, ("api_pipe_bind_req: no rpc contexts around\n")); + goto err_exit; + } + + if (pkt->u.bind.ctx_list[0].num_transfer_syntaxes == 0) { + DEBUG(1, ("api_pipe_bind_req: no transfer syntaxes around\n")); goto err_exit; } @@ -988,6 +993,16 @@ static bool api_pipe_alter_context(struct pipes_struct *p, goto err_exit; } + if (pkt->u.alter.num_contexts == 0) { + DEBUG(1, ("api_pipe_alter_context: no rpc contexts around\n")); + goto err_exit; + } + + if (pkt->u.alter.ctx_list[0].num_transfer_syntaxes == 0) { + DEBUG(1, ("api_pipe_alter_context: no transfer syntaxes around\n")); + goto err_exit; + } + if (pkt->u.alter.assoc_group_id != 0) { assoc_gid = pkt->u.alter.assoc_group_id; } else { -- 1.9.1 From a77b996e2dd672e4e3f5de49e2b526602b2943f7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 16:06:59 +0200 Subject: [PATCH 302/323] CVE-2015-5370: s3:rpc_server: make use of dcerpc_verify_ncacn_packet_header() to verify incoming pdus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 82 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index a1304d3..ad4b7a8 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -30,7 +30,7 @@ #include "includes.h" #include "system/filesys.h" #include "srv_pipe_internal.h" -#include "../librpc/gen_ndr/dcerpc.h" +#include "../librpc/gen_ndr/ndr_dcerpc.h" #include "../librpc/rpc/rpc_common.h" #include "dcesrv_auth_generic.h" #include "rpc_server.h" @@ -645,6 +645,25 @@ static bool api_pipe_bind_req(struct pipes_struct *p, } p->allow_bind = false; + status = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_BIND, + pkt->u.bind.auth_info.length, + 0, /* required flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("api_pipe_bind_req: invalid pdu: %s\n", + nt_errstr(status))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + goto err_exit; + } + if (pkt->u.bind.num_contexts == 0) { DEBUG(1, ("api_pipe_bind_req: no rpc contexts around\n")); goto err_exit; @@ -887,6 +906,25 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) goto err; } + status = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_AUTH3, + pkt->u.auth3.auth_info.length, + 0, /* required flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("api_pipe_bind_auth3: invalid pdu: %s\n", + nt_errstr(status))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + goto err; + } + /* We can only finish if the pipe is unbound for now */ if (p->pipe_bound) { DEBUG(0, (__location__ ": Pipe already bound, " @@ -993,6 +1031,25 @@ static bool api_pipe_alter_context(struct pipes_struct *p, goto err_exit; } + status = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_ALTER, + pkt->u.alter.auth_info.length, + 0, /* required flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("api_pipe_alter_context: invalid pdu: %s\n", + nt_errstr(status))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + goto err_exit; + } + if (pkt->u.alter.num_contexts == 0) { DEBUG(1, ("api_pipe_alter_context: no rpc contexts around\n")); goto err_exit; @@ -1476,6 +1533,29 @@ static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt return False; } + /* + * We don't ignore DCERPC_PFC_FLAG_PENDING_CANCEL. + * TODO: we can reject it with DCERPC_FAULT_NO_CALL_ACTIVE later. + */ + status = dcerpc_verify_ncacn_packet_header(pkt, + DCERPC_PKT_REQUEST, + pkt->u.request.stub_and_verifier.length, + 0, /* required_flags */ + DCERPC_PFC_FLAG_FIRST | + DCERPC_PFC_FLAG_LAST | + 0x08 | /* this is not defined, but should be ignored */ + DCERPC_PFC_FLAG_CONC_MPX | + DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + DCERPC_PFC_FLAG_MAYBE | + DCERPC_PFC_FLAG_OBJECT_UUID); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("process_request_pdu: invalid pdu: %s\n", + nt_errstr(status))); + NDR_PRINT_DEBUG(ncacn_packet, pkt); + set_incoming_fault(p); + return false; + } + hdr2 = dcerpc_sec_vt_header2_from_ncacn_packet(pkt); if (pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) { p->header2 = hdr2; -- 1.9.1 From 12096bca9e857a5049693124ed8a93e665f3c1d6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 12:40:58 +0100 Subject: [PATCH 303/323] CVE-2015-5370: s3:rpc_server: disconnect the connection after a fatal FAULT pdu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/rpc_server.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c index 01a854c..5effe66 100644 --- a/source3/rpc_server/rpc_server.c +++ b/source3/rpc_server/rpc_server.c @@ -558,6 +558,12 @@ static void named_pipe_packet_done(struct tevent_req *subreq) return; } + if (npc->p->fault_state != 0) { + DEBUG(2, ("Disconnect after fault\n")); + sys_errno = EINVAL; + goto fail; + } + /* clear out any data that may have been left around */ npc->count = 0; TALLOC_FREE(npc->iov); @@ -1292,6 +1298,12 @@ static void dcerpc_ncacn_packet_done(struct tevent_req *subreq) goto fail; } + if (ncacn_conn->p->fault_state != 0) { + DEBUG(2, ("Disconnect after fault\n")); + sys_errno = EINVAL; + goto fail; + } + /* clear out any data that may have been left around */ ncacn_conn->count = 0; TALLOC_FREE(ncacn_conn->iov); -- 1.9.1 From 10192d897aaca9cb4b2312d9aedf51a1cc8965dc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 12:38:55 +0100 Subject: [PATCH 304/323] CVE-2015-5370: s3:rpc_server: let a failing BIND mark the connection as broken MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ad4b7a8..7e33ff0 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -278,6 +278,7 @@ static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt) p->out_data.data_sent_length = 0; p->out_data.current_pdu_sent = 0; + set_incoming_fault(p); TALLOC_FREE(p->auth.auth_ctx); p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE; p->auth.auth_type = DCERPC_AUTH_TYPE_NONE; -- 1.9.1 From a498e6d5ffdb6f387453b154f92f11ead6068a88 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 12:38:55 +0100 Subject: [PATCH 305/323] CVE-2015-5370: s3:rpc_server: use DCERPC_NCA_S_PROTO_ERROR FAULTs for protocol errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 7e33ff0..e4e40f1 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1484,7 +1484,7 @@ void set_incoming_fault(struct pipes_struct *p) data_blob_free(&p->in_data.data); p->in_data.pdu_needed_len = 0; p->in_data.pdu.length = 0; - p->fault_state = DCERPC_FAULT_CANT_PERFORM; + p->fault_state = DCERPC_NCA_S_PROTO_ERROR; p->allow_alter = false; p->allow_auth3 = false; @@ -1748,7 +1748,7 @@ done: if (!reply) { DEBUG(3,("DCE/RPC fault sent!")); set_incoming_fault(p); - setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR)); + setup_fault_pdu(p, NT_STATUS(DCERPC_NCA_S_PROTO_ERROR)); } /* pkt and p->in_data.pdu.data freed by caller */ } -- 1.9.1 From 095d6c5a128313b5b8514184d211e9eb0b392a54 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 11 Jul 2015 10:58:07 +0200 Subject: [PATCH 306/323] CVE-2015-5370: s3:librpc/rpc: remove unused dcerpc_pull_dcerpc_auth() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/librpc/rpc/dcerpc.h | 4 ---- source3/librpc/rpc/dcerpc_helpers.c | 41 ------------------------------------- 2 files changed, 45 deletions(-) diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h index 0a82e7e..b7537c2 100644 --- a/source3/librpc/rpc/dcerpc.h +++ b/source3/librpc/rpc/dcerpc.h @@ -69,10 +69,6 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx, uint32_t auth_context_id, const DATA_BLOB *credentials, DATA_BLOB *blob); -NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx, - const DATA_BLOB *blob, - struct dcerpc_auth *r, - bool bigendian); NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth, size_t header_len, size_t data_left, size_t max_xmit_frag, diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index 054647c..48410bb 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -177,47 +177,6 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx, } /** -* @brief Decodes a dcerpc_auth blob -* -* @param mem_ctx The memory context on which to allocate the packet -* elements -* @param blob The blob of data to decode -* @param r An empty dcerpc_auth structure, must not be NULL -* -* @return a NTSTATUS error code -*/ -NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx, - const DATA_BLOB *blob, - struct dcerpc_auth *r, - bool bigendian) -{ - enum ndr_err_code ndr_err; - struct ndr_pull *ndr; - - ndr = ndr_pull_init_blob(blob, mem_ctx); - if (!ndr) { - return NT_STATUS_NO_MEMORY; - } - if (bigendian) { - ndr->flags |= LIBNDR_FLAG_BIGENDIAN; - } - - ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, r); - - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(ndr); - return ndr_map_error2ntstatus(ndr_err); - } - talloc_free(ndr); - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_DEBUG(dcerpc_auth, r); - } - - return NT_STATUS_OK; -} - -/** * @brief Calculate how much data we can in a packet, including calculating * auth token and pad lengths. * -- 1.9.1 From e5046682cb27b2e13fc12ea755b0b1bce550455d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 307/323] CVE-2015-5370: s3:rpc_server: check the transfer syntax in check_bind_req() first MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index e4e40f1..27fd83c 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -350,20 +350,30 @@ static bool check_bind_req(struct pipes_struct *p, bool ok; const char *interface_name = NULL; - DEBUG(3,("check_bind_req for %s\n", + DEBUG(3,("check_bind_req for %s context_id=%u\n", ndr_interface_name(&abstract->uuid, - abstract->if_version))); + abstract->if_version), + (unsigned)context_id)); + + ok = ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr); + if (!ok) { + DEBUG(1,("check_bind_req unknown transfer syntax for " + "%s context_id=%u\n", + ndr_interface_name(&abstract->uuid, + abstract->if_version), + (unsigned)context_id)); + return false; + } /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */ - if (rpc_srv_pipe_exists_by_id(abstract) && - ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr)) { - DEBUG(3, ("check_bind_req: %s -> %s rpc service\n", - rpc_srv_get_pipe_cli_name(abstract), - rpc_srv_get_pipe_srv_name(abstract))); - } else { + if (!rpc_srv_pipe_exists_by_id(abstract)) { return false; } + DEBUG(3, ("check_bind_req: %s -> %s rpc service\n", + rpc_srv_get_pipe_cli_name(abstract), + rpc_srv_get_pipe_srv_name(abstract))); + ok = init_pipe_handles(p, abstract); if (!ok) { DEBUG(1, ("Failed to init pipe handles!\n")); -- 1.9.1 From 8b209ce6a6070fa8535515f51b4bff10ca684e8b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 13:05:01 +0200 Subject: [PATCH 308/323] CVE-2015-5370: s3:rpc_server: don't allow an existing context to be changed in check_bind_req() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An alter context can't change the syntax of an existing context, a new context_id will be used for that. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 27fd83c..bb3c3e8 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -365,6 +365,30 @@ static bool check_bind_req(struct pipes_struct *p, return false; } + for (context_fns = p->contexts; + context_fns != NULL; + context_fns = context_fns->next) + { + if (context_fns->context_id != context_id) { + continue; + } + + ok = ndr_syntax_id_equal(&context_fns->syntax, + abstract); + if (ok) { + return true; + } + + DEBUG(1,("check_bind_req: changing abstract syntax for " + "%s context_id=%u into %s not supported\n", + ndr_interface_name(&context_fns->syntax.uuid, + context_fns->syntax.if_version), + (unsigned)context_id, + ndr_interface_name(&abstract->uuid, + abstract->if_version))); + return false; + } + /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */ if (!rpc_srv_pipe_exists_by_id(abstract)) { return false; -- 1.9.1 From f8ab892469269855cf604e6720a7ac006365b951 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 309/323] CVE-2015-5370: s3:rpc_client: pass struct pipe_auth_data to create_rpc_{bind_auth3,alter_context}() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1d1ccad..6402637 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1695,9 +1695,8 @@ static bool check_bind_response(const struct dcerpc_bind_ack *r, static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, + struct pipe_auth_data *auth, uint32_t rpc_call_id, - enum dcerpc_AuthType auth_type, - enum dcerpc_AuthLevel auth_level, DATA_BLOB *pauth_blob, DATA_BLOB *rpc_out) { @@ -1707,8 +1706,8 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, u.auth3._pad = 0; status = dcerpc_push_dcerpc_auth(mem_ctx, - auth_type, - auth_level, + auth->auth_type, + auth->auth_level, 0, /* auth_pad_length */ 1, /* auth_context_id */ pauth_blob, @@ -1740,8 +1739,7 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, ********************************************************************/ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, - enum dcerpc_AuthType auth_type, - enum dcerpc_AuthLevel auth_level, + struct pipe_auth_data *auth, uint32_t rpc_call_id, const struct ndr_syntax_id *abstract, const struct ndr_syntax_id *transfer, @@ -1752,8 +1750,8 @@ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, NTSTATUS status; status = dcerpc_push_dcerpc_auth(mem_ctx, - auth_type, - auth_level, + auth->auth_type, + auth->auth_level, 0, /* auth_pad_length */ 1, /* auth_context_id */ pauth_blob, @@ -1983,9 +1981,7 @@ static NTSTATUS rpc_bind_next_send(struct tevent_req *req, /* Now prepare the alter context pdu. */ data_blob_free(&state->rpc_out); - status = create_rpc_alter_context(state, - auth->auth_type, - auth->auth_level, + status = create_rpc_alter_context(state, auth, state->rpc_call_id, &state->cli->abstract_syntax, &state->cli->transfer_syntax, @@ -2018,10 +2014,8 @@ static NTSTATUS rpc_bind_finish_send(struct tevent_req *req, /* Now prepare the auth3 context pdu. */ data_blob_free(&state->rpc_out); - status = create_rpc_bind_auth3(state, state->cli, + status = create_rpc_bind_auth3(state, state->cli, auth, state->rpc_call_id, - auth->auth_type, - auth->auth_level, auth_token, &state->rpc_out); if (!NT_STATUS_IS_OK(status)) { -- 1.9.1 From a9b0ae6c363e2277d8c04ca6475cd3a11989d2bf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 310/323] CVE-2015-5370: s3:librpc/rpc: add auth_context_id to struct pipe_auth_data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/librpc/rpc/dcerpc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h index b7537c2..1838012 100644 --- a/source3/librpc/rpc/dcerpc.h +++ b/source3/librpc/rpc/dcerpc.h @@ -40,6 +40,7 @@ struct gensec_security; struct pipe_auth_data { enum dcerpc_AuthType auth_type; enum dcerpc_AuthLevel auth_level; + uint32_t auth_context_id; bool client_hdr_signing; bool hdr_signing; bool verified_bitmask1; -- 1.9.1 From 3289d0f5a4cd60d3793f0a0026648488968a5a4e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 311/323] CVE-2015-5370: s3:rpc_client: make use of pipe_auth_data->auth_context_id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is better than using hardcoded values. We need to use auth_context_id = 1 for authenticated connections, as old Samba server (before this patchset) will use a hardcoded value of 1. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 6402637..3015cbb 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1190,7 +1190,7 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, auth->auth_type, auth->auth_level, 0, /* auth_pad_length */ - 1, /* auth_context_id */ + auth->auth_context_id, &auth_token, &auth_info); if (!NT_STATUS_IS_OK(ret)) { @@ -1709,7 +1709,7 @@ static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, auth->auth_type, auth->auth_level, 0, /* auth_pad_length */ - 1, /* auth_context_id */ + auth->auth_context_id, pauth_blob, &u.auth3.auth_info); if (!NT_STATUS_IS_OK(status)) { @@ -1753,7 +1753,7 @@ static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, auth->auth_type, auth->auth_level, 0, /* auth_pad_length */ - 1, /* auth_context_id */ + auth->auth_context_id, pauth_blob, &auth_info); if (!NT_STATUS_IS_OK(status)) { @@ -2369,6 +2369,7 @@ NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx, result->auth_type = DCERPC_AUTH_TYPE_NONE; result->auth_level = DCERPC_AUTH_LEVEL_NONE; + result->auth_context_id = 0; status = auth_generic_client_prepare(result, &auth_generic_ctx); @@ -2429,6 +2430,7 @@ static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx, result->auth_type = auth_type; result->auth_level = auth_level; + result->auth_context_id = 1; status = auth_generic_client_prepare(result, &auth_generic_ctx); @@ -2499,6 +2501,7 @@ static NTSTATUS rpccli_generic_bind_data_from_creds(TALLOC_CTX *mem_ctx, result->auth_type = auth_type; result->auth_level = auth_level; + result->auth_context_id = 1; status = auth_generic_client_prepare(result, &auth_generic_ctx); -- 1.9.1 From 4ab3cbca1bea9fabc326a5cd1f58d4bcea5053ce Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 312/323] CVE-2015-5370: s3:rpc_server: make use of pipe_auth_data->auth_context_id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is better than using hardcoded values. We need to use the value the client used in the BIND request. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/rpc_ncacn_np.c | 1 + source3/rpc_server/srv_pipe.c | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c index 5514956..5647596 100644 --- a/source3/rpc_server/rpc_ncacn_np.c +++ b/source3/rpc_server/rpc_ncacn_np.c @@ -977,6 +977,7 @@ static NTSTATUS rpc_pipe_open_external(TALLOC_CTX *mem_ctx, } result->auth->auth_type = DCERPC_AUTH_TYPE_NONE; result->auth->auth_level = DCERPC_AUTH_LEVEL_NONE; + result->auth->auth_context_id = 0; status = rpccli_anon_bind_data(result, &auth); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index bb3c3e8..821623c 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -539,6 +539,7 @@ static bool pipe_auth_generic_bind(struct pipes_struct *p, p->auth.auth_ctx = gensec_security; p->auth.auth_type = auth_info->auth_type; p->auth.auth_level = auth_info->auth_level; + p->auth.auth_context_id = auth_info->auth_context_id; if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) { p->auth.client_hdr_signing = true; @@ -812,6 +813,7 @@ static bool api_pipe_bind_req(struct pipes_struct *p, } else { p->auth.auth_type = DCERPC_AUTH_TYPE_NONE; p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE; + p->auth.auth_context_id = 0; } ZERO_STRUCT(u.bind_ack); @@ -862,12 +864,11 @@ static bool api_pipe_bind_req(struct pipes_struct *p, } if (auth_resp.length) { - status = dcerpc_push_dcerpc_auth(pkt, p->auth.auth_type, p->auth.auth_level, - 0, - 1, /* auth_context_id */ + 0, /* pad_len */ + p->auth.auth_context_id, &auth_resp, &auth_blob); if (!NT_STATUS_IS_OK(status)) { @@ -1222,10 +1223,10 @@ static bool api_pipe_alter_context(struct pipes_struct *p, if (auth_resp.length) { status = dcerpc_push_dcerpc_auth(pkt, - auth_info.auth_type, - auth_info.auth_level, + p->auth.auth_type, + p->auth.auth_level, 0, /* pad_len */ - 1, /* auth_context_id */ + p->auth.auth_context_id, &auth_resp, &auth_blob); if (!NT_STATUS_IS_OK(status)) { -- 1.9.1 From f2374493c2fd2192d30d1f07a1e05302407bd593 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 313/323] CVE-2015-5370: s3:librpc/rpc: make use of auth->auth_context_id in dcerpc_add_auth_footer() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/librpc/rpc/dcerpc_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index 48410bb..c030f79 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -403,7 +403,7 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, auth->auth_type, auth->auth_level, pad_len, - 1 /* context id. */, + auth->auth_context_id, &auth_blob, &auth_info); if (!NT_STATUS_IS_OK(status)) { -- 1.9.1 From ac152470039c215937b394e5ae50d9ed85236594 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 314/323] CVE-2015-5370: s3:librpc/rpc: verify auth_context_id in dcerpc_check_auth() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/librpc/rpc/dcerpc_helpers.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index c030f79..aab43a1 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -515,6 +515,10 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, return NT_STATUS_INVALID_PARAMETER; } + if (auth_info.auth_context_id != auth->auth_context_id) { + return NT_STATUS_INVALID_PARAMETER; + } + pkt_trailer->length -= auth_length; data = data_blob_const(raw_pkt->data + header_size, pkt_trailer->length); -- 1.9.1 From fa81de74af67eb510915961996678cb75eaf894c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Jul 2015 22:51:18 +0200 Subject: [PATCH 315/323] CVE-2015-5370: s3:rpc_client: verify auth_context_id in rpc_pipe_bind_step_one_done() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 3015cbb..00ff530 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1921,6 +1921,14 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) return; } + if (auth.auth_context_id != pauth->auth_context_id) { + DEBUG(0, (__location__ " Auth context id %u mismatch expected %u.\n", + (unsigned)auth.auth_context_id, + (unsigned)pauth->auth_context_id)); + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); + return; + } + break; } -- 1.9.1 From 3251638bc5eb3148e09753f9da25f1457b0917f6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Jul 2015 00:01:37 +0200 Subject: [PATCH 316/323] CVE-2015-5370: s3:rpc_server: verify auth_context_id in api_pipe_{bind_auth3,alter_context} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_server/srv_pipe.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 821623c..bcd7e5d 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1004,6 +1004,14 @@ bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt) goto err; } + if (auth_info.auth_context_id != p->auth.auth_context_id) { + DEBUG(0, ("Auth context id mismatch! Client sent %u, " + "but auth was started as level %u!\n", + (unsigned)auth_info.auth_context_id, + (unsigned)p->auth.auth_context_id)); + goto err; + } + gensec_security = p->auth.auth_ctx; status = auth_generic_server_step(gensec_security, @@ -1160,6 +1168,14 @@ static bool api_pipe_alter_context(struct pipes_struct *p, goto err_exit; } + if (auth_info.auth_context_id != p->auth.auth_context_id) { + DEBUG(0, ("Auth context id mismatch! Client sent %u, " + "but auth was started as level %u!\n", + (unsigned)auth_info.auth_context_id, + (unsigned)p->auth.auth_context_id)); + goto err_exit; + } + gensec_security = p->auth.auth_ctx; status = auth_generic_server_step(gensec_security, pkt, -- 1.9.1 From 8e838f5271df1e8b9c4aae11e73f14c0a9ce2ffd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Dec 2015 11:05:45 +0100 Subject: [PATCH 317/323] CVE-2015-5370: libcli/smb: use a max timeout of 1 second in tstream_smbXcli_np_destructor() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- libcli/smb/tstream_smbXcli_np.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libcli/smb/tstream_smbXcli_np.c b/libcli/smb/tstream_smbXcli_np.c index af0863e..a59db13 100644 --- a/libcli/smb/tstream_smbXcli_np.c +++ b/libcli/smb/tstream_smbXcli_np.c @@ -111,7 +111,11 @@ static int tstream_smbXcli_np_destructor(struct tstream_smbXcli_np *cli_nps) * Once we've fixed all callers to call * tstream_disconnect_send()/_recv(), this will * never be called. + * + * We use a maximun timeout of 1 second == 1000 msec. */ + cli_nps->timeout = MIN(cli_nps->timeout, 1000); + if (cli_nps->is_smb1) { status = smb1cli_close(cli_nps->conn, cli_nps->timeout, -- 1.9.1 From 242cafe104e2e1422a268df5f2724e43b5ae14d4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Dec 2015 21:23:14 +0100 Subject: [PATCH 318/323] CVE-2015-5370: s3:rpc_client: disconnect connection on protocol errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/rpc_client/cli_pipe.c | 67 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 00ff530..97f4944 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -936,6 +936,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) state->pkt = talloc(state, struct ncacn_packet); if (!state->pkt) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -945,6 +951,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) state->pkt, !state->endianess); if (!NT_STATUS_IS_OK(status)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); tevent_req_nterror(req, status); return; } @@ -962,6 +974,28 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) (unsigned)state->reply_pdu_offset, nt_errstr(status))); + if (state->pkt->ptype != DCERPC_PKT_FAULT && !NT_STATUS_IS_OK(status)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); return; @@ -986,12 +1020,24 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) "%s\n", state->endianess?"little":"big", state->pkt->drep[0]?"little":"big")); - tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); return; } if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) { - tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); return; } @@ -999,6 +1045,12 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) { if (!data_blob_realloc(NULL, &state->reply_pdu, state->reply_pdu_offset + rdata.length)) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -1027,6 +1079,14 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) subreq = get_complete_frag_send(state, state->ev, state->cli, &state->incoming_frag); + if (subreq == NULL) { + /* + * TODO: do a real async disconnect ... + * + * For now do it sync... + */ + TALLOC_FREE(state->cli->transport); + } if (tevent_req_nomem(subreq, req)) { return; } @@ -2275,8 +2335,9 @@ static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx, /* * TODO: do a real async disconnect ... * - * For now the caller needs to free rpc_cli + * For now we do it sync... */ + TALLOC_FREE(hs->rpc_cli->transport); hs->rpc_cli = NULL; tevent_req_done(req); -- 1.9.1 From 0641152888209674f381b12007f81bf9f6cb0b4c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Dec 2015 21:13:41 +0100 Subject: [PATCH 319/323] CVE-2015-5370: s4:librpc/rpc: call dcerpc_connection_dead() on protocol errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/librpc/rpc/dcerpc.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 60d5b8d..464ae95 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1546,7 +1546,16 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c, } if (pkt->ptype == DCERPC_PKT_FAULT) { + status = dcerpc_fault_to_nt_status(pkt->u.fault.status); DEBUG(5,("rpc fault: %s\n", dcerpc_errstr(c, pkt->u.fault.status))); + if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) { + dcerpc_connection_dead(c, status); + return; + } + if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) { + dcerpc_connection_dead(c, status); + return; + } req->fault_code = pkt->u.fault.status; req->status = NT_STATUS_NET_WRITE_FAULT; goto req_done; @@ -1555,16 +1564,15 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c, if (pkt->ptype != DCERPC_PKT_RESPONSE) { DEBUG(2,("Unexpected packet type %d in dcerpc response\n", (int)pkt->ptype)); - req->fault_code = DCERPC_FAULT_OTHER; - req->status = NT_STATUS_NET_WRITE_FAULT; - goto req_done; + dcerpc_connection_dead(c, NT_STATUS_RPC_PROTOCOL_ERROR); + return; } /* now check the status from the auth routines, and if it failed then fail this request accordingly */ if (!NT_STATUS_IS_OK(status)) { - req->status = status; - goto req_done; + dcerpc_connection_dead(c, status); + return; } length = pkt->u.response.stub_and_verifier.length; @@ -1573,9 +1581,8 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c, DEBUG(2,("Unexpected total payload 0x%X > 0x%X dcerpc response\n", (unsigned)req->payload.length + length, DCERPC_NCACN_PAYLOAD_MAX_SIZE)); - req->fault_code = DCERPC_FAULT_OTHER; - req->status = NT_STATUS_NET_WRITE_FAULT; - goto req_done; + dcerpc_connection_dead(c, NT_STATUS_RPC_PROTOCOL_ERROR); + return; } if (length > 0) { -- 1.9.1 From fa68ae071ff650b200700da0bd6bb9aefe8254c4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 26 Mar 2014 22:42:19 +0100 Subject: [PATCH 320/323] CVE-2015-5370: python/samba/tests: add infrastructure to do raw protocol tests for DCERPC These are independent from our client library and allow testing of invalid pdus. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher --- python/samba/tests/__init__.py | 525 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 525 insertions(+) diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 87b6943..1c5f678 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -1,5 +1,6 @@ # Unix SMB/CIFS implementation. # Copyright (C) Jelmer Vernooij 2007-2010 +# Copyright (C) Stefan Metzmacher 2014,2015 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -24,6 +25,12 @@ import samba.auth from samba import param from samba.samdb import SamDB from samba import credentials +import samba.ndr +import samba.dcerpc.dcerpc +import samba.dcerpc.base +import samba.dcerpc.epmapper +import socket +import struct import subprocess import sys import tempfile @@ -222,6 +229,524 @@ cmdline_credentials = None class RpcInterfaceTestCase(TestCase): """DCE/RPC Test case.""" +class RawDCERPCTest(TestCase): + """A raw DCE/RPC Test case.""" + + def _disconnect(self, reason): + if self.s is None: + return + self.s.close() + self.s = None + if self.do_hexdump: + sys.stderr.write("disconnect[%s]\n" % reason) + + def connect(self): + try: + self.a = socket.getaddrinfo(self.host, self.tcp_port, socket.AF_UNSPEC, + socket.SOCK_STREAM, socket.SOL_TCP, + 0) + self.s = socket.socket(self.a[0][0], self.a[0][1], self.a[0][2]) + self.s.settimeout(10) + self.s.connect(self.a[0][4]) + except socket.error as e: + self.s.close() + raise + except IOError as e: + self.s.close() + raise + except Exception as e: + raise + finally: + pass + + def setUp(self): + super(RawDCERPCTest, self).setUp() + self.do_ndr_print = False + self.do_hexdump = False + + self.host = samba.tests.env_get_var_value('SERVER') + self.tcp_port = 135 + + self.settings = {} + self.settings["lp_ctx"] = self.lp_ctx = samba.tests.env_loadparm() + self.settings["target_hostname"] = self.host + + self.connect() + + def epmap_reconnect(self, abstract): + ndr32 = samba.dcerpc.base.transfer_syntax_ndr() + + tsf0_list = [ndr32] + ctx0 = samba.dcerpc.dcerpc.ctx_list() + ctx0.context_id = 1 + ctx0.num_transfer_syntaxes = len(tsf0_list) + ctx0.abstract_syntax = samba.dcerpc.epmapper.abstract_syntax() + ctx0.transfer_syntaxes = tsf0_list + + req = self.generate_bind(call_id=0, ctx_list=[ctx0]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_BIND_ACK, + req.call_id, auth_length=0) + self.assertEqual(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEqual(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEqual(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEqual(rep.u.secondary_address_size, 4) + self.assertEqual(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEqual(len(rep.u._pad1), 2) + self.assertEqual(rep.u._pad1, '\0' * 2) + self.assertEqual(rep.u.num_results, 1) + self.assertEqual(rep.u.ctx_list[0].result, + samba.dcerpc.dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEqual(rep.u.ctx_list[0].reason, + samba.dcerpc.dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEqual(rep.u.auth_info, '\0' * 0) + + # And now try a request + data1 = samba.ndr.ndr_pack(abstract) + lhs1 = samba.dcerpc.epmapper.epm_lhs() + lhs1.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_UUID + lhs1.lhs_data = data1[:18] + rhs1 = samba.dcerpc.epmapper.epm_rhs_uuid() + rhs1.unknown = data1[18:] + floor1 = samba.dcerpc.epmapper.epm_floor() + floor1.lhs = lhs1 + floor1.rhs = rhs1 + data2 = samba.ndr.ndr_pack(ndr32) + lhs2 = samba.dcerpc.epmapper.epm_lhs() + lhs2.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_UUID + lhs2.lhs_data = data2[:18] + rhs2 = samba.dcerpc.epmapper.epm_rhs_uuid() + rhs2.unknown = data1[18:] + floor2 = samba.dcerpc.epmapper.epm_floor() + floor2.lhs = lhs2 + floor2.rhs = rhs2 + lhs3 = samba.dcerpc.epmapper.epm_lhs() + lhs3.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_NCACN + lhs3.lhs_data = "" + floor3 = samba.dcerpc.epmapper.epm_floor() + floor3.lhs = lhs3 + floor3.rhs.minor_version = 0 + lhs4 = samba.dcerpc.epmapper.epm_lhs() + lhs4.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_TCP + lhs4.lhs_data = "" + floor4 = samba.dcerpc.epmapper.epm_floor() + floor4.lhs = lhs4 + floor4.rhs.port = self.tcp_port + lhs5 = samba.dcerpc.epmapper.epm_lhs() + lhs5.protocol = samba.dcerpc.epmapper.EPM_PROTOCOL_IP + lhs5.lhs_data = "" + floor5 = samba.dcerpc.epmapper.epm_floor() + floor5.lhs = lhs5 + floor5.rhs.ipaddr = "0.0.0.0" + + floors = [floor1,floor2,floor3,floor4,floor5] + req_tower = samba.dcerpc.epmapper.epm_tower() + req_tower.num_floors = len(floors) + req_tower.floors = floors + req_twr = samba.dcerpc.epmapper.epm_twr_t() + req_twr.tower = req_tower + + pack_twr = samba.ndr.ndr_pack(req_twr) + + # object + stub = "\x01\x00\x00\x00" + stub += "\x00" * 16 + # tower + stub += "\x02\x00\x00\x00" + stub += pack_twr + # padding? + stub += "\x00" * 1 + # handle + stub += "\x00" * 20 + # max_towers + stub += "\x04\x00\x00\x00" + + # we do an epm_Map() request + req = self.generate_request(call_id = 1, + context_id=ctx0.context_id, + opnum=3, + stub=stub) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, samba.dcerpc.dcerpc.DCERPC_PKT_RESPONSE, + req.call_id, auth_length=0) + self.assertNotEqual(rep.u.alloc_hint, 0) + self.assertEqual(rep.u.context_id, req.u.context_id) + self.assertEqual(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + num_towers = struct.unpack_from(" samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH: + p.auth_length = len(ai) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH + else: + p.auth_length = 0 + p.call_id = call_id + p.u = payload + + pdu = samba.ndr.ndr_pack(p) + p.frag_length = len(pdu) + + return p + + def verify_pdu(self, p, ptype, call_id, + rpc_vers=5, + rpc_vers_minor=0, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + drep = [samba.dcerpc.dcerpc.DCERPC_DREP_LE, 0, 0, 0], + auth_length=None): + + self.assertIsNotNone(p, "No valid pdu") + + if getattr(p.u, 'auth_info', None): + ai = p.u.auth_info + else: + ai = "" + + self.assertEqual(p.rpc_vers, rpc_vers) + self.assertEqual(p.rpc_vers_minor, rpc_vers_minor) + self.assertEqual(p.ptype, ptype) + self.assertEqual(p.pfc_flags, pfc_flags) + self.assertEqual(p.drep, drep) + self.assertGreaterEqual(p.frag_length, + samba.dcerpc.dcerpc.DCERPC_NCACN_PAYLOAD_OFFSET) + if len(ai) > samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH: + self.assertEqual(p.auth_length, + len(ai) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH) + elif auth_length is not None: + self.assertEqual(p.auth_length, auth_length) + else: + self.assertEqual(p.auth_length, 0) + self.assertEqual(p.call_id, call_id) + + return + + def generate_bind(self, call_id, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + max_xmit_frag=5840, + max_recv_frag=5840, + assoc_group_id=0, + ctx_list=[], + auth_info="", + ndr_print=None, hexdump=None): + + b = samba.dcerpc.dcerpc.bind() + b.max_xmit_frag = max_xmit_frag + b.max_recv_frag = max_recv_frag + b.assoc_group_id = assoc_group_id + b.num_contexts = len(ctx_list) + b.ctx_list = ctx_list + b.auth_info = auth_info + + p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_BIND, + pfc_flags=pfc_flags, + call_id=call_id, + payload=b, + ndr_print=ndr_print, hexdump=hexdump) + + return p + + def generate_alter(self, call_id, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + max_xmit_frag=5840, + max_recv_frag=5840, + assoc_group_id=0, + ctx_list=[], + auth_info="", + ndr_print=None, hexdump=None): + + a = samba.dcerpc.dcerpc.bind() + a.max_xmit_frag = max_xmit_frag + a.max_recv_frag = max_recv_frag + a.assoc_group_id = assoc_group_id + a.num_contexts = len(ctx_list) + a.ctx_list = ctx_list + a.auth_info = auth_info + + p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_ALTER, + pfc_flags=pfc_flags, + call_id=call_id, + payload=a, + ndr_print=ndr_print, hexdump=hexdump) + + return p + + def generate_auth3(self, call_id, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + auth_info="", + ndr_print=None, hexdump=None): + + a = samba.dcerpc.dcerpc.auth3() + a.auth_info = auth_info + + p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_AUTH3, + pfc_flags=pfc_flags, + call_id=call_id, + payload=a, + ndr_print=ndr_print, hexdump=hexdump) + + return p + + def generate_request(self, call_id, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + alloc_hint=None, + context_id=None, + opnum=None, + object=None, + stub=None, + auth_info="", + ndr_print=None, hexdump=None): + + if alloc_hint is None: + alloc_hint = len(stub) + + r = samba.dcerpc.dcerpc.request() + r.alloc_hint = alloc_hint + r.context_id = context_id + r.opnum = opnum + if object is not None: + r.object = object + r.stub_and_verifier = stub + auth_info + + p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_REQUEST, + pfc_flags=pfc_flags, + call_id=call_id, + payload=r, + ndr_print=ndr_print, hexdump=hexdump) + + if len(auth_info) > samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH: + p.auth_length = len(auth_info) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH + + return p + + def generate_co_cancel(self, call_id, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + auth_info="", + ndr_print=None, hexdump=None): + + c = samba.dcerpc.dcerpc.co_cancel() + c.auth_info = auth_info + + p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_CO_CANCEL, + pfc_flags=pfc_flags, + call_id=call_id, + payload=c, + ndr_print=ndr_print, hexdump=hexdump) + + return p + + def generate_orphaned(self, call_id, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + auth_info="", + ndr_print=None, hexdump=None): + + o = samba.dcerpc.dcerpc.orphaned() + o.auth_info = auth_info + + p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_ORPHANED, + pfc_flags=pfc_flags, + call_id=call_id, + payload=o, + ndr_print=ndr_print, hexdump=hexdump) + + return p + + def generate_shutdown(self, call_id, + pfc_flags = samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_FIRST | + samba.dcerpc.dcerpc.DCERPC_PFC_FLAG_LAST, + ndr_print=None, hexdump=None): + + s = samba.dcerpc.dcerpc.shutdown() + + p = self.generate_pdu(ptype=samba.dcerpc.dcerpc.DCERPC_PKT_SHUTDOWN, + pfc_flags=pfc_flags, + call_id=call_id, + payload=s, + ndr_print=ndr_print, hexdump=hexdump) + + return p + + def assertIsConnected(self): + self.assertIsNotNone(self.s, msg="Not connected") + return + + def assertNotConnected(self): + self.assertIsNone(self.s, msg="Is connected") + return + + def assertNDRSyntaxEquals(self, s1, s2): + self.assertEqual(s1.uuid, s2.uuid) + self.assertEqual(s1.if_version, s2.if_version) + return class ValidNetbiosNameTests(TestCase): -- 1.9.1 From 08200fcc0bc6a52c4b66b96dd0848036b9ae568e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 26 Mar 2014 22:42:19 +0100 Subject: [PATCH 321/323] CVE-2015-5370: python/samba/tests: add some dcerpc raw_protocol tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are independent from our client library and allow testing of invalid pdus. It can be used like this in standalone mode: SMB_CONF_PATH=/dev/null SERVER=172.31.9.188 python/samba/tests/dcerpc/raw_protocol.py or SMB_CONF_PATH=/dev/null SERVER=172.31.9.188 python/samba/tests/dcerpc/raw_protocol.py -v -f TestDCERPC_BIND.test_invalid_auth_noctx BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- python/samba/tests/dcerpc/raw_protocol.py | 2623 +++++++++++++++++++++++++++++ 1 file changed, 2623 insertions(+) create mode 100755 python/samba/tests/dcerpc/raw_protocol.py diff --git a/python/samba/tests/dcerpc/raw_protocol.py b/python/samba/tests/dcerpc/raw_protocol.py new file mode 100755 index 0000000..ccd0f6b --- /dev/null +++ b/python/samba/tests/dcerpc/raw_protocol.py @@ -0,0 +1,2623 @@ +#!/usr/bin/env python +# Unix SMB/CIFS implementation. +# Copyright (C) Stefan Metzmacher 2014,2015 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import sys +import os + +sys.path.insert(0, "bin/python") +os.environ["PYTHONUNBUFFERED"] = "1" + +import samba.dcerpc.dcerpc as dcerpc +import samba.dcerpc.base as base +import samba.dcerpc.epmapper +import samba.dcerpc.mgmt +import samba.dcerpc.netlogon +import struct +from samba.credentials import Credentials +from samba import gensec +from samba.tests import RawDCERPCTest + +global_ndr_print = False +global_hexdump = False + +class TestDCERPC_BIND(RawDCERPCTest): + + def setUp(self): + super(TestDCERPC_BIND, self).setUp() + self.do_ndr_print = global_ndr_print + self.do_hexdump = global_hexdump + + def _test_no_auth_request_bind_pfc_flags(self, req_pfc_flags, rep_pfc_flags): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, pfc_flags=req_pfc_flags, ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + pfc_flags=rep_pfc_flags, auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEquals(len(rep.u._pad1), 2) + # sometimes windows sends random bytes + # self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + # And now try a request + req = self.generate_request(call_id = 1, + context_id=ctx1.context_id, + opnum=0, + stub="") + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + def _test_no_auth_request_alter_pfc_flags(self, req_pfc_flags, rep_pfc_flags): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEquals(len(rep.u._pad1), 2) + # sometimes windows sends random bytes + # self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + # And now try a alter context + req = self.generate_alter(call_id=0, pfc_flags=req_pfc_flags, ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, + pfc_flags=rep_pfc_flags, auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 0) + self.assertEquals(rep.u.secondary_address, "") + self.assertEquals(len(rep.u._pad1), 2) + # sometimes windows sends random bytes + # self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + # And now try a request + req = self.generate_request(call_id = 1, + context_id=ctx1.context_id, + opnum=0, + stub="") + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + def test_no_auth_request(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_bind_pfc_00(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_bind_pfc_FIRST(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_bind_pfc_LAST(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_LAST | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN + # without authentication + def _test_no_auth_request_bind_pfc_HDR_SIGNING(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) + + def test_no_auth_request_bind_pfc_08(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + 8 | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + # TODO: doesn't announce DCERPC_PFC_FLAG_CONC_MPX + # by default + def _test_no_auth_request_bind_pfc_CONC_MPX(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_CONC_MPX | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST | + dcerpc.DCERPC_PFC_FLAG_CONC_MPX) + + def test_no_auth_request_bind_pfc_DID_NOT_EXECUTE(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_bind_pfc_MAYBE(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_MAYBE | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_bind_pfc_OBJECT_UUID(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_OBJECT_UUID | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN + # without authentication + # TODO: doesn't announce DCERPC_PFC_FLAG_CONC_MPX + # by default + def _test_no_auth_request_bind_pfc_ff(self): + return self._test_no_auth_request_bind_pfc_flags( + req_pfc_flags=0 | + 0xff | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + dcerpc.DCERPC_PFC_FLAG_CONC_MPX) + + def test_no_auth_request_alter_pfc_00(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_alter_pfc_FIRST(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_alter_pfc_LAST(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_LAST | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN + # without authentication + def _test_no_auth_request_alter_pfc_HDR_SIGNING(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) + + def test_no_auth_request_alter_pfc_08(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + 8 | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_alter_pfc_CONC_MPX(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_CONC_MPX | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_alter_pfc_DID_NOT_EXECUTE(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_alter_pfc_MAYBE(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_MAYBE | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + def test_no_auth_request_alter_pfc_OBJECT_UUID(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_OBJECT_UUID | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST) + + # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN + # without authentication + def _test_no_auth_request_alter_pfc_ff(self): + return self._test_no_auth_request_alter_pfc_flags( + req_pfc_flags=0 | + 0xff | + 0, + rep_pfc_flags=0 | + dcerpc.DCERPC_PFC_FLAG_FIRST | + dcerpc.DCERPC_PFC_FLAG_LAST | + dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) + + def test_no_auth_no_ctx(self): + # send an useless bind + req = self.generate_bind(call_id=0) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.reject_reason, + dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + self.assertEquals(rep.u.num_versions, 1) + self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) + self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) + self.assertEquals(len(rep.u._pad), 3) + self.assertEquals(rep.u._pad, '\0' * 3) + + def test_invalid_auth_noctx(self): + req = self.generate_bind(call_id=0) + req.auth_length = dcerpc.DCERPC_AUTH_TRAILER_LENGTH + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.reject_reason, + dcerpc.DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED) + self.assertEquals(rep.u.num_versions, 1) + self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) + self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) + self.assertEquals(len(rep.u._pad), 3) + self.assertEquals(rep.u._pad, '\0' * 3) + + def test_no_auth_valid_valid_request(self): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEquals(len(rep.u._pad1), 2) + self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + # Send a bind again + tsf2_list = [ndr32] + ctx2 = dcerpc.ctx_list() + ctx2.context_id = 2 + ctx2.num_transfer_syntaxes = len(tsf2_list) + ctx2.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx2.transfer_syntaxes = tsf2_list + + req = self.generate_bind(call_id=1, ctx_list=[ctx2]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.reject_reason, + dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + self.assertEquals(rep.u.num_versions, 1) + self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) + self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) + self.assertEquals(len(rep.u._pad), 3) + self.assertEquals(rep.u._pad, '\0' * 3) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + + def test_no_auth_invalid_valid_request(self): + # send an useless bind + req = self.generate_bind(call_id=0) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.reject_reason, + dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + self.assertEquals(rep.u.num_versions, 1) + self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) + self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) + self.assertEquals(len(rep.u._pad), 3) + self.assertEquals(rep.u._pad, '\0' * 3) + + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + + def test_alter_no_auth_no_ctx(self): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEquals(len(rep.u._pad1), 2) + self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + # Send a alter + req = self.generate_alter(call_id=1, ctx_list=[]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, + pfc_flags=req.pfc_flags | + dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, 0) + self.assertEquals(rep.u.cancel_count, 0) + self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) + self.assertEquals(len(rep.u._pad), 4) + self.assertEquals(rep.u._pad, '\0' * 4) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + + def _test_auth_none_level_bind(self, auth_level, + reason=dcerpc.DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + ctx_list = [ctx1] + + auth_type = dcerpc.DCERPC_AUTH_TYPE_NONE + auth_context_id = 0 + + auth_info = self.generate_auth(auth_type=auth_type, + auth_level=auth_level, + auth_context_id=auth_context_id, + auth_blob="none") + + req = self.generate_bind(call_id=0, + ctx_list=ctx_list, + auth_info=auth_info) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.reject_reason, reason) + self.assertEquals(rep.u.num_versions, 1) + self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers) + self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor) + self.assertEquals(len(rep.u._pad), 3) + self.assertEquals(rep.u._pad, '\0' * 3) + + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + + def test_auth_none_none_bind(self): + return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_NONE, + reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + + def test_auth_none_connect_bind(self): + return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_CONNECT) + + def test_auth_none_call_bind(self): + return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_CALL) + + def test_auth_none_packet_bind(self): + return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_PACKET) + + def test_auth_none_integrity_bind(self): + return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY) + + def test_auth_none_privacy_bind(self): + return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_PRIVACY) + + def test_auth_none_0_bind(self): + return self._test_auth_none_level_bind(0, + reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + + def test_auth_none_7_bind(self): + return self._test_auth_none_level_bind(7, + reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + + def test_auth_none_255_bind(self): + return self._test_auth_none_level_bind(255, + reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED) + + def _test_auth_none_level_request(self, auth_level): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + ctx_list = [ctx1] + + auth_type = dcerpc.DCERPC_AUTH_TYPE_NONE + auth_context_id = 0 + + req = self.generate_bind(call_id=0, + ctx_list=ctx_list) + + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEquals(len(rep.u._pad1), 2) + self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(len(rep.u.auth_info), 0) + + # And now try a request without auth_info + req = self.generate_request(call_id = 2, + context_id=ctx1.context_id, + opnum=0, + stub="") + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + auth_info = self.generate_auth(auth_type=auth_type, + auth_level=auth_level, + auth_context_id=auth_context_id, + auth_blob="none") + + req = self.generate_request(call_id = 3, + context_id=ctx1.context_id, + opnum=0, + stub="", + auth_info=auth_info) + self.send_pdu(req) + rep = self.recv_pdu() + # We get a fault back + self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED) + self.assertEquals(len(rep.u._pad), 4) + self.assertEquals(rep.u._pad, '\0' * 4) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + + def test_auth_none_none_request(self): + return self._test_auth_none_level_request(dcerpc.DCERPC_AUTH_LEVEL_NONE) + + def test_auth_none_connect_request(self): + return self._test_auth_none_level_request(dcerpc.DCERPC_AUTH_LEVEL_CONNECT) + + def test_auth_none_call_request(self): + return self._test_auth_none_level_request(dcerpc.DCERPC_AUTH_LEVEL_CALL) + + def _test_neg_xmit_check_values(self, + req_xmit=None, + req_recv=None, + rep_both=None, + alter_xmit=None, + alter_recv=None): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx1 = dcerpc.ctx_list() + ctx1.context_id = 1 + ctx1.num_transfer_syntaxes = len(tsf1_list) + ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx1.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, + max_xmit_frag=req_xmit, + max_recv_frag=req_recv, + ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, rep_both) + self.assertEquals(rep.u.max_recv_frag, rep_both) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEquals(len(rep.u._pad1), 2) + self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + assoc_group_id = rep.u.assoc_group_id + if alter_xmit is None: + alter_xmit = rep_both - 8 + if alter_recv is None: + alter_recv = rep_both - 8 + + # max_{xmit,recv}_frag and assoc_group_id are completely + # ignored in alter_context requests + req = self.generate_alter(call_id=1, + max_xmit_frag=alter_xmit, + max_recv_frag=alter_recv, + assoc_group_id=0xffffffff-rep.u.assoc_group_id, + ctx_list=[ctx1]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, rep_both) + self.assertEquals(rep.u.max_recv_frag, rep_both) + self.assertEquals(rep.u.assoc_group_id, rep.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 0) + self.assertEquals(len(rep.u._pad1), 2) + #self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + chunk_size = rep_both - dcerpc.DCERPC_REQUEST_LENGTH + req = self.generate_request(call_id = 2, + context_id=ctx1.context_id, + opnum=0, + alloc_hint=0xffffffff, + stub="\00" * chunk_size) + self.send_pdu(req,ndr_print=True,hexdump=True) + rep = self.recv_pdu(ndr_print=True,hexdump=True) + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + chunk_size = 5840 - dcerpc.DCERPC_REQUEST_LENGTH + req = self.generate_request(call_id = 2, + context_id=ctx1.context_id, + opnum=0, + alloc_hint=0xffffffff, + stub="\00" * chunk_size) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + chunk_size += 1 + req = self.generate_request(call_id = 3, + context_id=ctx1.context_id, + opnum=0, + alloc_hint=0xffffffff, + stub="\00" * chunk_size) + self.send_pdu(req) + rep = self.recv_pdu() + # We get a fault + self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, 0) + self.assertEquals(rep.u.cancel_count, 0) + self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR) + self.assertEquals(len(rep.u._pad), 4) + self.assertEquals(rep.u._pad, '\0' * 4) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + + def test_neg_xmit_ffff_ffff(self): + return self._test_neg_xmit_check_values(req_xmit=0xffff, + req_recv=0xffff, + rep_both=5840) + + def test_neg_xmit_0_ffff(self): + return self._test_neg_xmit_check_values(req_xmit=0, + req_recv=0xffff, + rep_both=2048, + alter_xmit=0xffff, + alter_recv=0xffff) + + def test_neg_xmit_ffff_0(self): + return self._test_neg_xmit_check_values(req_xmit=0xffff, + req_recv=0, + rep_both=2048) + + def test_neg_xmit_0_0(self): + return self._test_neg_xmit_check_values(req_xmit=0, + req_recv=0, + rep_both=2048, + alter_xmit=0xffff, + alter_recv=0xffff) + + def test_neg_xmit_3199_0(self): + return self._test_neg_xmit_check_values(req_xmit=3199, + req_recv=0, + rep_both=2048) + def test_neg_xmit_0_3199(self): + return self._test_neg_xmit_check_values(req_xmit=0, + req_recv=3199, + rep_both=2048) + + def test_neg_xmit_3199_ffff(self): + return self._test_neg_xmit_check_values(req_xmit=3199, + req_recv=0xffff, + rep_both=3192) + def test_neg_xmit_ffff_3199(self): + return self._test_neg_xmit_check_values(req_xmit=0xffff, + req_recv=3199, + rep_both=3192) + + def test_alloc_hint(self): + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx = dcerpc.ctx_list() + ctx.context_id = 0 + ctx.num_transfer_syntaxes = len(tsf1_list) + ctx.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax() + ctx.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, + ctx_list=[ctx]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + self.assertEquals(rep.u.secondary_address_size, 4) + self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port) + self.assertEquals(len(rep.u._pad1), 2) + self.assertEquals(rep.u._pad1, '\0' * 2) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + # And now try a request without auth_info + req = self.generate_request(call_id = 2, + context_id=ctx.context_id, + opnum=0, + alloc_hint=0xffffffff, + stub="") + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + req = self.generate_request(call_id = 3, + context_id=ctx.context_id, + opnum=1, + alloc_hint=0xffffffff, + stub="\04\00\00\00\00\00\00\00") + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + req = self.generate_request(call_id = 4, + context_id=ctx.context_id, + opnum=1, + alloc_hint=1, + stub="\04\00\00\00\00\00\00\00") + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + def _get_netlogon_ctx(self): + abstract = samba.dcerpc.netlogon.abstract_syntax() + self.epmap_reconnect(abstract) + + ndr32 = base.transfer_syntax_ndr() + + tsf1_list = [ndr32] + ctx = dcerpc.ctx_list() + ctx.context_id = 0 + ctx.num_transfer_syntaxes = len(tsf1_list) + ctx.abstract_syntax = abstract + ctx.transfer_syntaxes = tsf1_list + + req = self.generate_bind(call_id=0, + ctx_list=[ctx]) + self.send_pdu(req) + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id, + auth_length=0) + self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag) + self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag) + self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id) + port_str = "%d" % self.tcp_port + port_len = len(port_str) + 1 + mod_len = (2 + port_len) % 4 + if mod_len != 0: + port_pad = 4 - mod_len + else: + port_pad = 0 + self.assertEquals(rep.u.secondary_address_size, port_len) + self.assertEquals(rep.u.secondary_address, port_str) + self.assertEquals(len(rep.u._pad1), port_pad) + self.assertEquals(rep.u._pad1, '\0' * port_pad) + self.assertEquals(rep.u.num_results, 1) + self.assertEquals(rep.u.ctx_list[0].result, + dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE) + self.assertEquals(rep.u.ctx_list[0].reason, + dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED) + self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32) + self.assertEquals(rep.u.auth_info, '\0' * 0) + + server = '\\\\' + self.host + server_utf16 = unicode(server, 'utf-8').encode('utf-16-le') + computer = 'UNKNOWNCOMPUTER' + computer_utf16 = unicode(computer, 'utf-8').encode('utf-16-le') + + real_stub = struct.pack(' 0: + thistime = min(remaining, chunk) + remaining -= thistime + total += thistime + + pfc_flags = 0 + if first: + pfc_flags |= dcerpc.DCERPC_PFC_FLAG_FIRST + first = False + stub = real_stub + '\x00' * (thistime - len(real_stub)) + else: + stub = "\x00" * thistime + + if remaining == 0: + pfc_flags |= dcerpc.DCERPC_PFC_FLAG_LAST + + # And now try a request without auth_info + # netr_ServerReqChallenge() + req = self.generate_request(call_id = 2, + pfc_flags=pfc_flags, + context_id=ctx.context_id, + opnum=4, + alloc_hint=alloc_hint, + stub=stub) + if alloc_hint >= thistime: + alloc_hint -= thistime + else: + alloc_hint = 0 + self.send_pdu(req,hexdump=False) + if fault_first is not None: + rep = self.recv_pdu() + # We get a fault back + self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertEquals(rep.u.status, fault_first) + self.assertEquals(len(rep.u._pad), 4) + self.assertEquals(rep.u._pad, '\0' * 4) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + return + if remaining == 0: + break + if total >= 0x400000 and fault_last is not None: + rep = self.recv_pdu() + # We get a fault back + self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertEquals(rep.u.status, fault_last) + self.assertEquals(len(rep.u._pad), 4) + self.assertEquals(rep.u._pad, '\0' * 4) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + return + rep = self.recv_pdu(timeout=0.01) + self.assertIsNone(rep) + self.assertIsConnected() + + if total >= 0x400000 and fault_last is not None: + rep = self.recv_pdu() + # We get a fault back + self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertEquals(rep.u.status, fault_last) + self.assertEquals(len(rep.u._pad), 4) + self.assertEquals(rep.u._pad, '\0' * 4) + + # wait for a disconnect + rep = self.recv_pdu() + self.assertIsNone(rep) + self.assertNotConnected() + return + rep = self.recv_pdu() + self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id, + auth_length=0) + self.assertNotEquals(rep.u.alloc_hint, 0) + self.assertEquals(rep.u.context_id, req.u.context_id) + self.assertEquals(rep.u.cancel_count, 0) + self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint) + + self.assertEquals(len(rep.u.stub_and_verifier), 12) + status = struct.unpack_from(" Date: Fri, 26 Jun 2015 21:05:53 +0200 Subject: [PATCH 322/323] CVE-2015-5370: s4:selftest: run samba.tests.dcerpc.raw_protocol against ad_dc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=11344 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source4/selftest/tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index a1a04bd..a2f2203 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -554,6 +554,7 @@ planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.rpcecho") planoldpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.registry", extra_args=['-U"$USERNAME%$PASSWORD"']) planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"']) planoldpythontestsuite("ad_dc", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"']) +planoldpythontestsuite("ad_dc", "samba.tests.dcerpc.raw_protocol", extra_args=['-U"$USERNAME%$PASSWORD"']) plantestsuite_loadlist("samba4.ldap.python(ad_dc_ntvfs)", "ad_dc_ntvfs", [python, os.path.join(samba4srcdir, "dsdb/tests/python/ldap.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) plantestsuite_loadlist("samba4.tokengroups.python(ad_dc_ntvfs)", "ad_dc_ntvfs:local", [python, os.path.join(samba4srcdir, "dsdb/tests/python/token_group.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) plantestsuite("samba4.sam.python(ad_dc_ntvfs)", "ad_dc_ntvfs", [python, os.path.join(samba4srcdir, "dsdb/tests/python/sam.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN']) -- 1.9.1 From 777bee33e6eb0520418863dd0060e85e37f773cb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Apr 2016 10:05:38 +0200 Subject: [PATCH 323/323] s3:libads: sasl wrapped LDAP connections against with kerberos and arcfour-hmac-md5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a regression in commit 2cb07ba50decdfd6d08271cd2b3d893ff95f5af9 (s3:libads: make use of ads_sasl_spnego_gensec_bind() for GSS-SPNEGO with Kerberos) that prevents things like 'net ads join' from working against a Windows 2003 domain. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11804 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- source3/libads/sasl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 4fcd733..22aa9cf 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -312,7 +312,13 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads, ads->ldap.out.max_unwrapped = gensec_max_input_size(auth_generic_state->gensec_security); ads->ldap.out.sig_size = max_wrapped - ads->ldap.out.max_unwrapped; - ads->ldap.in.min_wrapped = ads->ldap.out.sig_size; + /* + * Note that we have to truncate this to 0x2C + * (taken from a capture with LDAP unbind), as the + * signature size is not constant for Kerberos with + * arcfour-hmac-md5. + */ + ads->ldap.in.min_wrapped = MIN(ads->ldap.out.sig_size, 0x2C); ads->ldap.in.max_wrapped = max_wrapped; status = ads_setup_sasl_wrapping(ads, &ads_sasl_gensec_ops, auth_generic_state->gensec_security); if (!ADS_ERR_OK(status)) { -- 1.9.1