summaryrefslogtreecommitdiff
path: root/source3/winbindd/winbindd_pam.c
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2011-01-07 17:28:29 +0100
committerStefan Metzmacher <metze@samba.org>2011-02-04 18:11:04 +0100
commitf60398d7b20869d7b09d81854f3727fdcd897430 (patch)
tree92b2938c802cba41ae0ed83a8e4af76ab7f1f2a5 /source3/winbindd/winbindd_pam.c
parentac4127a9f432f762cb728c161d7fbf80de31b60e (diff)
downloadsamba-f60398d7b20869d7b09d81854f3727fdcd897430.tar.gz
samba-f60398d7b20869d7b09d81854f3727fdcd897430.tar.bz2
samba-f60398d7b20869d7b09d81854f3727fdcd897430.zip
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> Autobuild-User: Stefan Metzmacher <metze@samba.org> Autobuild-Date: Fri Feb 4 18:11:04 CET 2011 on sn-devel-104
Diffstat (limited to 'source3/winbindd/winbindd_pam.c')
-rw-r--r--source3/winbindd/winbindd_pam.c59
1 files changed, 57 insertions, 2 deletions
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 760fa3bc60..68fa01f6d7 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1148,6 +1148,8 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
do {
struct rpc_pipe_client *netlogon_pipe;
+ const struct pipe_auth_data *auth;
+ uint32_t neg_flags = 0;
ZERO_STRUCTP(info3);
retry = false;
@@ -1159,6 +1161,10 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
nt_errstr(result)));
return result;
}
+ 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
@@ -1179,8 +1185,35 @@ static NTSTATUS winbind_samlogon_retry_loop(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 it 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 != DCERPC_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;
+ }
+
if (domain->can_do_samlogon_ex) {
result = rpccli_netlogon_sam_network_logon_ex(
netlogon_pipe,
@@ -1191,6 +1224,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
domainname, /* target domain */
workstation, /* workstation */
chal,
+ domain->can_do_validation6 ? 6 : 3,
lm_response,
nt_response,
info3);
@@ -1204,22 +1238,43 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
domainname, /* target domain */
workstation, /* workstation */
chal,
+ domain->can_do_validation6 ? 6 : 3,
lm_response,
nt_response,
info3);
}
- attempts += 1;
-
if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR)
&& domain->can_do_samlogon_ex) {
DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
"retrying with NetSamLogon\n"));
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. */