From 99d35904552b01ef9f2adc40e16887da9eb4de69 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 2 Apr 2008 02:29:48 +0200 Subject: Fix NETLOGON credential chain with Windows 2008 all over the place. In order to avoid receiving NT_STATUS_DOWNGRADE_DETECTED from a w2k8 netr_ServerAuthenticate2 reply, we need to start with the AD netlogon negotiate flags everywhere (not only when running in security=ads). Only for NT4 we need to do a downgrade to the returned negotiate flags. Tested with w2k8, w2ksp4, w2k3r2 and nt4sp6. Guenther (This used to be commit 0970369ca0cb9ae465cff40e5c75739824daf1d0) --- source3/auth/auth_domain.c | 2 +- source3/include/rpc_dce.h | 44 +++++++++++++++++++++++++++++++++++---- source3/libnet/libnet_join.c | 3 +-- source3/libsmb/trusts_util.c | 2 +- source3/rpc_client/cli_netlogon.c | 11 ++++++++++ source3/rpc_client/cli_pipe.c | 4 ++-- source3/rpcclient/rpcclient.c | 2 +- source3/utils/net_rpc_join.c | 4 ++-- source3/utils/net_rpc_samsync.c | 2 +- source3/winbindd/winbindd_cm.c | 6 +----- 10 files changed, 61 insertions(+), 19 deletions(-) (limited to 'source3') diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index c9aa0648f4..f526677eca 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -126,7 +126,7 @@ machine %s. Error was : %s.\n", dc_name, nt_errstr(result))); if (!lp_client_schannel()) { /* We need to set up a creds chain on an unauthenticated netlogon pipe. */ - uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; uint32 sec_chan_type = 0; unsigned char machine_pwd[16]; const char *account_name; diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h index ec08eb5f8f..33ab365160 100644 --- a/source3/include/rpc_dce.h +++ b/source3/include/rpc_dce.h @@ -101,12 +101,48 @@ enum RPC_PKT_TYPE { /* The 7 here seems to be required to get Win2k not to downgrade us to NT4. Actually, anything other than 1ff would seem to do... */ #define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff +/* + (NETLOGON_NEG_ACCOUNT_LOCKOUT | + NETLOGON_NEG_PERSISTENT_SAMREPL | + NETLOGON_NEG_ARCFOUR | + NETLOGON_NEG_PROMOTION_COUNT | + NETLOGON_NEG_CHANGELOG_BDC | + NETLOGON_NEG_FULL_SYNC_REPL | + NETLOGON_NEG_MULTIPLE_SIDS | + NETLOGON_NEG_REDO | + NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL | + NETLOGON_NEG_DNS_DOMAIN_TRUSTS | + NETLOGON_NEG_PASSWORD_SET2 | + NETLOGON_NEG_GETDOMAININFO) +*/ #define NETLOGON_NEG_DOMAIN_TRUST_ACCOUNT 0x2010b000 - -/* these are the flags that ADS clients use */ -#define NETLOGON_NEG_AUTH2_ADS_FLAGS (0x200fbffb | NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_128BIT | NETLOGON_NEG_SCHANNEL) -#define NETLOGON_NEG_SELECT_AUTH2_FLAGS ((lp_security() == SEC_ADS) ? NETLOGON_NEG_AUTH2_ADS_FLAGS : NETLOGON_NEG_AUTH2_FLAGS) +/* these are the flags that ADS clients use */ +#define NETLOGON_NEG_AUTH2_ADS_FLAGS 0x600fffff +/* + (NETLOGON_NEG_ACCOUNT_LOCKOUT | + NETLOGON_NEG_PERSISTENT_SAMREPL | + NETLOGON_NEG_ARCFOUR | + NETLOGON_NEG_PROMOTION_COUNT | + NETLOGON_NEG_CHANGELOG_BDC | + NETLOGON_NEG_FULL_SYNC_REPL | + NETLOGON_NEG_MULTIPLE_SIDS | + NETLOGON_NEG_REDO | + NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL | + NETLOGON_NEG_SEND_PASSWORD_INFO_PDC | + NETLOGON_NEG_GENERIC_PASSTHROUGH | + NETLOGON_NEG_CONCURRENT_RPC | + NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL | + NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL | + NETLOGON_NEG_128BIT | + NETLOGON_NEG_TRANSITIVE_TRUSTS | + NETLOGON_NEG_DNS_DOMAIN_TRUSTS | + NETLOGON_NEG_PASSWORD_SET2 | + NETLOGON_NEG_GETDOMAININFO | + NETLOGON_NEG_CROSS_FOREST_TRUSTS | + NETLOGON_NEG_AUTHENTICATED_RPC_LSASS | + NETLOGON_NEG_SCHANNEL) +*/ enum schannel_direction { SENDER_IS_INITIATOR, diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 90e1b5941e..16db032c50 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -930,8 +930,7 @@ NTSTATUS libnet_join_ok(const char *netbios_domain_name, const char *machine_name, const char *dc_name) { - uint32_t neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS | - NETLOGON_NEG_SCHANNEL; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_hnd = NULL; struct rpc_pipe_client *netlogon_pipe = NULL; diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 8c2f69cee3..c3f5f2538a 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -40,7 +40,7 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX already have valid creds. If not we must set them up. */ if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { - uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; result = rpccli_netlogon_setup_creds(cli, cli->cli->desthost, /* server name */ diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index ec16186462..851a4a8da8 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -132,6 +132,7 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, struct netr_Credential clnt_chal_send; struct netr_Credential srv_chal_recv; struct dcinfo *dc; + bool retried = false; SMB_ASSERT(cli->pipe_idx == PI_NETLOGON); @@ -153,6 +154,7 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, fstr_sprintf( dc->mach_acct, "%s$", machine_account); + again: /* Create the client challenge. */ generate_random_buffer(clnt_chal_send.data, 8); @@ -186,6 +188,15 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, &clnt_chal_send, /* input. */ &srv_chal_recv, /* output. */ neg_flags_inout); + + /* we might be talking to NT4, so let's downgrade in that case and retry + * with the returned neg_flags - gd */ + + if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) && !retried) { + retried = true; + goto again; + } + if (!NT_STATUS_IS_OK(result)) { return result; } diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1fd06f868e..71422cd9ad 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2600,7 +2600,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state const char *password, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; @@ -2634,7 +2634,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, const char *domain, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 5e87058111..52dba2291b 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -607,7 +607,7 @@ static NTSTATUS do_cmd(struct cli_state *cli, } if (cmd_entry->pipe_idx == PI_NETLOGON) { - uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; uint32 sec_channel_type; uchar trust_password[16]; diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index 45c0fe5097..ea3bb10c22 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -46,7 +46,7 @@ NTSTATUS net_rpc_join_ok(const char *domain, const char *server, { enum security_types sec; unsigned int conn_flags = NET_FLAGS_PDC; - uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_hnd = NULL; struct rpc_pipe_client *netlogon_pipe = NULL; @@ -133,7 +133,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) struct cli_state *cli; TALLOC_CTX *mem_ctx; uint32 acb_info = ACB_WSTRUST; - uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|(lp_client_schannel() ? NETLOGON_NEG_SCHANNEL : 0); + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; uint32 sec_channel_type; struct rpc_pipe_client *pipe_hnd = NULL; diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index 87d35b3ef6..986499731a 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -412,7 +412,7 @@ NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid, NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uchar trust_password[16]; - uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; uint32 sec_channel_type = 0; if (!secrets_fetch_trust_account_password(domain_name, diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 39d8def7ea..b792de0aab 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2335,7 +2335,7 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, struct winbindd_cm_conn *conn; NTSTATUS result; - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; uint8 mach_pwd[16]; uint32 sec_chan_type; const char *account_name; @@ -2348,10 +2348,6 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, return result; } - if (domain->active_directory) { - neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; - } - conn = &domain->conn; if (conn->netlogon_pipe != NULL) { -- cgit