From 0b7301c22c42a3c33ad6b5ef82d67842c1c6146b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Feb 2018 10:03:23 +0100 Subject: [PATCH 1/7] s3:smb_macros.h: add IS_AD_DC as addition to IS_DC In the long run we should remove this again (as well as IS_DC). But for now this makes some code changes in winbindd easier to follow. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13278 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit c58f8c3cd84ab18d04bd39ad7d5f53676e092abb) --- source3/include/smb_macros.h | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index f1191ac011e..06d24744960 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -214,6 +214,7 @@ copy an IP address from one buffer to another *****************************************************************************/ #define IS_DC (lp_server_role()==ROLE_DOMAIN_PDC || lp_server_role()==ROLE_DOMAIN_BDC || lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) +#define IS_AD_DC (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) /* * If you add any entries to KERBEROS_VERIFY defines, please modify the below expressions -- 2.13.6 From d905cd5388d6f7c784405ca05b2fd1c5725b518a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Feb 2018 10:40:19 +0100 Subject: [PATCH 2/7] winbind: force the usage of schannel in cm_connect_lsa() as AD DC This makes sure we only talk to direct trusts. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13278 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 3e17a3b7cd4083299037ba9377931bea792b2d18) --- source3/winbindd/winbindd_cm.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 54416e02dcd..a735ebee6a7 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2967,6 +2967,13 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, TALLOC_FREE(conn->lsa_pipe); + if (IS_AD_DC) { + /* + * Make sure we only use schannel as AD DC. + */ + goto schannel; + } + result = get_trust_credentials(domain, talloc_tos(), false, &creds); if (!NT_STATUS_IS_OK(result)) { DEBUG(10, ("cm_connect_lsa: No user available for " @@ -3080,6 +3087,13 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, goto done; } + if (IS_AD_DC) { + /* + * Make sure we only use schannel as AD DC. + */ + goto done; + } + DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying " "anonymous\n")); @@ -3087,6 +3101,13 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, anonymous: + if (IS_AD_DC) { + /* + * Make sure we only use schannel as AD DC. + */ + goto done; + } + if (lp_winbind_sealed_pipes() || lp_require_strong_key()) { result = NT_STATUS_DOWNGRADE_DETECTED; DEBUG(1, ("Unwilling to make LSA connection to domain %s " -- 2.13.6 From c4a2182d2e7d000a9fed5df525da37c36cd1cc8c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Feb 2018 10:40:19 +0100 Subject: [PATCH 3/7] winbind: let cm_connect_netlogon_transport() only work against direct trust as AD DC BUG: https://bugzilla.samba.org/show_bug.cgi?id=13278 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 532a14dc684e7a6d8c584d5671a4ebbad00aa4fc) --- source3/winbindd/winbindd_cm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index a735ebee6a7..0bd845b009d 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -3209,6 +3209,17 @@ static NTSTATUS cm_connect_netlogon_transport(struct winbindd_domain *domain, *cli = NULL; + if (IS_AD_DC) { + if (domain->secure_channel_type == SEC_CHAN_NULL) { + /* + * Make sure we don't even try to + * connect to a foreign domain + * without a direct outbound trust. + */ + return NT_STATUS_NO_TRUST_LSA_SECRET; + } + } + result = init_dc_connection_rpc(domain, domain->rodc); if (!NT_STATUS_IS_OK(result)) { return result; -- 2.13.6 From 619d70f5a5b1781710adc3a9d58203110b1a7bcc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Feb 2018 10:33:48 +0100 Subject: [PATCH 4/7] winbind: make sure we don't contact trusted domains via SAMR as AD DC This is not needed for the normal operation of an AD DC. Administrators should just use other tools instead of wbinfo to list and query users and groups. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13278 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 32a63e3ea985c967ca2aadbcd9e0c60ade2d0367) --- source3/winbindd/winbindd_cm.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 0bd845b009d..02a6959f2bd 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2647,6 +2647,20 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, } } + if (IS_AD_DC) { + /* + * In theory we should not use SAMR within + * winbindd at all, but that's a larger task to + * remove this and avoid breaking existing + * setups. + * + * At least as AD DC we have the restriction + * to avoid SAMR against trusted domains, + * as there're no existing setups. + */ + return NT_STATUS_REQUEST_NOT_ACCEPTED; + } + retry: status = init_dc_connection_rpc(domain, need_rw_dc); if (!NT_STATUS_IS_OK(status)) { -- 2.13.6 From 5440575e769e508f92981bbd1f5455cf388bbffd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 2 Feb 2018 16:55:01 +0100 Subject: [PATCH 5/7] winbind: make sure we don't contact trusted domains via LDAP as AD DC BUG: https://bugzilla.samba.org/show_bug.cgi?id=13278 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 18f27b5385240852e537cd5010cedb09f0bf233d) --- source3/winbindd/idmap_ad.c | 11 +++++++++++ source3/winbindd/winbindd_ads.c | 23 +++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/source3/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c index 315a9444a19..15304109a2d 100644 --- a/source3/winbindd/idmap_ad.c +++ b/source3/winbindd/idmap_ad.c @@ -532,6 +532,17 @@ static NTSTATUS idmap_ad_get_context(struct idmap_domain *dom, struct idmap_ad_context *ctx = NULL; NTSTATUS status; + if (IS_AD_DC) { + /* + * Make sure we never try to use LDAP against + * a trusted domain as AD_DC. + * + * This shouldn't be called currently, + * but you never know what happens in future. + */ + return NT_STATUS_REQUEST_NOT_ACCEPTED; + } + if (dom->private_data != NULL) { *pctx = talloc_get_type_abort(dom->private_data, struct idmap_ad_context); diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index c330b9202c8..725fa4ff977 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -159,6 +159,14 @@ ADS_STATUS ads_idmap_cached_connection(ADS_STRUCT **adsp, const char *dom_name) struct winbindd_domain *wb_dom; ADS_STATUS status; + if (IS_AD_DC) { + /* + * Make sure we never try to use LDAP against + * a trusted domain as AD DC. + */ + return ADS_ERROR_NT(NT_STATUS_REQUEST_NOT_ACCEPTED); + } + ads_cached_connection_reuse(adsp); if (*adsp != NULL) { return ADS_SUCCESS; @@ -231,6 +239,14 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) ADS_STATUS status; char *password, *realm; + if (IS_AD_DC) { + /* + * Make sure we never try to use LDAP against + * a trusted domain as AD DC. + */ + return NULL; + } + DEBUG(10,("ads_cached_connection\n")); ads_cached_connection_reuse((ADS_STRUCT **)&domain->private_data); @@ -1309,6 +1325,13 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32_t *seq) return NT_STATUS_OK; } + if (IS_AD_DC) { + DEBUG(10,("sequence: Avoid LDAP connection for domain %s\n", + domain->name)); + *seq = time(NULL); + return NT_STATUS_OK; + } + *seq = DOM_SEQUENCE_NONE; ads = ads_cached_connection(domain); -- 2.13.6 From 616ab16b079e8410fe092f01b6aed75e847bb55b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Feb 2018 11:24:38 +0100 Subject: [PATCH 6/7] winbind: set_dc_type_and_flags() is not needed on a DC On a DC we load the trusts in the parent in add_trusted_domains_dc() from our local configuration. There's no need to find out the trust details via network calls. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13278 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 55c3af89f1b0baecf5e2d6c2646902edd0684aa8) --- source3/winbindd/winbindd_cm.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 02a6959f2bd..acccf104d3c 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2187,6 +2187,15 @@ static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain ) TALLOC_CTX *mem_ctx = NULL; struct dcerpc_binding_handle *b; + if (IS_DC) { + /* + * On a DC we loaded all trusts + * from configuration and never learn + * new domains. + */ + return true; + } + DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name )); /* Our primary domain doesn't need to worry about trust flags. @@ -2581,6 +2590,15 @@ static void set_dc_type_and_flags_connect( struct winbindd_domain *domain ) static void set_dc_type_and_flags( struct winbindd_domain *domain ) { + if (IS_DC) { + /* + * On a DC we loaded all trusts + * from configuration and never learn + * new domains. + */ + return; + } + /* we always have to contact our primary domain */ if ( domain->primary || domain->internal) { -- 2.13.6 From 97ce6ffcb553bba7eff452db4a06c0f7863c591d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Feb 2018 10:19:58 +0100 Subject: [PATCH 7/7] winbind: don't try to do an authenticated SMB connection as AD DC BUG: https://bugzilla.samba.org/show_bug.cgi?id=13278 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Fri Feb 23 17:58:23 CET 2018 on sn-devel-144 (cherry picked from commit 06601b3a9293db35feda1b033fa864dc1a764164) --- source3/winbindd/winbindd_cm.c | 44 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index acccf104d3c..e6cd3efcea9 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -996,6 +996,31 @@ static NTSTATUS cm_prepare_connection(struct winbindd_domain *domain, enum smb_signing_setting smb_sign_client_connections = lp_client_ipc_signing(); + if (IS_AD_DC) { + if (domain->secure_channel_type == SEC_CHAN_NULL) { + /* + * Make sure we don't even try to + * connect to a foreign domain + * without a direct outbound trust. + */ + return NT_STATUS_NO_TRUST_LSA_SECRET; + } + + /* + * As AD DC we only use netlogon and lsa + * using schannel over an anonymous transport + * (ncacn_ip_tcp or ncacn_np). + * + * Currently we always establish the SMB connection, + * even if we don't use it, because we later use ncacn_ip_tcp. + * + * As we won't use the SMB connection there's no + * need to try kerberos. And NT4 domains expect + * an anonymous IPC$ connection anyway. + */ + smb_sign_client_connections = SMB_SIGNING_OFF; + } + if (smb_sign_client_connections == SMB_SIGNING_DEFAULT) { /* * If we are connecting to our own AD domain, require @@ -1008,8 +1033,7 @@ static NTSTATUS cm_prepare_connection(struct winbindd_domain *domain, * AD domain in our forest * then require smb signing to disrupt MITM attacks */ - } else if ((lp_security() == SEC_ADS || - lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) + } else if ((lp_security() == SEC_ADS) && domain->active_directory && (domain->domain_trust_attribs & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST)) { @@ -1068,6 +1092,22 @@ static NTSTATUS cm_prepare_connection(struct winbindd_domain *domain, try_ipc_auth = true; } + if (IS_AD_DC) { + /* + * As AD DC we only use netlogon and lsa + * using schannel over an anonymous transport + * (ncacn_ip_tcp or ncacn_np). + * + * Currently we always establish the SMB connection, + * even if we don't use it, because we later use ncacn_ip_tcp. + * + * As we won't use the SMB connection there's no + * need to try kerberos. And NT4 domains expect + * an anonymous IPC$ connection anyway. + */ + try_ipc_auth = false; + } + if (try_ipc_auth) { result = get_trust_credentials(domain, talloc_tos(), false, &creds); if (!NT_STATUS_IS_OK(result)) { -- 2.13.6