The Samba-Bugzilla – Attachment 6245 Details for
Bug 7945
winbindd should try netr_Validation level 6 in netr_LogonSamLogon
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Backport Patch for v3-5-test
tmp.diff (text/plain), 14.62 KB, created by
Stefan Metzmacher
on 2011-02-04 11:23:36 UTC
(
hide
)
Description:
Backport Patch for v3-5-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2011-02-04 11:23:36 UTC
Size:
14.62 KB
patch
obsolete
>From 8cee914d3f1644839e34ab61f0373eec8aa0f3fd Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Fri, 7 Jan 2011 17:28:29 +0100 >Subject: [PATCH] s3-winbindd: let winbind try to use samlogon validation level 6. (bug #7945) > >The benefit of this that it makes us more robust to secure channel resets >triggered from tools outside the winbind process. Long term we need to have a >shared tdb secure channel store though as well. > >Guenther > >Signed-off-by: Stefan Metzmacher <metze@samba.org> > >(similar to commit f60398d7b20869d7b09d81854f3727fdcd897430) >(similar to commit 7add712498fe93603b1bffff2c633e097ce8fbdf) >--- > source3/auth/auth_domain.c | 1 + > source3/auth/auth_netlogond.c | 1 + > source3/include/proto.h | 2 + > source3/rpc_client/cli_netlogon.c | 100 +++++++++++++++++++++++++++++++++++-- > source3/winbindd/winbindd.h | 1 + > source3/winbindd/winbindd_cm.c | 1 + > source3/winbindd/winbindd_pam.c | 97 +++++++++++++++++++++++++++++++++++- > 7 files changed, 198 insertions(+), 5 deletions(-) > >diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c >index c527360..9677ce7 100644 >--- a/source3/auth/auth_domain.c >+++ b/source3/auth/auth_domain.c >@@ -310,6 +310,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, > user_info->client_domain, /* domain name */ > user_info->wksta_name, /* workstation name */ > chal, /* 8 byte challenge. */ >+ 3, /* validation level */ > user_info->lm_resp, /* lanman 24 byte response */ > user_info->nt_resp, /* nt 24 byte response */ > &info3); /* info3 out */ >diff --git a/source3/auth/auth_netlogond.c b/source3/auth/auth_netlogond.c >index ebfed83..2347dae 100644 >--- a/source3/auth/auth_netlogond.c >+++ b/source3/auth/auth_netlogond.c >@@ -85,6 +85,7 @@ static NTSTATUS netlogond_validate(TALLOC_CTX *mem_ctx, > user_info->client_domain, /* domain name */ > user_info->wksta_name, /* workstation name */ > (uchar *)auth_context->challenge.data, /* 8 byte challenge. */ >+ 3, /* validation level */ > user_info->lm_resp, /* lanman 24 byte response */ > user_info->nt_resp, /* nt 24 byte response */ > &info3); /* info3 out */ >diff --git a/source3/include/proto.h b/source3/include/proto.h >index bfcd012..ce33b70 100644 >--- a/source3/include/proto.h >+++ b/source3/include/proto.h >@@ -5260,6 +5260,7 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli, > const char *domain, > const char *workstation, > const uint8 chal[8], >+ uint16_t validation_level, > DATA_BLOB lm_response, > DATA_BLOB nt_response, > struct netr_SamInfo3 **info3); >@@ -5271,6 +5272,7 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli, > const char *domain, > const char *workstation, > const uint8 chal[8], >+ uint16_t validation_level, > DATA_BLOB lm_response, > DATA_BLOB nt_response, > struct netr_SamInfo3 **info3); >diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c >index 9cb0bc6..ca66faa 100644 >--- a/source3/rpc_client/cli_netlogon.c >+++ b/source3/rpc_client/cli_netlogon.c >@@ -283,6 +283,92 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli, > return result; > } > >+#define COPY_LSA_STRING(mem_ctx, in, out, name) do { \ >+ if (in->name.string) { \ >+ out->name.string = talloc_strdup(mem_ctx, in->name.string); \ >+ NT_STATUS_HAVE_NO_MEMORY(out->name.string); \ >+ } \ >+} while (0) >+ >+static NTSTATUS copy_netr_SamBaseInfo(TALLOC_CTX *mem_ctx, >+ const struct netr_SamBaseInfo *in, >+ struct netr_SamBaseInfo *out) >+{ >+ /* first copy all, then realloc pointers */ >+ *out = *in; >+ >+ COPY_LSA_STRING(mem_ctx, in, out, account_name); >+ COPY_LSA_STRING(mem_ctx, in, out, full_name); >+ COPY_LSA_STRING(mem_ctx, in, out, logon_script); >+ COPY_LSA_STRING(mem_ctx, in, out, profile_path); >+ COPY_LSA_STRING(mem_ctx, in, out, home_directory); >+ COPY_LSA_STRING(mem_ctx, in, out, home_drive); >+ >+ if (in->groups.count) { >+ out->groups.rids = (struct samr_RidWithAttribute *) >+ talloc_memdup(mem_ctx, in->groups.rids, >+ (sizeof(struct samr_RidWithAttribute) * >+ in->groups.count)); >+ NT_STATUS_HAVE_NO_MEMORY(out->groups.rids); >+ } >+ >+ COPY_LSA_STRING(mem_ctx, in, out, logon_server); >+ COPY_LSA_STRING(mem_ctx, in, out, domain); >+ >+ if (in->domain_sid) { >+ out->domain_sid = sid_dup_talloc(mem_ctx, in->domain_sid); >+ NT_STATUS_HAVE_NO_MEMORY(out->domain_sid); >+ } >+ >+ return NT_STATUS_OK; >+} >+ >+static NTSTATUS map_validation_to_info3(TALLOC_CTX *mem_ctx, >+ uint16_t validation_level, >+ union netr_Validation *validation, >+ struct netr_SamInfo3 **info3_p) >+{ >+ struct netr_SamInfo3 *info3; >+ 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 = talloc_move(mem_ctx, &validation->sam3); >+ break; >+ case 6: >+ if (validation->sam6 == NULL) { >+ return NT_STATUS_INVALID_PARAMETER; >+ } >+ >+ info3 = talloc_zero(mem_ctx, struct netr_SamInfo3); >+ if (info3 == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ status = copy_netr_SamBaseInfo(info3, &validation->sam6->base, &info3->base); >+ if (!NT_STATUS_IS_OK(status)) { >+ TALLOC_FREE(info3); >+ return status; >+ } >+ >+ info3->sidcount = validation->sam6->sidcount; >+ info3->sids = talloc_move(info3, &validation->sam6->sids); >+ break; >+ default: >+ return NT_STATUS_BAD_VALIDATION_CLASS; >+ } >+ >+ *info3_p = info3; >+ >+ return NT_STATUS_OK; >+} > > /** > * Logon domain user with an 'network' SAM logon >@@ -298,12 +384,12 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli, > const char *domain, > const char *workstation, > const uint8 chal[8], >+ uint16_t validation_level, > DATA_BLOB lm_response, > DATA_BLOB nt_response, > struct netr_SamInfo3 **info3) > { > NTSTATUS result = NT_STATUS_UNSUCCESSFUL; >- int validation_level = 3; > const char *workstation_name_slash; > const char *server_name_slash; > uint8 zeros[16]; >@@ -397,7 +483,10 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli, > > netlogon_creds_decrypt_samlogon(cli->dc, validation_level, &validation); > >- *info3 = validation.sam3; >+ result = map_validation_to_info3(mem_ctx, validation_level, &validation, info3); >+ if (!NT_STATUS_IS_OK(result)) { >+ return result; >+ } > > return result; > } >@@ -410,12 +499,12 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli, > const char *domain, > const char *workstation, > const uint8 chal[8], >+ uint16_t validation_level, > DATA_BLOB lm_response, > DATA_BLOB nt_response, > struct netr_SamInfo3 **info3) > { > NTSTATUS result = NT_STATUS_UNSUCCESSFUL; >- int validation_level = 3; > const char *workstation_name_slash; > const char *server_name_slash; > uint8 zeros[16]; >@@ -498,7 +587,10 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli, > > netlogon_creds_decrypt_samlogon(cli->dc, validation_level, &validation); > >- *info3 = validation.sam3; >+ result = map_validation_to_info3(mem_ctx, validation_level, &validation, info3); >+ if (!NT_STATUS_IS_OK(result)) { >+ return result; >+ } > > return result; > } >diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h >index f1815ac..56b0ad9 100644 >--- a/source3/winbindd/winbindd.h >+++ b/source3/winbindd/winbindd.h >@@ -167,6 +167,7 @@ struct winbindd_domain { > * we don't have to try _ex every time. */ > > bool can_do_ncacn_ip_tcp; >+ bool can_do_validation6; > > /* Lookup methods for this domain (LDAP or RPC) */ > struct winbindd_methods *methods; >diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c >index 77e5003..cc3e3ed 100644 >--- a/source3/winbindd/winbindd_cm.c >+++ b/source3/winbindd/winbindd_cm.c >@@ -1945,6 +1945,7 @@ done: > domain->name, domain->active_directory ? "" : "NOT ")); > > domain->can_do_ncacn_ip_tcp = domain->active_directory; >+ domain->can_do_validation6 = domain->active_directory; > > TALLOC_FREE(cli); > >diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c >index e958a7e..aab3b72 100644 >--- a/source3/winbindd/winbindd_pam.c >+++ b/source3/winbindd/winbindd_pam.c >@@ -1185,6 +1185,7 @@ typedef NTSTATUS (*netlogon_fn_t)(struct rpc_pipe_client *cli, > const char *domain, > const char *workstation, > const uint8 chal[8], >+ uint16_t validation_level, > DATA_BLOB lm_response, > DATA_BLOB nt_response, > struct netr_SamInfo3 **info3); >@@ -1296,6 +1297,8 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, > > do { > netlogon_fn_t logon_fn; >+ const struct cli_pipe_auth_data *auth; >+ uint32_t neg_flags = 0; > > ZERO_STRUCTP(my_info3); > retry = false; >@@ -1306,6 +1309,10 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, > DEBUG(3, ("could not open handle to NETLOGON pipe\n")); > goto done; > } >+ auth = netlogon_pipe->auth; >+ if (netlogon_pipe->dc) { >+ neg_flags = netlogon_pipe->dc->negotiate_flags; >+ } > > /* It is really important to try SamLogonEx here, > * because in a clustered environment, we want to use >@@ -1326,8 +1333,35 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, > * wrapping SamLogon context. > * > * -- abartlet 21 April 2008 >+ * >+ * It's also important to use NetlogonValidationSamInfo4 (6), >+ * because it relies on the rpc transport encryption >+ * and avoids using the global netlogon schannel >+ * session key to en/decrypt secret information >+ * like the user_session_key for network logons. >+ * >+ * [MS-APDS] 3.1.5.2 NTLM Network Logon >+ * says NETLOGON_NEG_CROSS_FOREST_TRUSTS and >+ * NETLOGON_NEG_AUTHENTICATED_RPC set together >+ * are the indication that the server supports >+ * NetlogonValidationSamInfo4 (6). And must only >+ * be used if "SealSecureChannel" is used. >+ * >+ * -- metze 4 February 2011 > */ > >+ if (auth == NULL) { >+ domain->can_do_validation6 = false; >+ } else if (auth->auth_type != PIPE_AUTH_TYPE_SCHANNEL) { >+ domain->can_do_validation6 = false; >+ } else if (auth->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { >+ domain->can_do_validation6 = false; >+ } else if (!(neg_flags & NETLOGON_NEG_CROSS_FOREST_TRUSTS)) { >+ domain->can_do_validation6 = false; >+ } else if (!(neg_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) { >+ domain->can_do_validation6 = false; >+ } >+ > logon_fn = contact_domain->can_do_samlogon_ex > ? rpccli_netlogon_sam_network_logon_ex > : rpccli_netlogon_sam_network_logon; >@@ -1340,20 +1374,42 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, > name_domain, /* target domain */ > global_myname(), /* workstation */ > chal, >+ domain->can_do_validation6 ? 6 : 3, > lm_resp, > nt_resp, > &my_info3); >- attempts += 1; > > if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR) > && contact_domain->can_do_samlogon_ex) { > DEBUG(3, ("Got a DC that can not do NetSamLogonEx, " > "retrying with NetSamLogon\n")); > contact_domain->can_do_samlogon_ex = false; >+ /* >+ * It's likely that the server also does not support >+ * validation level 6 >+ */ >+ domain->can_do_validation6 = false; >+ retry = true; >+ continue; >+ } >+ >+ if (domain->can_do_validation6 && >+ (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_INFO_CLASS) || >+ NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PARAMETER) || >+ NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL))) { >+ DEBUG(3,("Got a DC that can not do validation level 6, " >+ "retrying with level 3\n")); >+ domain->can_do_validation6 = false; > retry = true; > continue; > } > >+ /* >+ * we increment this after the "feature negotiation" >+ * for can_do_samlogon_ex and can_do_validation6 >+ */ >+ attempts += 1; >+ > /* We have to try a second time as cm_connect_netlogon > might not yet have noticed that the DC has killed > our connection. */ >@@ -1889,6 +1945,8 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, > > do { > netlogon_fn_t logon_fn; >+ const struct cli_pipe_auth_data *auth; >+ uint32_t neg_flags = 0; > > retry = false; > >@@ -1900,6 +1958,22 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, > nt_errstr(result))); > goto done; > } >+ auth = netlogon_pipe->auth; >+ if (netlogon_pipe->dc) { >+ neg_flags = netlogon_pipe->dc->negotiate_flags; >+ } >+ >+ if (auth == NULL) { >+ domain->can_do_validation6 = false; >+ } else if (auth->auth_type != PIPE_AUTH_TYPE_SCHANNEL) { >+ domain->can_do_validation6 = false; >+ } else if (auth->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { >+ domain->can_do_validation6 = false; >+ } else if (!(neg_flags & NETLOGON_NEG_CROSS_FOREST_TRUSTS)) { >+ domain->can_do_validation6 = false; >+ } else if (!(neg_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) { >+ domain->can_do_validation6 = false; >+ } > > logon_fn = contact_domain->can_do_samlogon_ex > ? rpccli_netlogon_sam_network_logon_ex >@@ -1914,6 +1988,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, > /* Bug #3248 - found by Stefan Burkei. */ > workstation, /* We carefully set this above so use it... */ > state->request->data.auth_crap.chal, >+ domain->can_do_validation6 ? 6 : 3, > lm_resp, > nt_resp, > &info3); >@@ -1923,10 +1998,30 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, > DEBUG(3, ("Got a DC that can not do NetSamLogonEx, " > "retrying with NetSamLogon\n")); > contact_domain->can_do_samlogon_ex = false; >+ /* >+ * It's likely that the server also does not support >+ * validation level 6 >+ */ >+ domain->can_do_validation6 = false; > retry = true; > continue; > } > >+ if (domain->can_do_validation6 && >+ (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_INFO_CLASS) || >+ NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PARAMETER) || >+ NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL))) { >+ DEBUG(3,("Got a DC that can not do validation level 6, " >+ "retrying with level 3\n")); >+ domain->can_do_validation6 = false; >+ retry = true; >+ continue; >+ } >+ >+ /* >+ * we increment this after the "feature negotiation" >+ * for can_do_samlogon_ex and can_do_validation6 >+ */ > attempts += 1; > > /* We have to try a second time as cm_connect_netlogon >-- >1.7.0.4 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
gd
:
review+
Actions:
View
Attachments on
bug 7945
: 6245