From 61c2e8d4599b67b10178b870ba6971054697ec2b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 17 Jan 2018 14:38:41 +0100 Subject: [PATCH 01/41] pdb: Fix CID 1427624 Resource leak It's not exactly a resource leak (we only really realloc if we shrink dramatically), but assigning the result from tdb_realloc looks nicer. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13263 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme (cherry picked from commit e4f62d4e4b91395d46c99c2a5313b0536793cca7) --- source3/passdb/pdb_samba_dsdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/passdb/pdb_samba_dsdb.c b/source3/passdb/pdb_samba_dsdb.c index 16a7a85bdfd..b06267b2d64 100644 --- a/source3/passdb/pdb_samba_dsdb.c +++ b/source3/passdb/pdb_samba_dsdb.c @@ -2959,7 +2959,7 @@ static NTSTATUS pdb_samba_dsdb_enum_trusteddoms(struct pdb_methods *m, domains[di++] = d; } - talloc_realloc(domains, domains, struct trustdom_info *, di); + domains = talloc_realloc(domains, domains, struct trustdom_info *, di); *_domains = talloc_move(mem_ctx, &domains); *_num_domains = di; TALLOC_FREE(tmp_ctx); -- 2.13.6 From 067cc5ce1d085638d0bb82431e76ce132772d23d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 17 Jan 2018 14:42:31 +0100 Subject: [PATCH 02/41] winbind: Fix CID 1427626 Uninitialized scalar variable Likely a false positive, but Coverity can't follow all the paths leading to line 2030 Bug: https://bugzilla.samba.org/show_bug.cgi?id=13263 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme (cherry picked from commit 92131d08987ac7c2fb219bf2e8300f3bc7b702f9) --- source3/winbindd/winbindd_pam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 9a61cd3a578..6e34b5a777d 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -1823,7 +1823,7 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, fstring name_domain, name_user; char *mapped_user; fstring domain_user; - uint16_t validation_level; + uint16_t validation_level = UINT16_MAX; union netr_Validation *validation = NULL; NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL; -- 2.13.6 From ff6b6bdc732a09d4a17ff5ea4d6f7b6ec91e62db Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 17 Jan 2018 14:38:41 +0100 Subject: [PATCH 03/41] pdb: Fix CID 1427620 Resource leak It's not exactly a resource leak (we only really realloc if we shrink dramatically), but assigning the result from tdb_realloc looks nicer. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13263 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme (cherry picked from commit 4e5c9427085f001941adaf761b18740a2e169240) --- source3/passdb/pdb_samba_dsdb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/passdb/pdb_samba_dsdb.c b/source3/passdb/pdb_samba_dsdb.c index b06267b2d64..4e55a15a0cc 100644 --- a/source3/passdb/pdb_samba_dsdb.c +++ b/source3/passdb/pdb_samba_dsdb.c @@ -3741,7 +3741,8 @@ static NTSTATUS pdb_samba_dsdb_enum_trusted_domains(struct pdb_methods *m, domains[di++] = d; } - talloc_realloc(domains, domains, struct pdb_trusted_domain *, di); + domains = talloc_realloc(domains, domains, struct pdb_trusted_domain *, + di); *_domains = talloc_move(mem_ctx, &domains); *_num_domains = di; TALLOC_FREE(tmp_ctx); -- 2.13.6 From bc5174bd7ebab44ece614d0079136c4c72e48c79 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 17 Jan 2018 14:45:49 +0100 Subject: [PATCH 04/41] winbind: Fix CID 1427626 Uninitialized scalar variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Likely a false positive, but Coverity can't follow all the paths leading to line 1598. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13263 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme Autobuild-User(master): Ralph Böhme Autobuild-Date(master): Wed Jan 17 23:58:34 CET 2018 on sn-devel-144 (cherry picked from commit 3be1e68ce69f7ab8ac2cac97920c0e7f65b5ed6f) --- source3/winbindd/winbindd_pam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 6e34b5a777d..97425e859f3 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -1428,7 +1428,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, int netr_attempts = 0; bool retry = false; NTSTATUS result; - uint16_t validation_level; + uint16_t validation_level = UINT16_MAX; union netr_Validation *validation = NULL; do { -- 2.13.6 From e85ce25d5d07f8ddf651660d96c0a26d2c5c4c2d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2018 14:24:47 +0100 Subject: [PATCH 05/41] winbindd: fix LSA connections via DCERPC_AUTH_SCHANNEL Bug: https://bugzilla.samba.org/show_bug.cgi?id=13231 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 53484d0d98475f55ae3bd02e1a86b9c45b20e33d) --- source3/winbindd/winbindd.h | 1 - source3/winbindd/winbindd_cm.c | 9 --------- 2 files changed, 10 deletions(-) diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h index b60094bafcd..43c90445e87 100644 --- a/source3/winbindd/winbindd.h +++ b/source3/winbindd/winbindd.h @@ -100,7 +100,6 @@ struct winbindd_cm_conn { struct rpc_pipe_client *netlogon_pipe; struct netlogon_creds_cli_context *netlogon_creds_ctx; - uint32_t netlogon_flags; bool netlogon_force_reauth; }; diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 4d3a372dd25..2aca5f374f6 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2039,7 +2039,6 @@ void invalidate_cm_connection(struct winbindd_domain *domain) conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY; conn->netlogon_force_reauth = false; - conn->netlogon_flags = 0; TALLOC_FREE(conn->netlogon_creds_ctx); if (conn->cli) { @@ -2620,9 +2619,6 @@ static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain, } if (domain->conn.netlogon_creds_ctx != NULL) { - if (!(domain->conn.netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) { - return NT_STATUS_TRUSTED_DOMAIN_FAILURE; - } *ppdc = domain->conn.netlogon_creds_ctx; return NT_STATUS_OK; } @@ -2636,10 +2632,6 @@ static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain, return NT_STATUS_TRUSTED_DOMAIN_FAILURE; } - if (!(domain->conn.netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) { - return NT_STATUS_TRUSTED_DOMAIN_FAILURE; - } - *ppdc = domain->conn.netlogon_creds_ctx; return NT_STATUS_OK; } @@ -3234,7 +3226,6 @@ static NTSTATUS cm_connect_netlogon_transport(struct winbindd_domain *domain, } TALLOC_FREE(conn->netlogon_pipe); - conn->netlogon_flags = 0; TALLOC_FREE(conn->netlogon_creds_ctx); result = get_trust_credentials(domain, talloc_tos(), true, &creds); -- 2.13.6 From 6c1c2b1554255377170a10f26d5f71339923e3c6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2018 14:30:12 +0100 Subject: [PATCH 06/41] winbindd: remove useless calls to get_trust_credentials() before cli_rpc_pipe_open_schannel_with_creds() Bug: https://bugzilla.samba.org/show_bug.cgi?id=13231 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 1918a870c38c29bd3a05cd3f660ffe6623121bf3) --- source3/winbindd/winbindd_cm.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 2aca5f374f6..b7fd981547f 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2758,13 +2758,6 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, goto anonymous; } TALLOC_FREE(creds); - result = get_trust_credentials(domain, talloc_tos(), true, &creds); - if (!NT_STATUS_IS_OK(result)) { - DEBUG(10, ("cm_connect_sam: No user available for " - "domain %s (error %s), trying anon\n", domain->name, - nt_errstr(result))); - goto anonymous; - } status = cli_rpc_pipe_open_schannel_with_creds( conn->cli, &ndr_table_samr, NCACN_NP, p_creds, &conn->samr_pipe); @@ -2908,7 +2901,6 @@ static NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain, { struct winbindd_cm_conn *conn; struct netlogon_creds_cli_context *p_creds = NULL; - struct cli_credentials *creds = NULL; NTSTATUS status; DEBUG(10,("cm_connect_lsa_tcp\n")); @@ -2936,11 +2928,6 @@ static NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain, goto done; } - status = get_trust_credentials(domain, talloc_tos(), true, &creds); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - status = cli_rpc_pipe_open_schannel_with_creds(conn->cli, &ndr_table_lsarpc, NCACN_IP_TCP, @@ -3063,13 +3050,6 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, } TALLOC_FREE(creds); - result = get_trust_credentials(domain, talloc_tos(), true, &creds); - if (!NT_STATUS_IS_OK(result)) { - DEBUG(10, ("cm_connect_lsa: No user available for " - "domain %s (error %s), trying anon\n", domain->name, - nt_errstr(result))); - goto anonymous; - } result = cli_rpc_pipe_open_schannel_with_creds( conn->cli, &ndr_table_lsarpc, NCACN_NP, p_creds, &conn->lsa_pipe); -- 2.13.6 From dd37a3f9daef691214ca916f92652c1b40d1d809 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2018 14:30:48 +0100 Subject: [PATCH 07/41] winbindd: add missing can_do_ncacn_ip_tcp initialisation Bug: https://bugzilla.samba.org/show_bug.cgi?id=13232 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 9fef5d1891e6c1aebea29fbfbb90e77631b7836c) --- source3/winbindd/winbindd_util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 4d66571703f..910e02269b5 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -275,6 +275,8 @@ static NTSTATUS add_trusted_domain(const char *domain_name, } } + domain->can_do_ncacn_ip_tcp = domain->active_directory; + /* Link to domain list */ DLIST_ADD_END(_domain_list, domain); -- 2.13.6 From e9a1e29f421e758150143a2b8071b2c8aba27d83 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 18 Jan 2018 08:38:59 +0100 Subject: [PATCH 08/41] winbindd: add routing_domain as parameter to add_trusted_domain This also fixes the following CIDs: CID 1427622: Null pointer dereferences (REVERSE_INULL) CID 1427619: Null pointer dereferences (REVERSE_INULL) Bug: https://bugzilla.samba.org/show_bug.cgi?id=13233 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher (cherry picked from commit 9a613f4bccf171c40ede3e6ead9236463fcc5883) --- source3/winbindd/winbindd_util.c | 55 +++++++++++----------------------------- 1 file changed, 15 insertions(+), 40 deletions(-) diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 910e02269b5..b20976c8048 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -127,6 +127,7 @@ static NTSTATUS add_trusted_domain(const char *domain_name, uint32_t trust_flags, uint32_t trust_attribs, enum netr_SchannelType secure_channel_type, + struct winbindd_domain *routing_domain, struct winbindd_domain **_d) { struct winbindd_domain *domain = NULL; @@ -253,6 +254,7 @@ static NTSTATUS add_trusted_domain(const char *domain_name, domain->domain_type = trust_type; domain->domain_trust_attribs = trust_attribs; domain->secure_channel_type = secure_channel_type; + domain->routing_domain = routing_domain; sid_copy(&domain->sid, sid); /* Is this our primary domain ? */ @@ -343,6 +345,7 @@ bool add_trusted_domain_from_auth(uint16_t validation_level, NETR_TRUST_FLAG_OUTBOUND, 0, SEC_CHAN_NULL, + find_default_route_domain(), &domain); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) @@ -352,11 +355,6 @@ bool add_trusted_domain_from_auth(uint16_t validation_level, return false; } - ok = set_routing_domain(domain, find_default_route_domain()); - if (!ok) { - return false; - } - return true; } @@ -416,7 +414,6 @@ static void trustdom_list_done(struct tevent_req *req) ptrdiff_t extra_len; bool within_forest = false; NTSTATUS status; - bool ok; /* * Only when we enumerate our primary domain @@ -540,6 +537,7 @@ static void trustdom_list_done(struct tevent_req *req) trust_flags, trust_attribs, SEC_CHAN_NULL, + find_default_route_domain(), &domain); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) @@ -549,12 +547,6 @@ static void trustdom_list_done(struct tevent_req *req) return; } - ok = set_routing_domain(domain, find_default_route_domain()); - if (!ok) { - DBG_ERR("set_routing_domain failed\n"); - return; - } - p = q + strlen(q) + 1; } @@ -597,7 +589,6 @@ static void rescan_forest_root_trusts( void ) size_t num_trusts = 0; int i; NTSTATUS status; - bool ok; /* The only transitive trusts supported by Windows 2003 AD are (a) Parent-Child, (b) Tree-Root, and (c) Forest. The @@ -630,6 +621,7 @@ static void rescan_forest_root_trusts( void ) dom_list[i].trust_flags, dom_list[i].trust_attribs, SEC_CHAN_NULL, + find_default_route_domain(), &d); if (!NT_STATUS_IS_OK(status) && @@ -639,11 +631,6 @@ static void rescan_forest_root_trusts( void ) nt_errstr(status)); return; } - ok = set_routing_domain(d, find_default_route_domain()); - if (!ok) { - DBG_ERR("set_routing_domain failed\n"); - return; - } } if (d == NULL) { continue; @@ -679,7 +666,6 @@ static void rescan_forest_trusts( void ) size_t num_trusts = 0; int i; NTSTATUS status; - bool ok; /* The only transitive trusts supported by Windows 2003 AD are (a) Parent-Child, (b) Tree-Root, and (c) Forest. The @@ -718,6 +704,7 @@ static void rescan_forest_trusts( void ) flags, attribs, SEC_CHAN_NULL, + find_default_route_domain(), &d); if (!NT_STATUS_IS_OK(status) && NT_STATUS_EQUAL(status, @@ -727,12 +714,6 @@ static void rescan_forest_trusts( void ) nt_errstr(status)); return; } - ok = set_routing_domain( - d, find_default_route_domain()); - if (!ok) { - DBG_ERR("set_routing_domain failed\n"); - return; - } } if (d == NULL) { @@ -839,7 +820,6 @@ static void wb_imsg_new_trusted_domain(struct imessaging_context *msg, struct winbindd_domain *d = NULL; uint32_t trust_flags = 0; NTSTATUS status; - bool ok; DEBUG(5, ("wb_imsg_new_trusted_domain\n")); @@ -881,6 +861,7 @@ static void wb_imsg_new_trusted_domain(struct imessaging_context *msg, trust_flags, info.trust_attributes, secure_channel_type, + find_default_route_domain(), &d); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) @@ -890,11 +871,7 @@ static void wb_imsg_new_trusted_domain(struct imessaging_context *msg, TALLOC_FREE(frame); return; } - ok = set_routing_domain(d, find_default_route_domain()); - if (!ok) { - TALLOC_FREE(frame); - return; - } + TALLOC_FREE(frame); } @@ -961,6 +938,7 @@ bool init_domain_list(void) 0, /* trust_flags */ 0, /* trust_attribs */ SEC_CHAN_LOCAL, + NULL, &domain); if (!NT_STATUS_IS_OK(status)) { DBG_ERR("add_trusted_domain BUILTIN returned %s\n", @@ -1013,6 +991,7 @@ bool init_domain_list(void) trust_flags, LSA_TRUST_ATTRIBUTE_WITHIN_FOREST, SEC_CHAN_BDC, + NULL, &domain); TALLOC_FREE(pdb_domain_info); if (!NT_STATUS_IS_OK(status)) { @@ -1084,6 +1063,7 @@ bool init_domain_list(void) trust_flags, 0, /* trust_attribs */ secure_channel_type, + NULL, &domain); if (!NT_STATUS_IS_OK(status)) { DBG_ERR("Failed to add local SAM to " @@ -1116,6 +1096,7 @@ bool init_domain_list(void) NETR_TRUST_FLAG_OUTBOUND, 0, /* trust_attribs */ SEC_CHAN_WKSTA, + NULL, &domain); if (!NT_STATUS_IS_OK(status)) { DBG_ERR("Failed to add local SAM to " @@ -1173,6 +1154,7 @@ bool init_domain_list(void) trust_flags, domains[i]->trust_attributes, sec_chan_type, + NULL, &domain); if (!NT_STATUS_IS_OK(status)) { DBG_NOTICE("add_trusted_domain returned %s\n", @@ -1202,7 +1184,6 @@ bool init_domain_list(void) uint32_t fi; enum ndr_err_code ndr_err; struct winbindd_domain *routing_domain = NULL; - bool ok; if (domains[i]->trust_type != LSA_TRUST_TYPE_UPLEVEL) { continue; @@ -1271,6 +1252,7 @@ bool init_domain_list(void) NETR_TRUST_FLAG_OUTBOUND, 0, SEC_CHAN_NULL, + routing_domain, &domain); if (!NT_STATUS_IS_OK(status)) { DBG_NOTICE("add_trusted_domain returned %s\n", @@ -1280,14 +1262,6 @@ bool init_domain_list(void) if (domain == NULL) { continue; } - ok = set_routing_domain(domain, routing_domain); - if (!ok) { - DBG_ERR("set_routing_domain on [%s] to " - "[%s] failed\n", - domain->name, - routing_domain->name); - return false; - } } } } else if (IS_DC) { @@ -1310,6 +1284,7 @@ bool init_domain_list(void) NETR_TRUST_FLAG_OUTBOUND, 0, SEC_CHAN_DOMAIN, + NULL, &domain); if (!NT_STATUS_IS_OK(status)) { DBG_NOTICE("add_trusted_domain returned %s\n", -- 2.13.6 From 810c687a2443217c5702a173fd78e531baab996c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2018 11:58:31 +0100 Subject: [PATCH 09/41] s3:rpc_client: allow Netlogon{Network,Interactive}TransitiveInformation in rpccli_netlogon_password_logon() Bug: https://bugzilla.samba.org/show_bug.cgi?id=13234 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit fe47041b4bf8d2ef6f6f9ba15a80038f1c60da3f) --- source3/rpc_client/cli_netlogon.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 800b995215c..7dc69c066c7 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -490,7 +490,8 @@ NTSTATUS rpccli_netlogon_password_logon( /* Initialise input parameters */ switch (logon_type) { - case NetlogonInteractiveInformation: { + case NetlogonInteractiveInformation: + case NetlogonInteractiveTransitiveInformation: { struct netr_PasswordInfo *password_info; @@ -519,7 +520,8 @@ NTSTATUS rpccli_netlogon_password_logon( break; } - case NetlogonNetworkInformation: { + case NetlogonNetworkInformation: + case NetlogonNetworkTransitiveInformation: { struct netr_NetworkInfo *network_info; uint8_t chal[8]; unsigned char local_lm_response[24]; -- 2.13.6 From 243b993ec9a49bd43ea93c2bf834052fee9589ef Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2018 12:00:19 +0100 Subject: [PATCH 10/41] s3:rpc_client: allow passing NetlogonNetwork[Transitive]Information to rpccli_netlogon_network_logon() Bug: https://bugzilla.samba.org/show_bug.cgi?id=13234 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 7329706a037fef75e8ced63bfb7ab93b64482eda) --- source3/rpc_client/cli_netlogon.c | 13 ++++++++++++- source3/rpc_client/cli_netlogon.h | 1 + source3/winbindd/winbindd_pam.c | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 7dc69c066c7..d8ccce72e0d 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -610,6 +610,7 @@ NTSTATUS rpccli_netlogon_network_logon( const uint8_t chal[8], DATA_BLOB lm_response, DATA_BLOB nt_response, + enum netr_LogonInfoClass logon_type, uint8_t *authoritative, uint32_t *flags, uint16_t *_validation_level, @@ -629,6 +630,16 @@ NTSTATUS rpccli_netlogon_network_logon( ZERO_STRUCT(lm); ZERO_STRUCT(nt); + switch (logon_type) { + case NetlogonNetworkInformation: + case NetlogonNetworkTransitiveInformation: + break; + default: + DEBUG(0, ("switch value %d not supported\n", + logon_type)); + return NT_STATUS_INVALID_INFO_CLASS; + } + logon = talloc_zero(mem_ctx, union netr_LogonLevel); if (!logon) { return NT_STATUS_NO_MEMORY; @@ -674,7 +685,7 @@ NTSTATUS rpccli_netlogon_network_logon( status = netlogon_creds_cli_LogonSamLogon(creds_ctx, binding_handle, - NetlogonNetworkInformation, + logon_type, logon, mem_ctx, &validation_level, diff --git a/source3/rpc_client/cli_netlogon.h b/source3/rpc_client/cli_netlogon.h index d31bdee461f..dc04c0b0676 100644 --- a/source3/rpc_client/cli_netlogon.h +++ b/source3/rpc_client/cli_netlogon.h @@ -84,6 +84,7 @@ NTSTATUS rpccli_netlogon_network_logon( const uint8_t chal[8], DATA_BLOB lm_response, DATA_BLOB nt_response, + enum netr_LogonInfoClass logon_type, uint8_t *authoritative, uint32_t *flags, uint16_t *_validation_level, diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 97425e859f3..b2622a0e92e 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -1520,6 +1520,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, chal, lm_response, nt_response, + NetlogonNetworkInformation, authoritative, flags, &validation_level, -- 2.13.6 From 6e2c4ed59566f357466b60f0553774150223354b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2018 12:02:05 +0100 Subject: [PATCH 11/41] winbindd: use Netlogon{Interactive,Network}TransitiveInformation on transitive trusts Bug: https://bugzilla.samba.org/show_bug.cgi?id=13234 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 70bb9c27cf8c464d5af79acbe11a0d2d0e20f5a8) --- source3/winbindd/winbindd_pam.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index b2622a0e92e..52a24efc531 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -1428,6 +1428,8 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, int netr_attempts = 0; bool retry = false; NTSTATUS result; + enum netr_LogonInfoClass logon_type_i; + enum netr_LogonInfoClass logon_type_n; uint16_t validation_level = UINT16_MAX; union netr_Validation *validation = NULL; @@ -1488,6 +1490,29 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, } return result; } + + logon_type_i = NetlogonInteractiveInformation; + logon_type_n = NetlogonNetworkInformation; + if (domain->domain_trust_attribs & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) { + logon_type_i = NetlogonInteractiveTransitiveInformation; + logon_type_n = NetlogonNetworkTransitiveInformation; + } + + if (domain->domain_trust_attribs & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) { + logon_type_i = NetlogonInteractiveTransitiveInformation; + logon_type_n = NetlogonNetworkTransitiveInformation; + } + + if (domain->domain_trust_attribs & LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE) { + logon_type_i = NetlogonInteractiveInformation; + logon_type_n = NetlogonNetworkInformation; + } + + if (domain->domain_trust_attribs & LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) { + logon_type_i = NetlogonInteractiveInformation; + logon_type_n = NetlogonNetworkInformation; + } + netr_attempts = 0; if (domain->conn.netlogon_creds_ctx == NULL) { DBG_NOTICE("No security credentials available for " @@ -1503,7 +1528,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, username, password, workstation, - NetlogonInteractiveInformation, + logon_type_i, authoritative, flags, &validation_level, @@ -1520,7 +1545,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, chal, lm_response, nt_response, - NetlogonNetworkInformation, + logon_type_n, authoritative, flags, &validation_level, -- 2.13.6 From f3a4beef9b1f35a3342eb503370da8f0f93b007b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2018 12:03:11 +0100 Subject: [PATCH 12/41] winbindd: remove const from set_routing_domain() Bug: https://bugzilla.samba.org/show_bug.cgi?id=13235 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit c5bd18c0021b428c669dbbc35f65a3d436b4add5) --- source3/winbindd/winbindd.h | 2 +- source3/winbindd/winbindd_proto.h | 2 +- source3/winbindd/winbindd_util.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h index 43c90445e87..3e4b256ef32 100644 --- a/source3/winbindd/winbindd.h +++ b/source3/winbindd/winbindd.h @@ -142,7 +142,7 @@ struct winbindd_domain { uint32_t domain_flags; /* Domain flags from netlogon.h */ uint32_t domain_type; /* Domain type from netlogon.h */ uint32_t domain_trust_attribs; /* Trust attribs from netlogon.h */ - const struct winbindd_domain *routing_domain; + struct winbindd_domain *routing_domain; bool initialized; /* Did we already ask for the domain mode? */ bool native_mode; /* is this a win2k domain in native mode ? */ bool active_directory; /* is this a win2k active directory ? */ diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 9a52f6a4edb..49d44af97ff 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -439,7 +439,7 @@ NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain, struct winbindd_domain *domain_list(void); struct winbindd_domain *wb_next_domain(struct winbindd_domain *domain); bool set_routing_domain(struct winbindd_domain *domain, - const struct winbindd_domain *routing_domain); + struct winbindd_domain *routing_domain); bool add_trusted_domain_from_auth(uint16_t validation_level, struct info3_text *info3, struct info6_text *info6); diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index b20976c8048..876ee69a4b6 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -295,7 +295,7 @@ static NTSTATUS add_trusted_domain(const char *domain_name, } bool set_routing_domain(struct winbindd_domain *domain, - const struct winbindd_domain *routing_domain) + struct winbindd_domain *routing_domain) { if (domain->routing_domain == NULL) { domain->routing_domain = routing_domain; -- 2.13.6 From 77d5ebb61bd66c82675f0cf2235904c37c7015cb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2018 12:06:50 +0100 Subject: [PATCH 13/41] winbindd: prepare find_auth_domain() transitive trusts on a DC Bug: https://bugzilla.samba.org/show_bug.cgi?id=13235 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit af9a37aa1925a18709365ceb93460d8ae0f66f51) --- source3/winbindd/winbindd_pam.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 52a24efc531..a14b801cb94 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -395,8 +395,14 @@ struct winbindd_domain *find_auth_domain(uint8_t flags, DEBUG(3, ("Authentication for domain [%s] refused " "as it is not a trusted domain\n", domain_name)); + return NULL; } - return domain; + + if (domain->secure_channel_type != SEC_CHAN_NULL) { + return domain; + } + + return domain->routing_domain; } if (strequal(domain_name, get_global_sam_name())) { -- 2.13.6 From a02b89777e53eec5879c53c33c8bb1f145266715 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2018 12:06:50 +0100 Subject: [PATCH 14/41] winbindd: prepare find_lookup_domain_from_{name,sid}() transitive trusts on a DC Bug: https://bugzilla.samba.org/show_bug.cgi?id=13235 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 8b7bf6d4d81cde099d78cd9cc03aa085cec672d4) --- source3/winbindd/winbindd_util.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 876ee69a4b6..c190ad26ddf 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1488,15 +1488,31 @@ struct winbindd_domain *find_lookup_domain_from_sid(const struct dom_sid *sid) return find_domain_from_sid(get_global_sam_sid()); } - /* A DC can't ask the local smbd for remote SIDs, here winbindd is the - * one to contact the external DC's. On member servers the internal - * domains are different: These are part of the local SAM. */ + /* + * On member servers the internal domains are different: These are part + * of the local SAM. + */ - if (IS_DC || is_internal_domain(sid) || is_in_internal_domain(sid)) { + if (is_internal_domain(sid) || is_in_internal_domain(sid)) { DEBUG(10, ("calling find_domain_from_sid\n")); return find_domain_from_sid(sid); } + if (IS_DC) { + struct winbindd_domain *domain = NULL; + + domain = find_domain_from_sid_noinit(sid); + if (domain == NULL) { + return NULL; + } + + if (domain->secure_channel_type != SEC_CHAN_NULL) { + return domain; + } + + return domain->routing_domain; + } + /* On a member server a query for SID or name can always go to our * primary DC. */ @@ -1516,10 +1532,24 @@ struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name) return find_domain_from_name_noinit( get_global_sam_name() ); } - if (IS_DC || strequal(domain_name, "BUILTIN") || + if (strequal(domain_name, "BUILTIN") || strequal(domain_name, get_global_sam_name())) return find_domain_from_name_noinit(domain_name); + if (IS_DC) { + struct winbindd_domain *domain = NULL; + + domain = find_domain_from_name_noinit(domain_name); + if (domain == NULL) { + return NULL; + } + + if (domain->secure_channel_type != SEC_CHAN_NULL) { + return domain; + } + + return domain->routing_domain; + } return find_our_domain(); } -- 2.13.6 From 42c030b05c130725e80e3ba6097d8ccd3ec423e2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2018 12:57:11 +0100 Subject: [PATCH 15/41] s3:rpc_client: pass down lsa_LookupNamesLevel to dcerpc_lsa_lookup_sids_generic() Bug: https://bugzilla.samba.org/show_bug.cgi?id=13236 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 7fc19747ef346df9cc72bb516b45a8309f462dd8) --- source3/rpc_client/cli_lsarpc.c | 10 +++++++++- source3/rpc_client/cli_lsarpc.h | 1 + source3/winbindd/winbindd_msrpc.c | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index 41c1ef482f4..65c6ca04d50 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -172,6 +172,7 @@ static NTSTATUS dcerpc_lsa_lookup_sids_noalloc(struct dcerpc_binding_handle *h, struct policy_handle *pol, int num_sids, const struct dom_sid *sids, + enum lsa_LookupNamesLevel level, char **domains, char **names, enum lsa_SidType *types, @@ -183,7 +184,6 @@ static NTSTATUS dcerpc_lsa_lookup_sids_noalloc(struct dcerpc_binding_handle *h, struct lsa_SidArray sid_array; struct lsa_RefDomainList *ref_domains = NULL; struct lsa_TransNameArray lsa_names; - enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL; uint32_t count = 0; int i; @@ -348,6 +348,7 @@ NTSTATUS dcerpc_lsa_lookup_sids_generic(struct dcerpc_binding_handle *h, struct policy_handle *pol, int num_sids, const struct dom_sid *sids, + enum lsa_LookupNamesLevel level, char ***pdomains, char ***pnames, enum lsa_SidType **ptypes, @@ -414,6 +415,7 @@ NTSTATUS dcerpc_lsa_lookup_sids_generic(struct dcerpc_binding_handle *h, pol, hunk_num_sids, hunk_sids, + level, hunk_domains, hunk_names, hunk_types, @@ -489,11 +491,13 @@ NTSTATUS dcerpc_lsa_lookup_sids(struct dcerpc_binding_handle *h, enum lsa_SidType **ptypes, NTSTATUS *result) { + enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL; return dcerpc_lsa_lookup_sids_generic(h, mem_ctx, pol, num_sids, sids, + level, pdomains, pnames, ptypes, @@ -512,12 +516,14 @@ NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, { NTSTATUS status; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL; status = dcerpc_lsa_lookup_sids_generic(cli->binding_handle, mem_ctx, pol, num_sids, sids, + level, pdomains, pnames, ptypes, @@ -540,11 +546,13 @@ NTSTATUS dcerpc_lsa_lookup_sids3(struct dcerpc_binding_handle *h, enum lsa_SidType **ptypes, NTSTATUS *result) { + enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL; return dcerpc_lsa_lookup_sids_generic(h, mem_ctx, pol, num_sids, sids, + level, pdomains, pnames, ptypes, diff --git a/source3/rpc_client/cli_lsarpc.h b/source3/rpc_client/cli_lsarpc.h index 4f9464d5b05..f716b049e12 100644 --- a/source3/rpc_client/cli_lsarpc.h +++ b/source3/rpc_client/cli_lsarpc.h @@ -130,6 +130,7 @@ NTSTATUS dcerpc_lsa_lookup_sids_generic(struct dcerpc_binding_handle *h, struct policy_handle *pol, int num_sids, const struct dom_sid *sids, + enum lsa_LookupNamesLevel level, char ***pdomains, char ***pnames, enum lsa_SidType **ptypes, diff --git a/source3/winbindd/winbindd_msrpc.c b/source3/winbindd/winbindd_msrpc.c index 9bf4354f4e3..bc27a39c08f 100644 --- a/source3/winbindd/winbindd_msrpc.c +++ b/source3/winbindd/winbindd_msrpc.c @@ -999,6 +999,7 @@ NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx, unsigned int orig_timeout; bool use_lookupsids3 = false; bool retried = false; + enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL; connect: status = cm_connect_lsat(domain, mem_ctx, &cli, &lsa_policy); @@ -1024,6 +1025,7 @@ NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx, &lsa_policy, num_sids, sids, + level, domains, names, types, -- 2.13.6 From 54076e08a42feff5a038d0319cc32ff7861ee794 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Jan 2018 13:02:04 +0100 Subject: [PATCH 16/41] winbindd: don't force using LSA_LOOKUP_NAMES_ALL for non workstation trusts. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13236 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 728fb7c593230abeb681854d924e4619d6f4cf37) --- source3/winbindd/winbindd_msrpc.c | 61 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_msrpc.c b/source3/winbindd/winbindd_msrpc.c index bc27a39c08f..eb400f0ebf3 100644 --- a/source3/winbindd/winbindd_msrpc.c +++ b/source3/winbindd/winbindd_msrpc.c @@ -983,6 +983,60 @@ static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain, return status; } +static enum lsa_LookupNamesLevel winbindd_lookup_level( + struct winbindd_domain *domain) +{ + enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_DOMAINS_ONLY; + + if (domain->internal) { + level = LSA_LOOKUP_NAMES_ALL; + } else if (domain->secure_channel_type == SEC_CHAN_DNS_DOMAIN) { + if (domain->domain_flags & NETR_TRUST_FLAG_IN_FOREST) { + /* + * TODO: + * + * Depending on what we want to resolve. We need to use: + * 1. LsapLookupXForestReferral(5)/LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY + * if we want to pass the request into the direction of the forest + * root domain. The forest root domain uses + * LsapLookupXForestResolve(6)/LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 + * when passing the request to trusted forests. + * 2. LsapLookupGC(4)/LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY + * if we're not a GC and want to resolve a name within our own forest. + * + * As we don't support more than one domain in our own forest + * and always try to be a GC for now, we just set + * LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY. + */ + level = LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY; + } else if (domain->domain_trust_attribs & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) { + /* + * This is LsapLookupXForestResolve(6)/LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 + */ + level = LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2; + } else { + /* + * This is LsapLookupTDL(3)/LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY + */ + level = LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY; + } + } else if (domain->secure_channel_type == SEC_CHAN_DOMAIN) { + /* + * This is LsapLookupTDL(3)/LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY + */ + level = LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY; + } else if (domain->rodc) { + level = LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC; + } else { + /* + * This is LsapLookupPDC(2)/LSA_LOOKUP_NAMES_DOMAINS_ONLY + */ + level = LSA_LOOKUP_NAMES_DOMAINS_ONLY; + } + + return level; +} + NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, uint32_t num_sids, @@ -1013,6 +1067,8 @@ NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx, use_lookupsids3 = true; } + level = winbindd_lookup_level(domain); + /* * This call can take a long time * allow the server to time out. @@ -1076,6 +1132,7 @@ static NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, unsigned int orig_timeout = 0; bool use_lookupnames4 = false; bool retried = false; + enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL; connect: status = cm_connect_lsat(domain, mem_ctx, &cli, &lsa_policy); @@ -1089,6 +1146,8 @@ static NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, use_lookupnames4 = true; } + level = winbindd_lookup_level(domain); + /* * This call can take a long time * allow the server to time out. @@ -1102,7 +1161,7 @@ static NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, num_names, (const char **) names, domains, - 1, + level, sids, types, use_lookupnames4, -- 2.13.6 From b32f5d692873965d06c764c5ca965502ff6ee05c Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 18 Jan 2018 11:28:20 +0100 Subject: [PATCH 17/41] winbindd: move loading of trusted domains on a DC to a seperate function This allows using the split out function in a subsequent commit in the MSG_WINBIND_NEW_TRUSTED_DOMAIN message handler. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13237 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher (cherry picked from commit 4274ef681bf3b974ce99b8f21fda3a86a5b305bc) --- source3/winbindd/winbindd_util.c | 400 ++++++++++++++++++++------------------- 1 file changed, 207 insertions(+), 193 deletions(-) diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index c190ad26ddf..600abe6deac 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -918,6 +918,203 @@ static bool migrate_secrets_tdb_to_ldb(struct winbindd_domain *domain) return true; } +static bool add_trusted_domains_dc(void) +{ + struct winbindd_domain *domain = NULL; + struct pdb_trusted_domain **domains = NULL; + uint32_t num_domains = 0; + uint32_t i; + NTSTATUS status; + + if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) { + struct trustdom_info **ti = NULL; + + status = pdb_enum_trusteddoms(talloc_tos(), &num_domains, &ti); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("pdb_enum_trusteddoms() failed - %s\n", + nt_errstr(status)); + return false; + } + + for (i = 0; i < num_domains; i++) { + status = add_trusted_domain(ti[i]->name, + NULL, + &ti[i]->sid, + LSA_TRUST_TYPE_DOWNLEVEL, + NETR_TRUST_FLAG_OUTBOUND, + 0, + SEC_CHAN_DOMAIN, + NULL, + &domain); + if (!NT_STATUS_IS_OK(status)) { + DBG_NOTICE("add_trusted_domain returned %s\n", + nt_errstr(status)); + return false; + } + + /* Even in the parent winbindd we'll need to + talk to the DC, so try and see if we can + contact it. Theoretically this isn't neccessary + as the init_dc_connection() in init_child_recv() + will do this, but we can start detecting the DC + early here. */ + set_domain_online_request(domain); + } + + return true; + } + + status = pdb_enum_trusted_domains(talloc_tos(), &num_domains, &domains); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("pdb_enum_trusted_domains() failed - %s\n", + nt_errstr(status)); + return false; + } + + for (i = 0; i < num_domains; i++) { + enum netr_SchannelType sec_chan_type = SEC_CHAN_DOMAIN; + uint32_t trust_flags = 0; + + if (domains[i]->trust_type == LSA_TRUST_TYPE_UPLEVEL) { + sec_chan_type = SEC_CHAN_DNS_DOMAIN; + } + + if (!(domains[i]->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND)) { + sec_chan_type = SEC_CHAN_NULL; + } + + if (domains[i]->trust_direction & LSA_TRUST_DIRECTION_INBOUND) { + trust_flags |= NETR_TRUST_FLAG_INBOUND; + } + if (domains[i]->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) { + trust_flags |= NETR_TRUST_FLAG_OUTBOUND; + } + if (domains[i]->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) { + trust_flags |= NETR_TRUST_FLAG_IN_FOREST; + } + + status = add_trusted_domain(domains[i]->netbios_name, + domains[i]->domain_name, + &domains[i]->security_identifier, + domains[i]->trust_type, + trust_flags, + domains[i]->trust_attributes, + sec_chan_type, + NULL, + &domain); + if (!NT_STATUS_IS_OK(status)) { + DBG_NOTICE("add_trusted_domain returned %s\n", + nt_errstr(status)); + return false; + } + + if (domains[i]->trust_type == LSA_TRUST_TYPE_UPLEVEL) { + domain->active_directory = true; + } + domain->domain_type = domains[i]->trust_type; + domain->domain_trust_attribs = domains[i]->trust_attributes; + + if (sec_chan_type != SEC_CHAN_NULL) { + /* Even in the parent winbindd we'll need to + talk to the DC, so try and see if we can + contact it. Theoretically this isn't neccessary + as the init_dc_connection() in init_child_recv() + will do this, but we can start detecting the DC + early here. */ + set_domain_online_request(domain); + } + } + + for (i = 0; i < num_domains; i++) { + struct ForestTrustInfo fti; + uint32_t fi; + enum ndr_err_code ndr_err; + struct winbindd_domain *routing_domain = NULL; + + if (domains[i]->trust_type != LSA_TRUST_TYPE_UPLEVEL) { + continue; + } + + if (!(domains[i]->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) { + continue; + } + + if (domains[i]->trust_forest_trust_info.length == 0) { + continue; + } + + routing_domain = find_domain_from_name_noinit( + domains[i]->netbios_name); + if (routing_domain == NULL) { + DBG_ERR("Can't find winbindd domain [%s]\n", + domains[i]->netbios_name); + return false; + } + + ndr_err = ndr_pull_struct_blob_all( + &domains[i]->trust_forest_trust_info, + talloc_tos(), &fti, + (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DBG_ERR("ndr_pull_ForestTrustInfo(%s) - %s\n", + domains[i]->netbios_name, + ndr_map_error2string(ndr_err)); + return false; + } + + for (fi = 0; fi < fti.count; fi++) { + struct ForestTrustInfoRecord *rec = + &fti.records[fi].record; + struct ForestTrustDataDomainInfo *drec = NULL; + + if (rec->type != FOREST_TRUST_DOMAIN_INFO) { + continue; + } + drec = &rec->data.info; + + if (rec->flags & LSA_NB_DISABLED_MASK) { + continue; + } + + if (rec->flags & LSA_SID_DISABLED_MASK) { + continue; + } + + /* + * TODO: + * also try to find a matching + * LSA_TLN_DISABLED_MASK ??? + */ + + domain = find_domain_from_name_noinit(drec->netbios_name.string); + if (domain != NULL) { + continue; + } + + status = add_trusted_domain(drec->netbios_name.string, + drec->dns_name.string, + &drec->sid, + LSA_TRUST_TYPE_UPLEVEL, + NETR_TRUST_FLAG_OUTBOUND, + 0, + SEC_CHAN_NULL, + routing_domain, + &domain); + if (!NT_STATUS_IS_OK(status)) { + DBG_NOTICE("add_trusted_domain returned %s\n", + nt_errstr(status)); + return false; + } + if (domain == NULL) { + continue; + } + } + } + + return true; +} + + /* Look up global info for the winbind daemon */ bool init_domain_list(void) { @@ -925,6 +1122,7 @@ bool init_domain_list(void) struct pdb_domain_info *pdb_domain_info = NULL; struct winbindd_domain *domain = NULL; NTSTATUS status; + bool ok; /* Free existing list */ free_domain_list(); @@ -965,7 +1163,6 @@ bool init_domain_list(void) enum netr_SchannelType sec_chan_type; const char *account_name; struct samr_Password current_nt_hash; - bool ok; if (pdb_domain_info == NULL) { DEBUG(0, ("Failed to fetch our own, local AD " @@ -1071,7 +1268,14 @@ bool init_domain_list(void) return false; } } - /* Add ourselves as the first entry. */ + + if (IS_DC) { + ok = add_trusted_domains_dc(); + if (!ok) { + DBG_ERR("init_domain_list_dc failed\n"); + return false; + } + } if ( role == ROLE_DOMAIN_MEMBER ) { struct dom_sid our_sid; @@ -1113,201 +1317,11 @@ bool init_domain_list(void) } - if (IS_DC && (pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) { - uint32_t num_domains = 0; - struct pdb_trusted_domain **domains = NULL; - uint32_t i; - - status = pdb_enum_trusted_domains(talloc_tos(), &num_domains, &domains); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("pdb_enum_trusted_domains() failed - %s\n", - nt_errstr(status)); - return false; - } - - for (i = 0; i < num_domains; i++) { - enum netr_SchannelType sec_chan_type = SEC_CHAN_DOMAIN; - uint32_t trust_flags = 0; - - if (domains[i]->trust_type == LSA_TRUST_TYPE_UPLEVEL) { - sec_chan_type = SEC_CHAN_DNS_DOMAIN; - } - - if (!(domains[i]->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND)) { - sec_chan_type = SEC_CHAN_NULL; - } - - if (domains[i]->trust_direction & LSA_TRUST_DIRECTION_INBOUND) { - trust_flags |= NETR_TRUST_FLAG_INBOUND; - } - if (domains[i]->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) { - trust_flags |= NETR_TRUST_FLAG_OUTBOUND; - } - if (domains[i]->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) { - trust_flags |= NETR_TRUST_FLAG_IN_FOREST; - } - - status = add_trusted_domain(domains[i]->netbios_name, - domains[i]->domain_name, - &domains[i]->security_identifier, - domains[i]->trust_type, - trust_flags, - domains[i]->trust_attributes, - sec_chan_type, - NULL, - &domain); - if (!NT_STATUS_IS_OK(status)) { - DBG_NOTICE("add_trusted_domain returned %s\n", - nt_errstr(status)); - return false; - } - - if (domains[i]->trust_type == LSA_TRUST_TYPE_UPLEVEL) { - domain->active_directory = true; - } - domain->domain_type = domains[i]->trust_type; - domain->domain_trust_attribs = domains[i]->trust_attributes; - - if (sec_chan_type != SEC_CHAN_NULL) { - /* Even in the parent winbindd we'll need to - talk to the DC, so try and see if we can - contact it. Theoretically this isn't neccessary - as the init_dc_connection() in init_child_recv() - will do this, but we can start detecting the DC - early here. */ - set_domain_online_request(domain); - } - } - - for (i = 0; i < num_domains; i++) { - struct ForestTrustInfo fti; - uint32_t fi; - enum ndr_err_code ndr_err; - struct winbindd_domain *routing_domain = NULL; - - if (domains[i]->trust_type != LSA_TRUST_TYPE_UPLEVEL) { - continue; - } - - if (!(domains[i]->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) { - continue; - } - - if (domains[i]->trust_forest_trust_info.length == 0) { - continue; - } - - routing_domain = find_domain_from_name_noinit( - domains[i]->netbios_name); - if (routing_domain == NULL) { - DBG_ERR("Can't find winbindd domain [%s]\n", - domains[i]->netbios_name); - return false; - } - - ndr_err = ndr_pull_struct_blob_all( - &domains[i]->trust_forest_trust_info, - talloc_tos(), &fti, - (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DBG_ERR("ndr_pull_ForestTrustInfo(%s) - %s\n", - domains[i]->netbios_name, - ndr_map_error2string(ndr_err)); - return false; - } - - for (fi = 0; fi < fti.count; fi++) { - struct ForestTrustInfoRecord *rec = - &fti.records[fi].record; - struct ForestTrustDataDomainInfo *drec = NULL; - - if (rec->type != FOREST_TRUST_DOMAIN_INFO) { - continue; - } - drec = &rec->data.info; - - if (rec->flags & LSA_NB_DISABLED_MASK) { - continue; - } - - if (rec->flags & LSA_SID_DISABLED_MASK) { - continue; - } - - /* - * TODO: - * also try to find a matching - * LSA_TLN_DISABLED_MASK ??? - */ - - domain = find_domain_from_name_noinit(drec->netbios_name.string); - if (domain != NULL) { - continue; - } - - status = add_trusted_domain(drec->netbios_name.string, - drec->dns_name.string, - &drec->sid, - LSA_TRUST_TYPE_UPLEVEL, - NETR_TRUST_FLAG_OUTBOUND, - 0, - SEC_CHAN_NULL, - routing_domain, - &domain); - if (!NT_STATUS_IS_OK(status)) { - DBG_NOTICE("add_trusted_domain returned %s\n", - nt_errstr(status)); - return false; - } - if (domain == NULL) { - continue; - } - } - } - } else if (IS_DC) { - uint32_t num_domains = 0; - struct trustdom_info **domains = NULL; - uint32_t i; - - status = pdb_enum_trusteddoms(talloc_tos(), &num_domains, &domains); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("pdb_enum_trusteddoms() failed - %s\n", - nt_errstr(status)); - return false; - } - - for (i = 0; i < num_domains; i++) { - status = add_trusted_domain(domains[i]->name, - NULL, - &domains[i]->sid, - LSA_TRUST_TYPE_DOWNLEVEL, - NETR_TRUST_FLAG_OUTBOUND, - 0, - SEC_CHAN_DOMAIN, - NULL, - &domain); - if (!NT_STATUS_IS_OK(status)) { - DBG_NOTICE("add_trusted_domain returned %s\n", - nt_errstr(status)); - return false; - } - - /* Even in the parent winbindd we'll need to - talk to the DC, so try and see if we can - contact it. Theoretically this isn't neccessary - as the init_dc_connection() in init_child_recv() - will do this, but we can start detecting the DC - early here. */ - set_domain_online_request(domain); - } - } - status = imessaging_register(winbind_imessaging_context(), NULL, MSG_WINBIND_NEW_TRUSTED_DOMAIN, wb_imsg_new_trusted_domain); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("imessaging_register(MSG_WINBIND_NEW_TRUSTED_DOMAIN) - %s\n", - nt_errstr(status))); + DBG_ERR("imessaging_register failed %s\n", nt_errstr(status)); return false; } -- 2.13.6 From 5b5a5d84e1f0dc5ea32d403070de947beef89161 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 18 Jan 2018 11:30:53 +0100 Subject: [PATCH 18/41] winbindd: use add_trusted_domains_dc in wb_imsg_new_trusted_domain Bug: https://bugzilla.samba.org/show_bug.cgi?id=13237 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher (cherry picked from commit d8e4e7cae57eb192c6fcab6b9aef95fb10eeb5a8) --- source3/winbindd/winbindd_util.c | 63 ++++------------------------------------ 1 file changed, 6 insertions(+), 57 deletions(-) diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 600abe6deac..a4d912d2ca1 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -43,6 +43,7 @@ * Winbind daemon for NT domain authentication nss module. **/ +static bool add_trusted_domains_dc(void); /* The list of trusted domains. Note that the list can be deleted and recreated using the init_domain_list() function so pointers to @@ -813,66 +814,14 @@ static void wb_imsg_new_trusted_domain(struct imessaging_context *msg, struct server_id server_id, DATA_BLOB *data) { - TALLOC_CTX *frame = talloc_stackframe(); - enum netr_SchannelType secure_channel_type = SEC_CHAN_DOMAIN; - struct lsa_TrustDomainInfoInfoEx info; - enum ndr_err_code ndr_err; - struct winbindd_domain *d = NULL; - uint32_t trust_flags = 0; - NTSTATUS status; - - DEBUG(5, ("wb_imsg_new_trusted_domain\n")); - - if (data == NULL) { - TALLOC_FREE(frame); - return; - } + bool ok; - ndr_err = ndr_pull_struct_blob_all(data, frame, &info, - (ndr_pull_flags_fn_t)ndr_pull_lsa_TrustDomainInfoInfoEx); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - TALLOC_FREE(frame); - return; - } + DBG_NOTICE("Rescanning trusted domains\n"); - d = find_domain_from_name_noinit(info.netbios_name.string); - if (d != NULL) { - TALLOC_FREE(frame); - return; - } - - if (info.trust_type == LSA_TRUST_TYPE_UPLEVEL) { - secure_channel_type = SEC_CHAN_DNS_DOMAIN; - } - if (info.trust_direction & LSA_TRUST_DIRECTION_INBOUND) { - trust_flags |= NETR_TRUST_FLAG_INBOUND; - } - if (info.trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) { - trust_flags |= NETR_TRUST_FLAG_OUTBOUND; - } - if (info.trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) { - trust_flags |= NETR_TRUST_FLAG_IN_FOREST; - } - - status = add_trusted_domain(info.netbios_name.string, - info.domain_name.string, - info.sid, - info.trust_type, - trust_flags, - info.trust_attributes, - secure_channel_type, - find_default_route_domain(), - &d); - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) - { - DBG_NOTICE("add_trusted_domain returned %s\n", - nt_errstr(status)); - TALLOC_FREE(frame); - return; + ok = add_trusted_domains_dc(); + if (!ok) { + DBG_ERR("Failed to reload trusted domains\n"); } - - TALLOC_FREE(frame); } /* -- 2.13.6 From 33c6a04b52f73cc4a62a0e0e376ec4a874aad3fe Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 18 Jan 2018 11:32:30 +0100 Subject: [PATCH 19/41] s4/rpc_server: remove unused data argument from MSG_WINBIND_NEW_TRUSTED_DOMAIN winbindd doesn't use that data anymore. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13237 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher (cherry picked from commit ffa9eb7d6453eb6c6f3a50ad72288d3891361752) --- source4/rpc_server/lsa/dcesrv_lsa.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 8b212222bc9..b2115fd49f9 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -1360,15 +1360,8 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc "winbind_server", &num_server_ids, &server_ids); if (NT_STATUS_IS_OK(status) && num_server_ids >= 1) { - enum ndr_err_code ndr_err; - DATA_BLOB b = {}; - - ndr_err = ndr_push_struct_blob(&b, mem_ctx, r->in.info, - (ndr_push_flags_fn_t)ndr_push_lsa_TrustDomainInfoInfoEx); - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - imessaging_send(dce_call->msg_ctx, server_ids[0], - MSG_WINBIND_NEW_TRUSTED_DOMAIN, &b); - } + imessaging_send(dce_call->msg_ctx, server_ids[0], + MSG_WINBIND_NEW_TRUSTED_DOMAIN, NULL); } TALLOC_FREE(server_ids); -- 2.13.6 From cf69be1ea5cc2285bedfac5c1cc694c2db10240f Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 18 Jan 2018 16:35:13 +0100 Subject: [PATCH 20/41] winbindd: rename MSG_WINBIND_NEW_TRUSTED_DOMAIN to MSG_WINBIND_RELOAD_TRUSTED_DOMAINS This reflects the new implementation in winbindd. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13237 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher (cherry picked from commit 9f96ede6f500cc1a7c76e67ee785b44a99244d0d) --- librpc/idl/messaging.idl | 2 +- source3/winbindd/winbindd_util.c | 2 +- source4/rpc_server/lsa/dcesrv_lsa.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/librpc/idl/messaging.idl b/librpc/idl/messaging.idl index 37f8fccfb8d..b35f1e1e9ae 100644 --- a/librpc/idl/messaging.idl +++ b/librpc/idl/messaging.idl @@ -123,7 +123,7 @@ interface messaging MSG_WINBIND_IP_DROPPED = 0x040A, MSG_WINBIND_DOMAIN_ONLINE = 0x040B, MSG_WINBIND_DOMAIN_OFFLINE = 0x040C, - MSG_WINBIND_NEW_TRUSTED_DOMAIN = 0x040D, + MSG_WINBIND_RELOAD_TRUSTED_DOMAINS = 0x040D, /* event messages */ MSG_DUMP_EVENT_LIST = 0x0500, diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index a4d912d2ca1..05c963f858f 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1267,7 +1267,7 @@ bool init_domain_list(void) } status = imessaging_register(winbind_imessaging_context(), NULL, - MSG_WINBIND_NEW_TRUSTED_DOMAIN, + MSG_WINBIND_RELOAD_TRUSTED_DOMAINS, wb_imsg_new_trusted_domain); if (!NT_STATUS_IS_OK(status)) { DBG_ERR("imessaging_register failed %s\n", nt_errstr(status)); diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index b2115fd49f9..4424b5667b7 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -1361,7 +1361,7 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc &num_server_ids, &server_ids); if (NT_STATUS_IS_OK(status) && num_server_ids >= 1) { imessaging_send(dce_call->msg_ctx, server_ids[0], - MSG_WINBIND_NEW_TRUSTED_DOMAIN, NULL); + MSG_WINBIND_RELOAD_TRUSTED_DOMAINS, NULL); } TALLOC_FREE(server_ids); -- 2.13.6 From dcaecebcf02d1e55dad315e1a5206c582a8b2978 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 18 Jan 2018 16:35:52 +0100 Subject: [PATCH 21/41] s4/rpc_server: trigger trusts reload in winbindd after successfull trust info acquisition Bug: https://bugzilla.samba.org/show_bug.cgi?id=13237 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher (cherry picked from commit 6151909c823016417f863c22e77c8a136f3fbb95) --- source4/rpc_server/lsa/dcesrv_lsa.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 4424b5667b7..9714e74a720 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -4363,6 +4363,8 @@ static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_stat struct lsa_ForestTrustCollisionInfo *c_info = NULL; DATA_BLOB ft_blob = {}; struct ldb_message *msg = NULL; + struct server_id *server_ids = NULL; + uint32_t num_server_ids = 0; NTSTATUS status; enum ndr_err_code ndr_err; int ret; @@ -4602,6 +4604,21 @@ static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_stat goto done; } + /* + * Notify winbindd that we have a acquired forest trust info + */ + status = irpc_servers_byname(dce_call->msg_ctx, + mem_ctx, + "winbind_server", + &num_server_ids, &server_ids); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("irpc_servers_byname failed\n"); + goto done; + } + + imessaging_send(dce_call->msg_ctx, server_ids[0], + MSG_WINBIND_RELOAD_TRUSTED_DOMAINS, NULL); + status = NT_STATUS_OK; done: -- 2.13.6 From 3f3b69d1480111026999f2d4886f74a418caa0b7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 31 Jan 2018 08:22:07 +0100 Subject: [PATCH 22/41] winbindd: fix debug message in find_default_route_domain() on a DC As we don't support multiple domains in a forest yet, we don't need to print a warning a log level 0. This also adds a missing \n. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13255 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit b112cbc2462edf810473026c133b0802d1e18468) --- source3/winbindd/winbindd_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 05c963f858f..5f4f905db4c 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1426,7 +1426,7 @@ struct winbindd_domain *find_default_route_domain(void) if (!IS_DC) { return find_our_domain(); } - DBG_ERR("Routing logic not yet implemented on a DC"); + DBG_DEBUG("Routing logic not yet implemented on a DC\n"); return NULL; } -- 2.13.6 From 8f3e40c04225306e52c8b02fd6532e345487f756 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 4 Feb 2018 22:48:01 +0100 Subject: [PATCH 23/41] wbinfo: avoid segfault in wbinfo_auth_crap() if winbindd is not available Bug: https://bugzilla.samba.org/show_bug.cgi?id=13256 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 8b0e1a77ae5f7ef6d8db9a05718afa8d472a971b) --- nsswitch/wbinfo.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c index 54d5758aa6c..82863c26760 100644 --- a/nsswitch/wbinfo.c +++ b/nsswitch/wbinfo.c @@ -1798,13 +1798,22 @@ static bool wbinfo_auth_crap(char *username, bool use_ntlmv2, bool use_lanman) if (use_ntlmv2) { DATA_BLOB server_chal; DATA_BLOB names_blob; + const char *netbios_name = NULL; + const char *domain = NULL; + + netbios_name = get_winbind_netbios_name(), + domain = get_winbind_domain(); + if (domain == NULL) { + d_fprintf(stderr, "Failed to get domain from winbindd\n"); + return false; + } server_chal = data_blob(params.password.response.challenge, 8); /* Pretend this is a login to 'us', for blob purposes */ names_blob = NTLMv2_generate_names_blob(NULL, - get_winbind_netbios_name(), - get_winbind_domain()); + netbios_name, + domain); if (pass != NULL && !SMBNTLMv2encrypt(NULL, name_user, name_domain, pass, -- 2.13.6 From 73f6df0a1c3362330cc7b11899b3c179dafccbce Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jan 2018 23:19:32 +0100 Subject: [PATCH 24/41] winbindd: add_trusted_domain_from_auth() should not use dns_name = "" Check whether the DNS domain name in the info6 struct is actually more then just an empty string. If it is we want to call add_trusted_domain() with NULL as DNS domain name argument. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13257 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 2ee2551409e0bd0cd5bf130cc1e3736e58b8c14d) --- source3/winbindd/winbindd_util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 5f4f905db4c..6292cce9d51 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -336,7 +336,9 @@ bool add_trusted_domain_from_auth(uint16_t validation_level, } if (validation_level == 6) { - dns_domainname = &info6->dns_domainname[0]; + if (!strequal(info6->dns_domainname, "")) { + dns_domainname = info6->dns_domainname; + } } status = add_trusted_domain(info3->logon_dom, -- 2.13.6 From 6a3c4d27870e452731348c079b738fdc9ab56126 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Feb 2018 16:15:18 +0100 Subject: [PATCH 25/41] s3/rpc_client: add rpccli_netlogon_interactive_logon() This will be used in a subsequent commit. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13258 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit be26a472ae082d612f9aec28c932d25e2317f9ba) --- source3/rpc_client/cli_netlogon.c | 112 ++++++++++++++++++++++++++++++++++++++ source3/rpc_client/cli_netlogon.h | 15 +++++ 2 files changed, 127 insertions(+) diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index d8ccce72e0d..2aa0f5e7b1c 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -701,3 +701,115 @@ NTSTATUS rpccli_netlogon_network_logon( return NT_STATUS_OK; } + +NTSTATUS rpccli_netlogon_interactive_logon( + struct netlogon_creds_cli_context *creds_ctx, + struct dcerpc_binding_handle *binding_handle, + TALLOC_CTX *mem_ctx, + uint32_t logon_parameters, + const char *username, + const char *domain, + const char *workstation, + DATA_BLOB lm_hash, + DATA_BLOB nt_hash, + enum netr_LogonInfoClass logon_type, + uint8_t *authoritative, + uint32_t *flags, + uint16_t *_validation_level, + union netr_Validation **_validation) +{ + TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS status; + const char *workstation_name_slash; + union netr_LogonLevel *logon = NULL; + struct netr_PasswordInfo *password_info = NULL; + uint16_t validation_level = 0; + union netr_Validation *validation = NULL; + struct netr_ChallengeResponse lm; + struct netr_ChallengeResponse nt; + + *_validation = NULL; + + ZERO_STRUCT(lm); + ZERO_STRUCT(nt); + + switch (logon_type) { + case NetlogonInteractiveInformation: + case NetlogonInteractiveTransitiveInformation: + break; + default: + DEBUG(0, ("switch value %d not supported\n", + logon_type)); + TALLOC_FREE(frame); + return NT_STATUS_INVALID_INFO_CLASS; + } + + logon = talloc_zero(mem_ctx, union netr_LogonLevel); + if (logon == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + + password_info = talloc_zero(logon, struct netr_PasswordInfo); + if (password_info == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + + if (workstation[0] != '\\' && workstation[1] != '\\') { + workstation_name_slash = talloc_asprintf(frame, "\\\\%s", workstation); + } else { + workstation_name_slash = workstation; + } + + if (workstation_name_slash == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + + /* Initialise input parameters */ + + password_info->identity_info.domain_name.string = domain; + password_info->identity_info.parameter_control = logon_parameters; + password_info->identity_info.logon_id_low = 0xdead; + password_info->identity_info.logon_id_high = 0xbeef; + password_info->identity_info.account_name.string = username; + password_info->identity_info.workstation.string = workstation_name_slash; + + if (nt_hash.length != sizeof(password_info->ntpassword.hash)) { + TALLOC_FREE(frame); + return NT_STATUS_INVALID_PARAMETER; + } + memcpy(password_info->ntpassword.hash, nt_hash.data, nt_hash.length); + if (lm_hash.length != 0) { + if (lm_hash.length != sizeof(password_info->lmpassword.hash)) { + TALLOC_FREE(frame); + return NT_STATUS_INVALID_PARAMETER; + } + memcpy(password_info->lmpassword.hash, lm_hash.data, lm_hash.length); + } + + logon->password = password_info; + + /* Marshall data and send request */ + + status = netlogon_creds_cli_LogonSamLogon(creds_ctx, + binding_handle, + logon_type, + logon, + mem_ctx, + &validation_level, + &validation, + authoritative, + flags); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + *_validation_level = validation_level; + *_validation = validation; + + TALLOC_FREE(frame); + return NT_STATUS_OK; +} diff --git a/source3/rpc_client/cli_netlogon.h b/source3/rpc_client/cli_netlogon.h index dc04c0b0676..d0232b51d98 100644 --- a/source3/rpc_client/cli_netlogon.h +++ b/source3/rpc_client/cli_netlogon.h @@ -89,5 +89,20 @@ NTSTATUS rpccli_netlogon_network_logon( uint32_t *flags, uint16_t *_validation_level, union netr_Validation **_validation); +NTSTATUS rpccli_netlogon_interactive_logon( + struct netlogon_creds_cli_context *creds_ctx, + struct dcerpc_binding_handle *binding_handle, + TALLOC_CTX *mem_ctx, + uint32_t logon_parameters, + const char *username, + const char *domain, + const char *workstation, + DATA_BLOB lm_hash, + DATA_BLOB nt_hash, + enum netr_LogonInfoClass logon_type, + uint8_t *authoritative, + uint32_t *flags, + uint16_t *_validation_level, + union netr_Validation **_validation); #endif /* _RPC_CLIENT_CLI_NETLOGON_H_ */ -- 2.13.6 From c68e26976f63f356f0fa2769bcb5fd2f79fb498c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jan 2018 16:36:45 +0100 Subject: [PATCH 26/41] winbindd: separate plaintext given and interactive in winbind_samlogon_retry_loop() We need to handle 4 cases: plaintext_given=true interactive=true plaintext_given=false interactive=true plaintext_given=true interactive=false plaintext_given=false interactive=false Bug: https://bugzilla.samba.org/show_bug.cgi?id=13258 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit d1c3676197032487505e9069c0655427b5fd385c) --- source3/winbindd/winbindd_pam.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index a14b801cb94..c618b7a1a24 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -1421,6 +1421,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, const char *password, const char *domainname, const char *workstation, + bool plaintext_given, const uint8_t chal[8], DATA_BLOB lm_response, DATA_BLOB nt_response, @@ -1524,7 +1525,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, DBG_NOTICE("No security credentials available for " "domain [%s]\n", domainname); result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - } else if (interactive) { + } else if (plaintext_given) { result = rpccli_netlogon_password_logon( domain->conn.netlogon_creds_ctx, netlogon_pipe->binding_handle, @@ -1539,6 +1540,22 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, flags, &validation_level, &validation); + } else if (interactive) { + result = rpccli_netlogon_interactive_logon( + domain->conn.netlogon_creds_ctx, + netlogon_pipe->binding_handle, + mem_ctx, + logon_parameters, + username, + domainname, + workstation, + lm_response, + nt_response, + logon_type_i, + authoritative, + flags, + &validation_level, + &validation); } else { result = rpccli_netlogon_network_logon( domain->conn.netlogon_creds_ctx, @@ -1745,6 +1762,7 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon( pass, name_domain, lp_netbios_name(), + true, /* plaintext_given */ NULL, data_blob_null, data_blob_null, true, /* interactive */ @@ -2251,6 +2269,7 @@ NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain, name_domain, /* Bug #3248 - found by Stefan Burkei. */ workstation, /* We carefully set this above so use it... */ + false, /* plaintext_given */ chal, lm_response, nt_response, -- 2.13.6 From 396c3c28282872900a5bbf06a03668ad14a29dac Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Feb 2018 17:23:49 +0100 Subject: [PATCH 27/41] winbindd: add a comment to a parameter in _winbind_SamLogon() Bug: https://bugzilla.samba.org/show_bug.cgi?id=13258 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 2268f1c0dd1e8543c126553f80d94e80a1e32487) --- source3/winbindd/winbindd_dual_srv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index c76531ddb5d..2775a1569e1 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -898,7 +898,7 @@ NTSTATUS _winbind_SamLogon(struct pipes_struct *p, r->in.logon.network->challenge, lm_response, nt_response, &r->out.authoritative, - true, + true, /* skip_sam */ &flags, &validation_level, &validation); -- 2.13.6 From a7a39319388f2791ad64a6065426f0ef251d1b2a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jan 2018 17:37:54 +0100 Subject: [PATCH 28/41] winbindd: pass 'bool interactive' to winbind_dual_SamLogon() Bug: https://bugzilla.samba.org/show_bug.cgi?id=13258 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 8c6c47aec0e91ab3944bea5f6eda8072f5db959d) --- source3/winbindd/winbindd_dual_srv.c | 1 + source3/winbindd/winbindd_pam.c | 6 ++++-- source3/winbindd/winbindd_proto.h | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index 2775a1569e1..4ac38ff19d2 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -891,6 +891,7 @@ NTSTATUS _winbind_SamLogon(struct pipes_struct *p, nt_response = data_blob_talloc(p->mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length); status = winbind_dual_SamLogon(domain, p->mem_ctx, + false, /* interactive */ r->in.logon.network->identity_info.parameter_control, r->in.logon.network->identity_info.account_name.string, r->in.logon.network->identity_info.domain_name.string, diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index c618b7a1a24..9cab59dd640 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -2201,6 +2201,7 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, + bool interactive, uint32_t logon_parameters, const char *name_user, const char *name_domain, @@ -2237,7 +2238,7 @@ NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain, logon_parameters, name_domain, name_user, &chal_blob, &lm_response, &nt_response, - false, /* interactive */ + interactive, authoritative, &info3); if (NT_STATUS_IS_OK(result)) { @@ -2273,7 +2274,7 @@ NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain, chal, lm_response, nt_response, - false, /* interactive */ + interactive, authoritative, flags, &validation_level, @@ -2417,6 +2418,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, result = winbind_dual_SamLogon(domain, state->mem_ctx, + false, /* interactive */ state->request->data.auth_crap.logon_parameters, name_user, name_domain, diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 49d44af97ff..568978141c9 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -421,6 +421,7 @@ NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, + bool interactive, uint32_t logon_parameters, const char *name_user, const char *name_domain, -- 2.13.6 From 18e0e55509bc4990f990b1db2daa372f36488974 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jan 2018 17:39:15 +0100 Subject: [PATCH 29/41] winbindd: handle interactive logons in _winbind_SamLogon() Bug: https://bugzilla.samba.org/show_bug.cgi?id=13258 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit d76bcdb0854cff9b08010d47469fd48324d902bc) --- source3/winbindd/winbindd_dual_srv.c | 76 ++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 13 deletions(-) diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index 4ac38ff19d2..4804da91583 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -868,35 +868,85 @@ NTSTATUS _winbind_SamLogon(struct pipes_struct *p, { struct winbindd_domain *domain; NTSTATUS status; + struct netr_IdentityInfo *identity_info = NULL; + const uint8_t chal_zero[8] = {0, }; + const uint8_t *challenge = chal_zero; DATA_BLOB lm_response, nt_response; uint32_t flags = 0; uint16_t validation_level; union netr_Validation *validation = NULL; + bool interactive = false; domain = wb_child_domain(); if (domain == NULL) { return NT_STATUS_REQUEST_NOT_ACCEPTED; } - /* TODO: Handle interactive logons here */ - if (r->in.validation_level != 3 || - r->in.logon.network == NULL || - (r->in.logon_level != NetlogonNetworkInformation - && r->in.logon_level != NetlogonNetworkTransitiveInformation)) { + if (r->in.validation_level != 3) { return NT_STATUS_REQUEST_NOT_ACCEPTED; } + switch (r->in.logon_level) { + case NetlogonInteractiveInformation: + case NetlogonServiceInformation: + case NetlogonInteractiveTransitiveInformation: + case NetlogonServiceTransitiveInformation: + if (r->in.logon.password == NULL) { + return NT_STATUS_REQUEST_NOT_ACCEPTED; + } + + interactive = true; + identity_info = &r->in.logon.password->identity_info; + + challenge = chal_zero; + lm_response = data_blob_talloc(p->mem_ctx, + r->in.logon.password->lmpassword.hash, + sizeof(r->in.logon.password->lmpassword.hash)); + nt_response = data_blob_talloc(p->mem_ctx, + r->in.logon.password->ntpassword.hash, + sizeof(r->in.logon.password->ntpassword.hash)); + break; + + case NetlogonNetworkInformation: + case NetlogonNetworkTransitiveInformation: + if (r->in.logon.network == NULL) { + return NT_STATUS_REQUEST_NOT_ACCEPTED; + } + + interactive = false; + identity_info = &r->in.logon.network->identity_info; + + challenge = r->in.logon.network->challenge; + lm_response = data_blob_talloc(p->mem_ctx, + r->in.logon.network->lm.data, + r->in.logon.network->lm.length); + nt_response = data_blob_talloc(p->mem_ctx, + r->in.logon.network->nt.data, + r->in.logon.network->nt.length); + break; - lm_response = data_blob_talloc(p->mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length); - nt_response = data_blob_talloc(p->mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length); + case NetlogonGenericInformation: + if (r->in.logon.generic == NULL) { + return NT_STATUS_REQUEST_NOT_ACCEPTED; + } + + identity_info = &r->in.logon.generic->identity_info; + /* + * Not implemented here... + */ + return NT_STATUS_REQUEST_NOT_ACCEPTED; + + default: + return NT_STATUS_REQUEST_NOT_ACCEPTED; + } status = winbind_dual_SamLogon(domain, p->mem_ctx, - false, /* interactive */ - r->in.logon.network->identity_info.parameter_control, - r->in.logon.network->identity_info.account_name.string, - r->in.logon.network->identity_info.domain_name.string, - r->in.logon.network->identity_info.workstation.string, - r->in.logon.network->challenge, + interactive, + identity_info->parameter_control, + identity_info->account_name.string, + identity_info->domain_name.string, + identity_info->workstation.string, + challenge, lm_response, nt_response, &r->out.authoritative, true, /* skip_sam */ -- 2.13.6 From 5b5955e196cc6de76ecb473b7e861e89e35ad6fd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 2 Feb 2018 15:24:00 +0100 Subject: [PATCH 30/41] winbindd: introduce a cm_connect_netlogon_secure() which gives a valid netlogon_creds_ctx At lot of callers require a valid schannel connection. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13259 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit b60c634123ee00021efc5b5aaa03e1663474d3da) --- source3/winbindd/winbindd_cm.c | 30 ++++++++++++---- source3/winbindd/winbindd_dual.c | 7 ++-- source3/winbindd/winbindd_dual_srv.c | 69 +++++++++++++++++++++++++----------- source3/winbindd/winbindd_pam.c | 16 ++++----- source3/winbindd/winbindd_proto.h | 3 ++ 5 files changed, 87 insertions(+), 38 deletions(-) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index b7fd981547f..54416e02dcd 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2623,16 +2623,11 @@ static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain, return NT_STATUS_OK; } - result = cm_connect_netlogon(domain, &netlogon_pipe); + result = cm_connect_netlogon_secure(domain, &netlogon_pipe, ppdc); if (!NT_STATUS_IS_OK(result)) { return result; } - if (domain->conn.netlogon_creds_ctx == NULL) { - return NT_STATUS_TRUSTED_DOMAIN_FAILURE; - } - - *ppdc = domain->conn.netlogon_creds_ctx; return NT_STATUS_OK; } @@ -3325,6 +3320,29 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, return status; } +NTSTATUS cm_connect_netlogon_secure(struct winbindd_domain *domain, + struct rpc_pipe_client **cli, + struct netlogon_creds_cli_context **ppdc) +{ + NTSTATUS status; + + if (domain->secure_channel_type == SEC_CHAN_NULL) { + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + + status = cm_connect_netlogon(domain, cli); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (domain->conn.netlogon_creds_ctx == NULL) { + return NT_STATUS_TRUSTED_DOMAIN_FAILURE; + } + + *ppdc = domain->conn.netlogon_creds_ctx; + return NT_STATUS_OK; +} + void winbind_msg_ip_dropped(struct messaging_context *msg_ctx, void *private_data, uint32_t msg_type, diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index a05644d2c34..33f1393e082 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -1055,6 +1055,7 @@ static void machine_password_change_handler(struct tevent_context *ctx, struct winbindd_child *child = (struct winbindd_child *)private_data; struct rpc_pipe_client *netlogon_pipe = NULL; + struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL; NTSTATUS result; struct timeval next_change; @@ -1083,7 +1084,9 @@ static void machine_password_change_handler(struct tevent_context *ctx, return; } - result = cm_connect_netlogon(child->domain, &netlogon_pipe); + result = cm_connect_netlogon_secure(child->domain, + &netlogon_pipe, + &netlogon_creds_ctx); if (!NT_STATUS_IS_OK(result)) { DEBUG(10,("machine_password_change_handler: " "failed to connect netlogon pipe: %s\n", @@ -1091,7 +1094,7 @@ static void machine_password_change_handler(struct tevent_context *ctx, return; } - result = trust_pw_change(child->domain->conn.netlogon_creds_ctx, + result = trust_pw_change(netlogon_creds_ctx, msg_ctx, netlogon_pipe->binding_handle, child->domain->name, diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index 4804da91583..5c12414fd25 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -679,8 +679,11 @@ NTSTATUS _wbint_CheckMachineAccount(struct pipes_struct *p, domain->conn.netlogon_force_reauth = true; { - struct rpc_pipe_client *netlogon_pipe; - status = cm_connect_netlogon(domain, &netlogon_pipe); + struct rpc_pipe_client *netlogon_pipe = NULL; + struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL; + status = cm_connect_netlogon_secure(domain, + &netlogon_pipe, + &netlogon_creds_ctx); } /* There is a race condition between fetching the trust account @@ -721,20 +724,23 @@ NTSTATUS _wbint_ChangeMachineAccount(struct pipes_struct *p, struct messaging_context *msg_ctx = server_messaging_context(); struct winbindd_domain *domain; NTSTATUS status; - struct rpc_pipe_client *netlogon_pipe; + struct rpc_pipe_client *netlogon_pipe = NULL; + struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL; domain = wb_child_domain(); if (domain == NULL) { return NT_STATUS_REQUEST_NOT_ACCEPTED; } - status = cm_connect_netlogon(domain, &netlogon_pipe); + status = cm_connect_netlogon_secure(domain, + &netlogon_pipe, + &netlogon_creds_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("could not open handle to NETLOGON pipe\n")); goto done; } - status = trust_pw_change(domain->conn.netlogon_creds_ctx, + status = trust_pw_change(netlogon_creds_ctx, msg_ctx, netlogon_pipe->binding_handle, domain->name, @@ -830,20 +836,23 @@ NTSTATUS _winbind_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p, { struct winbindd_domain *domain; NTSTATUS status; - struct rpc_pipe_client *netlogon_pipe; + struct rpc_pipe_client *netlogon_pipe = NULL; + struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL; domain = wb_child_domain(); if (domain == NULL) { return NT_STATUS_REQUEST_NOT_ACCEPTED; } - status = cm_connect_netlogon(domain, &netlogon_pipe); + status = cm_connect_netlogon_secure(domain, + &netlogon_pipe, + &netlogon_creds_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("could not open handle to NETLOGON pipe\n")); goto done; } - status = netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords(domain->conn.netlogon_creds_ctx, + status = netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords(netlogon_creds_ctx, netlogon_pipe->binding_handle, r->in.site_name, r->in.dns_ttl, @@ -973,6 +982,7 @@ static WERROR _winbind_LogonControl_REDISCOVER(struct pipes_struct *p, { NTSTATUS status; struct rpc_pipe_client *netlogon_pipe = NULL; + struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL; struct netr_NETLOGON_INFO_2 *info2 = NULL; WERROR check_result = WERR_INTERNAL_ERROR; @@ -993,7 +1003,9 @@ static WERROR _winbind_LogonControl_REDISCOVER(struct pipes_struct *p, */ invalidate_cm_connection(domain); domain->conn.netlogon_force_reauth = true; - status = cm_connect_netlogon(domain, &netlogon_pipe); + status = cm_connect_netlogon_secure(domain, + &netlogon_pipe, + &netlogon_creds_ctx); reset_cm_connection_on_error(domain, status); if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { status = NT_STATUS_NO_LOGON_SERVERS; @@ -1049,6 +1061,7 @@ static WERROR _winbind_LogonControl_TC_QUERY(struct pipes_struct *p, { NTSTATUS status; struct rpc_pipe_client *netlogon_pipe = NULL; + struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL; struct netr_NETLOGON_INFO_2 *info2 = NULL; WERROR check_result = WERR_INTERNAL_ERROR; @@ -1062,7 +1075,9 @@ static WERROR _winbind_LogonControl_TC_QUERY(struct pipes_struct *p, goto check_return; } - status = cm_connect_netlogon(domain, &netlogon_pipe); + status = cm_connect_netlogon_secure(domain, + &netlogon_pipe, + &netlogon_creds_ctx); reset_cm_connection_on_error(domain, status); if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { status = NT_STATUS_NO_LOGON_SERVERS; @@ -1121,6 +1136,7 @@ static WERROR _winbind_LogonControl_TC_VERIFY(struct pipes_struct *p, struct policy_handle local_lsa_policy = {}; struct dcerpc_binding_handle *local_lsa = NULL; struct rpc_pipe_client *netlogon_pipe = NULL; + struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL; struct cli_credentials *creds = NULL; struct samr_Password *cur_nt_hash = NULL; uint32_t trust_attributes = 0; @@ -1241,7 +1257,9 @@ static WERROR _winbind_LogonControl_TC_VERIFY(struct pipes_struct *p, } reconnect: - status = cm_connect_netlogon(domain, &netlogon_pipe); + status = cm_connect_netlogon_secure(domain, + &netlogon_pipe, + &netlogon_creds_ctx); reset_cm_connection_on_error(domain, status); if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { status = NT_STATUS_NO_LOGON_SERVERS; @@ -1261,7 +1279,7 @@ static WERROR _winbind_LogonControl_TC_VERIFY(struct pipes_struct *p, } if (fetch_fti) { - status = netlogon_creds_cli_GetForestTrustInformation(domain->conn.netlogon_creds_ctx, + status = netlogon_creds_cli_GetForestTrustInformation(netlogon_creds_ctx, b, frame, &new_fti); if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) { @@ -1323,7 +1341,7 @@ static WERROR _winbind_LogonControl_TC_VERIFY(struct pipes_struct *p, } } - status = netlogon_creds_cli_ServerGetTrustInfo(domain->conn.netlogon_creds_ctx, + status = netlogon_creds_cli_ServerGetTrustInfo(netlogon_creds_ctx, b, frame, &new_owf_password, &old_owf_password, @@ -1434,7 +1452,8 @@ static WERROR _winbind_LogonControl_CHANGE_PASSWORD(struct pipes_struct *p, { struct messaging_context *msg_ctx = server_messaging_context(); NTSTATUS status; - struct rpc_pipe_client *netlogon_pipe; + struct rpc_pipe_client *netlogon_pipe = NULL; + struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL; struct cli_credentials *creds = NULL; struct samr_Password *cur_nt_hash = NULL; struct netr_NETLOGON_INFO_1 *info1 = NULL; @@ -1461,7 +1480,9 @@ static WERROR _winbind_LogonControl_CHANGE_PASSWORD(struct pipes_struct *p, } reconnect: - status = cm_connect_netlogon(domain, &netlogon_pipe); + status = cm_connect_netlogon_secure(domain, + &netlogon_pipe, + &netlogon_creds_ctx); reset_cm_connection_on_error(domain, status); if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { status = NT_STATUS_NO_LOGON_SERVERS; @@ -1484,7 +1505,7 @@ static WERROR _winbind_LogonControl_CHANGE_PASSWORD(struct pipes_struct *p, } TALLOC_FREE(cur_nt_hash); - status = trust_pw_change(domain->conn.netlogon_creds_ctx, + status = trust_pw_change(netlogon_creds_ctx, msg_ctx, b, domain->name, domain->dcname, true); /* force */ @@ -1567,7 +1588,8 @@ WERROR _winbind_GetForestTrustInformation(struct pipes_struct *p, TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status, result; struct winbindd_domain *domain; - struct rpc_pipe_client *netlogon_pipe; + struct rpc_pipe_client *netlogon_pipe = NULL; + struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL; struct dcerpc_binding_handle *b; bool retry = false; struct lsa_String trusted_domain_name = {}; @@ -1666,7 +1688,9 @@ WERROR _winbind_GetForestTrustInformation(struct pipes_struct *p, } reconnect: - status = cm_connect_netlogon(domain, &netlogon_pipe); + status = cm_connect_netlogon_secure(domain, + &netlogon_pipe, + &netlogon_creds_ctx); reset_cm_connection_on_error(domain, status); if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { status = NT_STATUS_NO_LOGON_SERVERS; @@ -1679,7 +1703,7 @@ WERROR _winbind_GetForestTrustInformation(struct pipes_struct *p, } b = netlogon_pipe->binding_handle; - status = netlogon_creds_cli_GetForestTrustInformation(domain->conn.netlogon_creds_ctx, + status = netlogon_creds_cli_GetForestTrustInformation(netlogon_creds_ctx, b, p->mem_ctx, &new_fti); if (!NT_STATUS_IS_OK(status)) { @@ -1778,6 +1802,7 @@ NTSTATUS _winbind_SendToSam(struct pipes_struct *p, struct winbind_SendToSam *r) struct winbindd_domain *domain; NTSTATUS status; struct rpc_pipe_client *netlogon_pipe; + struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL; DEBUG(5, ("_winbind_SendToSam received\n")); domain = wb_child_domain(); @@ -1785,13 +1810,15 @@ NTSTATUS _winbind_SendToSam(struct pipes_struct *p, struct winbind_SendToSam *r) return NT_STATUS_REQUEST_NOT_ACCEPTED; } - status = cm_connect_netlogon(domain, &netlogon_pipe); + status = cm_connect_netlogon_secure(domain, + &netlogon_pipe, + &netlogon_creds_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("could not open handle to NETLOGON pipe\n")); return status; } - status = netlogon_creds_cli_SendToSam(domain->conn.netlogon_creds_ctx, + status = netlogon_creds_cli_SendToSam(netlogon_creds_ctx, netlogon_pipe->binding_handle, &r->in.message); diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 9cab59dd640..9c598d71855 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -1442,10 +1442,12 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, do { struct rpc_pipe_client *netlogon_pipe; + struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL; retry = false; - result = cm_connect_netlogon(domain, &netlogon_pipe); + result = cm_connect_netlogon_secure(domain, &netlogon_pipe, + &netlogon_creds_ctx); if (NT_STATUS_EQUAL(result, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) { @@ -1521,13 +1523,9 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, } netr_attempts = 0; - if (domain->conn.netlogon_creds_ctx == NULL) { - DBG_NOTICE("No security credentials available for " - "domain [%s]\n", domainname); - result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - } else if (plaintext_given) { + if (plaintext_given) { result = rpccli_netlogon_password_logon( - domain->conn.netlogon_creds_ctx, + netlogon_creds_ctx, netlogon_pipe->binding_handle, mem_ctx, logon_parameters, @@ -1542,7 +1540,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, &validation); } else if (interactive) { result = rpccli_netlogon_interactive_logon( - domain->conn.netlogon_creds_ctx, + netlogon_creds_ctx, netlogon_pipe->binding_handle, mem_ctx, logon_parameters, @@ -1558,7 +1556,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, &validation); } else { result = rpccli_netlogon_network_logon( - domain->conn.netlogon_creds_ctx, + netlogon_creds_ctx, netlogon_pipe->binding_handle, mem_ctx, logon_parameters, diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 568978141c9..015fd717b34 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -210,6 +210,9 @@ NTSTATUS cm_connect_lsat(struct winbindd_domain *domain, struct policy_handle *lsa_policy); NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, struct rpc_pipe_client **cli); +NTSTATUS cm_connect_netlogon_secure(struct winbindd_domain *domain, + struct rpc_pipe_client **cli, + struct netlogon_creds_cli_context **ppdc); bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx, const char *domain_name, char **p_dc_name, char **p_dc_ip); -- 2.13.6 From 77ebc829eecb88980e744079502a75859f997fb1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jan 2018 17:53:49 +0100 Subject: [PATCH 31/41] s3/rpc_client: add copy_netr_SamInfo6() and map_validation_to_info6() Bug: https://bugzilla.samba.org/show_bug.cgi?id=13260 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 60aa5e7657608c1a5519c03e690cce58efd67abd) --- source3/rpc_client/util_netlogon.c | 146 +++++++++++++++++++++++++++++++++++++ source3/rpc_client/util_netlogon.h | 7 ++ 2 files changed, 153 insertions(+) diff --git a/source3/rpc_client/util_netlogon.c b/source3/rpc_client/util_netlogon.c index 15c769ffe41..008861f00d1 100644 --- a/source3/rpc_client/util_netlogon.c +++ b/source3/rpc_client/util_netlogon.c @@ -190,6 +190,152 @@ NTSTATUS map_validation_to_info3(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } +NTSTATUS copy_netr_SamInfo6(TALLOC_CTX *mem_ctx, + const struct netr_SamInfo6 *in, + struct netr_SamInfo6 **pout) +{ + struct netr_SamInfo6 *info6 = NULL; + unsigned int i; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + + info6 = talloc_zero(mem_ctx, struct netr_SamInfo6); + if (info6 == NULL) { + status = NT_STATUS_NO_MEMORY; + goto out; + } + + status = copy_netr_SamBaseInfo(info6, &in->base, &info6->base); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + if (in->sidcount) { + info6->sidcount = in->sidcount; + info6->sids = talloc_array(info6, struct netr_SidAttr, + in->sidcount); + if (info6->sids == NULL) { + status = NT_STATUS_NO_MEMORY; + goto out; + } + + for (i = 0; i < in->sidcount; i++) { + info6->sids[i].sid = dom_sid_dup(info6->sids, + in->sids[i].sid); + if (info6->sids[i].sid == NULL) { + status = NT_STATUS_NO_MEMORY; + goto out; + } + info6->sids[i].attributes = in->sids[i].attributes; + } + } + + if (in->dns_domainname.string != NULL) { + info6->dns_domainname.string = talloc_strdup(info6, + in->dns_domainname.string); + if (info6->dns_domainname.string == NULL) { + status = NT_STATUS_NO_MEMORY; + goto out; + } + } + + if (in->principal_name.string != NULL) { + info6->principal_name.string = talloc_strdup(info6, + in->principal_name.string); + if (info6->principal_name.string == NULL) { + status = NT_STATUS_NO_MEMORY; + goto out; + } + } + + *pout = info6; + info6 = NULL; + + status = NT_STATUS_OK; +out: + TALLOC_FREE(info6); + return status; +} + +NTSTATUS map_validation_to_info6(TALLOC_CTX *mem_ctx, + uint16_t validation_level, + union netr_Validation *validation, + struct netr_SamInfo6 **info6_p) +{ + struct netr_SamInfo3 *info3 = NULL; + struct netr_SamInfo6 *info6 = NULL; + NTSTATUS status; + + if (validation == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + switch (validation_level) { + case 3: + if (validation->sam3 == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + info3 = validation->sam3; + + info6 = talloc_zero(mem_ctx, struct netr_SamInfo6); + if (info6 == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = copy_netr_SamBaseInfo(info6, + &info3->base, + &info6->base); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(info6); + return status; + } + + if (validation->sam3->sidcount > 0) { + int i; + + info6->sidcount = info3->sidcount; + + info6->sids = talloc_array(info6, + struct netr_SidAttr, + info6->sidcount); + if (info6->sids == NULL) { + TALLOC_FREE(info6); + return NT_STATUS_NO_MEMORY; + } + + for (i = 0; i < info6->sidcount; i++) { + info6->sids[i].sid = dom_sid_dup( + info6->sids, info3->sids[i].sid); + if (info6->sids[i].sid == NULL) { + TALLOC_FREE(info6); + return NT_STATUS_NO_MEMORY; + } + info6->sids[i].attributes = + info3->sids[i].attributes; + } + } + break; + case 6: + if (validation->sam6 == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + status = copy_netr_SamInfo6(mem_ctx, + validation->sam6, + &info6); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + break; + default: + return NT_STATUS_BAD_VALIDATION_CLASS; + } + + *info6_p = info6; + + return NT_STATUS_OK; +} + NTSTATUS map_info3_to_validation(TALLOC_CTX *mem_ctx, struct netr_SamInfo3 *info3, uint16_t *_validation_level, diff --git a/source3/rpc_client/util_netlogon.h b/source3/rpc_client/util_netlogon.h index 8b3a372ee8e..fc1da1face3 100644 --- a/source3/rpc_client/util_netlogon.h +++ b/source3/rpc_client/util_netlogon.h @@ -32,6 +32,13 @@ NTSTATUS map_validation_to_info3(TALLOC_CTX *mem_ctx, uint16_t validation_level, union netr_Validation *validation, struct netr_SamInfo3 **info3_p); +NTSTATUS copy_netr_SamInfo6(TALLOC_CTX *mem_ctx, + const struct netr_SamInfo6 *in, + struct netr_SamInfo6 **pout); +NTSTATUS map_validation_to_info6(TALLOC_CTX *mem_ctx, + uint16_t validation_level, + union netr_Validation *validation, + struct netr_SamInfo6 **info6_p); NTSTATUS map_info3_to_validation(TALLOC_CTX *mem_ctx, struct netr_SamInfo3 *info3, uint16_t *_validation_level, -- 2.13.6 From 6dff19099f0b6d08d574d428e7e292b7598832c3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jan 2018 17:57:37 +0100 Subject: [PATCH 32/41] winbindd: allow validation level 6 in winbind_SamLogon Bug: https://bugzilla.samba.org/show_bug.cgi?id=13260 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 1a9857369d2fae08fefef613cf6cbd3354092a4a) --- source3/winbindd/winbindd_dual_srv.c | 38 +++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index 5c12414fd25..66b4ee82a25 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -891,7 +891,11 @@ NTSTATUS _winbind_SamLogon(struct pipes_struct *p, return NT_STATUS_REQUEST_NOT_ACCEPTED; } - if (r->in.validation_level != 3) { + switch (r->in.validation_level) { + case 3: + case 6: + break; + default: return NT_STATUS_REQUEST_NOT_ACCEPTED; } @@ -965,15 +969,31 @@ NTSTATUS _winbind_SamLogon(struct pipes_struct *p, if (!NT_STATUS_IS_OK(status)) { return status; } - status = map_validation_to_info3(p->mem_ctx, - validation_level, - validation, - &r->out.validation.sam3); - TALLOC_FREE(validation); - if (!NT_STATUS_IS_OK(status)) { - return status; + switch (r->in.validation_level) { + case 3: + status = map_validation_to_info3(p->mem_ctx, + validation_level, + validation, + &r->out.validation.sam3); + TALLOC_FREE(validation); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + return NT_STATUS_OK; + case 6: + status = map_validation_to_info6(p->mem_ctx, + validation_level, + validation, + &r->out.validation.sam6); + TALLOC_FREE(validation); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + return NT_STATUS_OK; } - return NT_STATUS_OK; + + smb_panic(__location__); + return NT_STATUS_INTERNAL_ERROR; } static WERROR _winbind_LogonControl_REDISCOVER(struct pipes_struct *p, -- 2.13.6 From caa6ca22047cb21be35f8200c813ca81c53fdbc8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jan 2018 17:58:07 +0100 Subject: [PATCH 33/41] s4/auth_winbind: ask for validation level 6 Bug: https://bugzilla.samba.org/show_bug.cgi?id=13260 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit e1ba81996033e7c2cfeba13124ee7f404ded2031) --- source4/auth/ntlm/auth_winbind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/auth/ntlm/auth_winbind.c b/source4/auth/ntlm/auth_winbind.c index e887d5ea06d..2e885638ebe 100644 --- a/source4/auth/ntlm/auth_winbind.c +++ b/source4/auth/ntlm/auth_winbind.c @@ -176,7 +176,7 @@ static struct tevent_req *winbind_check_password_send(TALLOC_CTX *mem_ctx, identity_info->account_name.string = user_info->client.account_name; identity_info->workstation.string = user_info->workstation_name; - state->req.in.validation_level = 3; + state->req.in.validation_level = 6; subreq = dcerpc_winbind_SamLogon_r_send(state, ev, irpc_handle, &state->req); -- 2.13.6 From 0145de02907534366c940d4a43def31c74fa58fa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jan 2018 21:32:25 +0100 Subject: [PATCH 34/41] s3/auth: add create_info6_from_pac() Bug: https://bugzilla.samba.org/show_bug.cgi?id=13261 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit d4ba23fd353ad387a374a5d7f6f6d085a0699d2c) --- source3/auth/proto.h | 4 ++++ source3/auth/server_info.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/source3/auth/proto.h b/source3/auth/proto.h index e7746701022..ca851c21d4b 100644 --- a/source3/auth/proto.h +++ b/source3/auth/proto.h @@ -312,6 +312,10 @@ NTSTATUS serverinfo_to_SamInfo6(struct auth_serversupplied_info *server_info, NTSTATUS create_info3_from_pac_logon_info(TALLOC_CTX *mem_ctx, const struct PAC_LOGON_INFO *logon_info, struct netr_SamInfo3 **pp_info3); +NTSTATUS create_info6_from_pac(TALLOC_CTX *mem_ctx, + const struct PAC_LOGON_INFO *logon_info, + const struct PAC_UPN_DNS_INFO *upn_dns_info, + struct netr_SamInfo6 **pp_info6); NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx, struct samu *samu, const char *login_server, diff --git a/source3/auth/server_info.c b/source3/auth/server_info.c index 78981751286..339cce6c4ec 100644 --- a/source3/auth/server_info.c +++ b/source3/auth/server_info.c @@ -363,6 +363,62 @@ NTSTATUS create_info3_from_pac_logon_info(TALLOC_CTX *mem_ctx, } /* + * Create a copy of an info6 struct from the PAC_UPN_DNS_INFO and PAC_LOGON_INFO + * then merge resource SIDs, if any, into it. If successful return the created + * info6 struct. + */ +NTSTATUS create_info6_from_pac(TALLOC_CTX *mem_ctx, + const struct PAC_LOGON_INFO *logon_info, + const struct PAC_UPN_DNS_INFO *upn_dns_info, + struct netr_SamInfo6 **pp_info6) +{ + NTSTATUS status; + struct netr_SamInfo6 *info6 = NULL; + struct netr_SamInfo3 *info3 = NULL; + + info6 = talloc_zero(mem_ctx, struct netr_SamInfo6); + if (info6 == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = copy_netr_SamInfo3(info6, + &logon_info->info3, + &info3); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(info6); + return status; + } + + status = merge_resource_sids(logon_info, info3); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(info6); + return status; + } + + info6->base = info3->base; + info6->sids = info3->sids; + info6->sidcount = info3->sidcount; + + if (upn_dns_info != NULL) { + info6->dns_domainname.string = talloc_strdup(info6, + upn_dns_info->dns_domain_name); + if (info6->dns_domainname.string == NULL) { + TALLOC_FREE(info6); + return NT_STATUS_NO_MEMORY; + } + info6->principal_name.string = talloc_strdup(info6, + upn_dns_info->upn_name); + if (info6->principal_name.string == NULL) { + TALLOC_FREE(info6); + return NT_STATUS_NO_MEMORY; + } + } + + *pp_info6 = info6; + return NT_STATUS_OK; +} + +/* * Check if this is a "Unix Users" domain user, or a * "Unix Groups" domain group, we need to handle it * in a special way if that's the case. -- 2.13.6 From 5517929d814ea5ec7304fe78fbdf0f378b7568cc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jan 2018 21:32:53 +0100 Subject: [PATCH 35/41] s3/rpc_client: add map_info6_to_validation() Bug: https://bugzilla.samba.org/show_bug.cgi?id=13261 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 2b0181877806f171eee053c246dcb2eda2300261) --- source3/rpc_client/util_netlogon.c | 25 +++++++++++++++++++++++++ source3/rpc_client/util_netlogon.h | 4 ++++ 2 files changed, 29 insertions(+) diff --git a/source3/rpc_client/util_netlogon.c b/source3/rpc_client/util_netlogon.c index 008861f00d1..2d73bc95cea 100644 --- a/source3/rpc_client/util_netlogon.c +++ b/source3/rpc_client/util_netlogon.c @@ -360,3 +360,28 @@ NTSTATUS map_info3_to_validation(TALLOC_CTX *mem_ctx, *_validation = validation; return NT_STATUS_OK; } + +NTSTATUS map_info6_to_validation(TALLOC_CTX *mem_ctx, + const struct netr_SamInfo6 *info6, + uint16_t *_validation_level, + union netr_Validation **_validation) +{ + union netr_Validation *validation = NULL; + NTSTATUS status; + + validation = talloc_zero(mem_ctx, union netr_Validation); + if (validation == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = copy_netr_SamInfo6(mem_ctx, + info6, + &validation->sam6); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + * _validation_level = 6; + *_validation = validation; + return NT_STATUS_OK; +} diff --git a/source3/rpc_client/util_netlogon.h b/source3/rpc_client/util_netlogon.h index fc1da1face3..c3ed3f67201 100644 --- a/source3/rpc_client/util_netlogon.h +++ b/source3/rpc_client/util_netlogon.h @@ -43,5 +43,9 @@ NTSTATUS map_info3_to_validation(TALLOC_CTX *mem_ctx, struct netr_SamInfo3 *info3, uint16_t *_validation_level, union netr_Validation **_validation); +NTSTATUS map_info6_to_validation(TALLOC_CTX *mem_ctx, + const struct netr_SamInfo6 *info6, + uint16_t *_validation_level, + union netr_Validation **_validation); #endif /* _RPC_CLIENT_UTIL_NETLOGON_H_ */ -- 2.13.6 From a20d2bfe77549ecddd0f3db8f2dccb8d8ceeeb2f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jan 2018 21:34:46 +0100 Subject: [PATCH 36/41] winbindd: get netr_SamInfo6 out of winbindd_dual_pam_auth_kerberos() This way we don't loose dns_domain_name and user principal. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13261 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 021d75fb223630d06a256a605659abda9ece853f) --- source3/winbindd/winbindd_pam.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 9c598d71855..1e6cfb9736f 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -635,7 +635,7 @@ static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx, const char *pass, const char *krb5_cc_type, uid_t uid, - struct netr_SamInfo3 **info3, + struct netr_SamInfo6 **info6, fstring krb5ccname) { #ifdef HAVE_KRB5 @@ -652,13 +652,14 @@ static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx, time_t time_offset = 0; const char *user_ccache_file; struct PAC_LOGON_INFO *logon_info = NULL; + struct PAC_UPN_DNS_INFO *upn_dns_info = NULL; struct PAC_DATA *pac_data = NULL; struct PAC_DATA_CTR *pac_data_ctr = NULL; const char *local_service; uint32_t i; - struct netr_SamInfo3 *info3_copy = NULL; + struct netr_SamInfo6 *info6_copy = NULL; - *info3 = NULL; + *info6 = NULL; if (domain->alt_name == NULL) { return NT_STATUS_INVALID_PARAMETER; @@ -764,16 +765,15 @@ static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx, for (i=0; i < pac_data->num_buffers; i++) { - if (pac_data->buffers[i].type != PAC_TYPE_LOGON_INFO) { + if (pac_data->buffers[i].type == PAC_TYPE_LOGON_INFO) { + logon_info = pac_data->buffers[i].info->logon_info.info; continue; } - logon_info = pac_data->buffers[i].info->logon_info.info; - if (!logon_info) { - return NT_STATUS_INVALID_PARAMETER; + if (pac_data->buffers[i].type == PAC_TYPE_UPN_DNS_INFO) { + upn_dns_info = &pac_data->buffers[i].info->upn_dns_info; + continue; } - - break; } if (logon_info == NULL) { @@ -785,7 +785,8 @@ static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx, DEBUG(10,("winbindd_raw_kerberos_login: winbindd validated ticket of %s\n", principal_s)); - result = create_info3_from_pac_logon_info(mem_ctx, logon_info, &info3_copy); + result = create_info6_from_pac(mem_ctx, logon_info, + upn_dns_info, &info6_copy); if (!NT_STATUS_IS_OK(result)) { goto failed; } @@ -825,7 +826,7 @@ static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx, } } - *info3 = info3_copy; + *info6 = info6_copy; return NT_STATUS_OK; failed: @@ -1240,7 +1241,7 @@ static NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, static NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain, struct winbindd_cli_state *state, - struct netr_SamInfo3 **info3) + struct netr_SamInfo6 **info6) { struct winbindd_domain *contact_domain; fstring name_domain, name_user; @@ -1299,7 +1300,7 @@ static NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain, state->request->data.auth.pass, state->request->data.auth.krb5_cc_type, get_uid_from_request(state->request), - info3, state->response->data.auth.krb5ccname); + info6, state->response->data.auth.krb5ccname); done: return result; } @@ -1928,23 +1929,22 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, /* Check for Kerberos authentication */ if (domain->online && (state->request->flags & WBFLAG_PAM_KRB5)) { - struct netr_SamInfo3 *info3 = NULL; + struct netr_SamInfo6 *info6 = NULL; - result = winbindd_dual_pam_auth_kerberos(domain, state, &info3); + result = winbindd_dual_pam_auth_kerberos(domain, state, &info6); /* save for later */ krb5_result = result; - if (NT_STATUS_IS_OK(result)) { DEBUG(10,("winbindd_dual_pam_auth_kerberos succeeded\n")); - result = map_info3_to_validation(state->mem_ctx, - info3, + result = map_info6_to_validation(state->mem_ctx, + info6, &validation_level, &validation); - TALLOC_FREE(info3); + TALLOC_FREE(info6); if (!NT_STATUS_IS_OK(result)) { - DBG_ERR("map_info3_to_validation failed\n"); + DBG_ERR("map_info6_to_validation failed\n"); goto done; } goto process_result; -- 2.13.6 From 587e088b3768a4614e3258080e8f71fc40f81ead Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jan 2018 22:00:35 +0100 Subject: [PATCH 37/41] winbindd: call add_trusted_domain_from_auth() in winbindd_pam_auth_crap_done() Bug: https://bugzilla.samba.org/show_bug.cgi?id=13262 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 42e445396881c5b6651a0dde0abde3d6bb0740bf) --- source3/winbindd/winbindd_pam_auth_crap.c | 33 ++++++++++++++++--------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/source3/winbindd/winbindd_pam_auth_crap.c b/source3/winbindd/winbindd_pam_auth_crap.c index eb4087b1c2c..fe0ce4ade62 100644 --- a/source3/winbindd/winbindd_pam_auth_crap.c +++ b/source3/winbindd/winbindd_pam_auth_crap.c @@ -119,6 +119,23 @@ static void winbindd_pam_auth_crap_done(struct tevent_req *subreq) tevent_req_nterror(req, map_nt_error_from_unix(err)); return; } + + if (NT_STATUS_IS_OK(NT_STATUS(state->response->data.auth.nt_status)) && + (state->flags & WBFLAG_PAM_INFO3_TEXT)) + { + bool ok; + + ok = add_trusted_domain_from_auth( + state->response->data.auth.validation_level, + &state->response->data.auth.info3, + &state->response->data.auth.info6); + if (!ok) { + DBG_ERR("add_trusted_domain_from_auth failed\n"); + tevent_req_nterror(req, NT_STATUS_LOGON_FAILURE); + return; + } + } + tevent_req_done(req); } @@ -157,22 +174,6 @@ NTSTATUS winbindd_pam_auth_crap_recv(struct tevent_req *req, } - if (NT_STATUS_IS_OK(NT_STATUS(state->response->data.auth.nt_status)) && - (state->flags & WBFLAG_PAM_INFO3_TEXT)) - { - bool ok; - - ok = add_trusted_domain_from_auth( - state->response->data.auth.validation_level, - &state->response->data.auth.info3, - &state->response->data.auth.info6); - if (!ok) { - DBG_ERR("add_trusted_domain_from_auth failed\n"); - set_auth_errors(response, NT_STATUS_LOGON_FAILURE); - return NT_STATUS_LOGON_FAILURE; - } - } - *response = *state->response; response->result = WINBINDD_PENDING; state->response = talloc_move(response, &state->response); -- 2.13.6 From 3e6649e990689332697abf654bea30bc88584ac8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jan 2018 23:02:26 +0100 Subject: [PATCH 38/41] winbindd: let winbindd_pam_auth_pac_send() compute info6 from PAC This way we don't loose the DNS info and UPN. A subsequent commit will let winbindd_pam_auth_pac_send() return the full validation info. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13262 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 5ce3cb2fb468d8798980b49d84568782becf25ea) --- source3/winbindd/winbindd_pam.c | 108 +++++++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 40 deletions(-) diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 1e6cfb9736f..f186d865f56 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -2823,7 +2823,7 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai #ifdef HAVE_KRB5 static NTSTATUS extract_pac_vrfy_sigs(TALLOC_CTX *mem_ctx, DATA_BLOB pac_blob, - struct PAC_LOGON_INFO **logon_info) + struct PAC_DATA **p_pac_data) { krb5_context krbctx = NULL; krb5_error_code k5ret; @@ -2861,10 +2861,14 @@ static NTSTATUS extract_pac_vrfy_sigs(TALLOC_CTX *mem_ctx, DATA_BLOB pac_blob, k5ret = krb5_kt_next_entry(krbctx, keytab, &entry, &cursor); while (k5ret == 0) { - status = kerberos_pac_logon_info(mem_ctx, pac_blob, - krbctx, NULL, - KRB5_KT_KEY(&entry), NULL, 0, - logon_info); + status = kerberos_decode_pac(mem_ctx, + pac_blob, + krbctx, + NULL, /* krbtgt_keyblock */ + KRB5_KT_KEY(&entry), /* service_keyblock */ + NULL, /* client_principal */ + 0, /* tgs_authtime */ + p_pac_data); if (NT_STATUS_IS_OK(status)) { break; } @@ -2894,20 +2898,75 @@ NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, { struct winbindd_request *req = state->request; DATA_BLOB pac_blob; + struct PAC_DATA *pac_data = NULL; struct PAC_LOGON_INFO *logon_info = NULL; + struct PAC_UPN_DNS_INFO *upn_dns_info = NULL; + struct netr_SamInfo6 *info6 = NULL; + uint16_t validation_level = 0; + union netr_Validation *validation = NULL; struct netr_SamInfo3 *info3_copy = NULL; NTSTATUS result; + bool is_trusted = false; + uint32_t i; pac_blob = data_blob_const(req->extra_data.data, req->extra_len); - result = extract_pac_vrfy_sigs(state->mem_ctx, pac_blob, &logon_info); - if (!NT_STATUS_IS_OK(result) && - !NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) { + result = extract_pac_vrfy_sigs(state->mem_ctx, pac_blob, &pac_data); + if (NT_STATUS_IS_OK(result)) { + is_trusted = true; + } + if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) { + /* Try without signature verification */ + result = kerberos_decode_pac(state->mem_ctx, + pac_blob, + NULL, /* krb5_context */ + NULL, /* krbtgt_keyblock */ + NULL, /* service_keyblock */ + NULL, /* client_principal */ + 0, /* tgs_authtime */ + &pac_data); + } + if (!NT_STATUS_IS_OK(result)) { DEBUG(1, ("Error during PAC signature verification: %s\n", nt_errstr(result))); return result; } - if (logon_info) { + for (i=0; i < pac_data->num_buffers; i++) { + if (pac_data->buffers[i].type == PAC_TYPE_LOGON_INFO) { + logon_info = pac_data->buffers[i].info->logon_info.info; + continue; + } + if (pac_data->buffers[i].type == PAC_TYPE_UPN_DNS_INFO) { + upn_dns_info = &pac_data->buffers[i].info->upn_dns_info; + continue; + } + } + + result = create_info6_from_pac(state->mem_ctx, + logon_info, + upn_dns_info, + &info6); + if (!NT_STATUS_IS_OK(result)) { + return result; + } + + result = map_info6_to_validation(state->mem_ctx, + info6, + &validation_level, + &validation); + if (!NT_STATUS_IS_OK(result)) { + return result; + } + + result = map_validation_to_info3(state->mem_ctx, + validation_level, + validation, + &info3_copy); + if (!NT_STATUS_IS_OK(result)) { + return result; + } + + if (is_trusted) { /* * Signature verification succeeded, we can * trust the PAC and prime the netsamlogon @@ -2917,12 +2976,6 @@ NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, */ struct winbindd_domain *domain = NULL; - result = create_info3_from_pac_logon_info(state->mem_ctx, - logon_info, - &info3_copy); - if (!NT_STATUS_IS_OK(result)) { - return result; - } netsamlogon_cache_store(NULL, info3_copy); /* @@ -2949,31 +3002,6 @@ NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, info3_copy->base.account_name.string, sid_string_dbg(&user_sid)); } - - } else { - /* Try without signature verification */ - result = kerberos_pac_logon_info(state->mem_ctx, pac_blob, NULL, - NULL, NULL, NULL, 0, - &logon_info); - if (!NT_STATUS_IS_OK(result)) { - DEBUG(10, ("Could not extract PAC: %s\n", - nt_errstr(result))); - return result; - } - if (logon_info) { - /* - * Don't strictly need to copy here, - * but it makes it explicit we're - * returning a copy talloc'ed off - * the state->mem_ctx. - */ - result = copy_netr_SamInfo3(state->mem_ctx, - &logon_info->info3, - &info3_copy); - if (!NT_STATUS_IS_OK(result)) { - return result; - } - } } *info3 = info3_copy; -- 2.13.6 From 5ec28508c25b95e5c26443dee2576f4c591acfa2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jan 2018 23:10:42 +0100 Subject: [PATCH 39/41] winbindd: complete WBFLAG_PAM_AUTH_PAC handling in winbindd_pam_auth_crap_send() winbindd_pam_auth_crap_recv() should not have any real logic. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13262 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 5444cc4e7ed8ea0c063110f3b78f360d91b0b0a5) --- source3/winbindd/winbindd_pam_auth_crap.c | 64 ++++++++++++++++--------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/source3/winbindd/winbindd_pam_auth_crap.c b/source3/winbindd/winbindd_pam_auth_crap.c index fe0ce4ade62..afcce03172e 100644 --- a/source3/winbindd/winbindd_pam_auth_crap.c +++ b/source3/winbindd/winbindd_pam_auth_crap.c @@ -24,7 +24,6 @@ struct winbindd_pam_auth_crap_state { struct winbindd_response *response; - struct netr_SamInfo3 *info3; uint32_t flags; }; @@ -50,16 +49,44 @@ struct tevent_req *winbindd_pam_auth_crap_send( state->flags = request->flags; if (state->flags & WBFLAG_PAM_AUTH_PAC) { + struct netr_SamInfo3 *info3 = NULL; + uint16_t validation_level; + union netr_Validation *validation = NULL; NTSTATUS status; - status = winbindd_pam_auth_pac_send(cli, &state->info3); - if (NT_STATUS_IS_OK(status)) { - /* Defer filling out response to recv */ - tevent_req_done(req); - } else { - tevent_req_nterror(req, status); + status = winbindd_pam_auth_pac_send(cli, &info3); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + state->response = talloc_zero(state, + struct winbindd_response); + if (tevent_req_nomem(state->response, req)) { + return tevent_req_post(req, ev); } + state->response->result = WINBINDD_PENDING; + state->response->length = sizeof(struct winbindd_response); + status = map_info3_to_validation(talloc_tos(), + info3, + &validation_level, + &validation); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + status = append_auth_data(state->response, + state->response, + state->flags, + validation_level, + validation, + NULL, NULL); + TALLOC_FREE(validation); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + tevent_req_done(req); return tevent_req_post(req, ev); } @@ -151,29 +178,6 @@ NTSTATUS winbindd_pam_auth_crap_recv(struct tevent_req *req, return status; } - if (state->flags & WBFLAG_PAM_AUTH_PAC) { - uint16_t validation_level; - union netr_Validation *validation = NULL; - - status = map_info3_to_validation(talloc_tos(), - state->info3, - &validation_level, - &validation); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = append_auth_data(response, - response, - state->flags, - validation_level, - validation, - NULL, NULL); - TALLOC_FREE(validation); - return status; - - } - *response = *state->response; response->result = WINBINDD_PENDING; state->response = talloc_move(response, &state->response); -- 2.13.6 From dd7771b026cf9de3c1b25240c8c95d521fa5023f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Feb 2018 08:38:18 +0100 Subject: [PATCH 40/41] winbindd: rename winbindd_pam_auth_pac_send and let it return validation Just a preperational step. The next commit will update the caller to make use of the validation info. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13262 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit 8422c001bec169a73657b1d638ec8ec4c35c243a) --- source3/winbindd/winbindd_pam.c | 25 +++++++++++++++++++------ source3/winbindd/winbindd_pam_auth_crap.c | 15 +++++---------- source3/winbindd/winbindd_proto.h | 6 ++++-- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index f186d865f56..8403d7d57b6 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -2893,8 +2893,10 @@ static NTSTATUS extract_pac_vrfy_sigs(TALLOC_CTX *mem_ctx, DATA_BLOB pac_blob, return status; } -NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, - struct netr_SamInfo3 **info3) +NTSTATUS winbindd_pam_auth_pac_verify(struct winbindd_cli_state *state, + bool *p_is_trusted, + uint16_t *p_validation_level, + union netr_Validation **p_validation) { struct winbindd_request *req = state->request; DATA_BLOB pac_blob; @@ -2909,6 +2911,10 @@ NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, bool is_trusted = false; uint32_t i; + *p_is_trusted = false; + *p_validation_level = 0; + *p_validation = NULL; + pac_blob = data_blob_const(req->extra_data.data, req->extra_len); result = extract_pac_vrfy_sigs(state->mem_ctx, pac_blob, &pac_data); if (NT_STATUS_IS_OK(result)) { @@ -3004,14 +3010,21 @@ NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, } } - *info3 = info3_copy; - + *p_is_trusted = is_trusted; + *p_validation_level = validation_level; + *p_validation = validation; return NT_STATUS_OK; } #else /* HAVE_KRB5 */ -NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, - struct netr_SamInfo3 **info3) +NTSTATUS winbindd_pam_auth_pac_verify(struct winbindd_cli_state *state, + bool *p_is_trusted, + uint16_t *p_validation_level, + union netr_Validation **p_validation); { + + *p_is_trusted = false; + *p_validation_level = 0; + *p_validation = NULL; return NT_STATUS_NO_SUCH_USER; } #endif /* HAVE_KRB5 */ diff --git a/source3/winbindd/winbindd_pam_auth_crap.c b/source3/winbindd/winbindd_pam_auth_crap.c index afcce03172e..6fb65a27461 100644 --- a/source3/winbindd/winbindd_pam_auth_crap.c +++ b/source3/winbindd/winbindd_pam_auth_crap.c @@ -49,12 +49,15 @@ struct tevent_req *winbindd_pam_auth_crap_send( state->flags = request->flags; if (state->flags & WBFLAG_PAM_AUTH_PAC) { - struct netr_SamInfo3 *info3 = NULL; + bool is_trusted = false; uint16_t validation_level; union netr_Validation *validation = NULL; NTSTATUS status; - status = winbindd_pam_auth_pac_send(cli, &info3); + status = winbindd_pam_auth_pac_verify(cli, + &is_trusted, + &validation_level, + &validation); if (tevent_req_nterror(req, status)) { return tevent_req_post(req, ev); } @@ -67,14 +70,6 @@ struct tevent_req *winbindd_pam_auth_crap_send( state->response->result = WINBINDD_PENDING; state->response->length = sizeof(struct winbindd_response); - status = map_info3_to_validation(talloc_tos(), - info3, - &validation_level, - &validation); - if (tevent_req_nterror(req, status)) { - return tevent_req_post(req, ev); - } - status = append_auth_data(state->response, state->response, state->flags, diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 015fd717b34..d09176d954a 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -419,8 +419,10 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain, struct winbindd_cli_state *state) ; enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state); -NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, - struct netr_SamInfo3 **info3); +NTSTATUS winbindd_pam_auth_pac_verify(struct winbindd_cli_state *state, + bool *p_is_trusted, + uint16_t *p_validation_level, + union netr_Validation **p_validation); NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, -- 2.13.6 From 8751c18c24bbe4c2de6b91a734e71dc94fbf8cdd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Jan 2018 23:13:12 +0100 Subject: [PATCH 41/41] winbindd: WBFLAG_PAM_AUTH_PAC should call add_trusted_domain_from_auth() is the result is trusted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: https://bugzilla.samba.org/show_bug.cgi?id=13262 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme Autobuild-User(master): Ralph Böhme Autobuild-Date(master): Sat Feb 10 13:08:50 CET 2018 on sn-devel-144 (cherry picked from commit 597e755328940fc964b861333b557b0650666b24) --- source3/winbindd/winbindd_pam_auth_crap.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source3/winbindd/winbindd_pam_auth_crap.c b/source3/winbindd/winbindd_pam_auth_crap.c index 6fb65a27461..046517d1245 100644 --- a/source3/winbindd/winbindd_pam_auth_crap.c +++ b/source3/winbindd/winbindd_pam_auth_crap.c @@ -81,6 +81,20 @@ struct tevent_req *winbindd_pam_auth_crap_send( return tevent_req_post(req, ev); } + if (is_trusted && (state->flags & WBFLAG_PAM_INFO3_TEXT)) { + bool ok; + + ok = add_trusted_domain_from_auth( + state->response->data.auth.validation_level, + &state->response->data.auth.info3, + &state->response->data.auth.info6); + if (!ok) { + DBG_ERR("add_trusted_domain_from_auth failed\n"); + tevent_req_nterror(req, NT_STATUS_LOGON_FAILURE); + return tevent_req_post(req, ev); + } + } + tevent_req_done(req); return tevent_req_post(req, ev); } -- 2.13.6