Fix NETLOGON credential chain with Windows 2008 all over the place.
authorGünther Deschner <gd@samba.org>
Wed, 2 Apr 2008 00:29:48 +0000 (02:29 +0200)
committerGünther Deschner <gd@samba.org>
Wed, 2 Apr 2008 09:12:47 +0000 (11:12 +0200)
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

source/auth/auth_domain.c
source/include/rpc_dce.h
source/libnet/libnet_join.c
source/libsmb/trusts_util.c
source/rpc_client/cli_netlogon.c
source/rpc_client/cli_pipe.c
source/rpcclient/rpcclient.c
source/utils/net_rpc_join.c
source/utils/net_rpc_samsync.c
source/winbindd/winbindd_cm.c

index c9aa0648f45f6f1b41d782ec3832571dd64ca14b..f526677eca6848d9ad2c15ccc9a8542379b2cfb5 100644 (file)
@@ -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;
index ec08eb5f8f1f3761f70cd7bc9913b7f02b470206..33ab365160430eafccfa732c18c8e7abb1cc4aa8 100644 (file)
@@ -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,
index 90e1b5941e52c176397521663daa03ab95235196..16db032c5020a56d9d2d3962a66ae582cd0081f9 100644 (file)
@@ -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;
index 8c2f69cee364387fdb97f833820a88e81ed79fbb..c3f5f2538aaa106aa52f442f6811573354b29cbc 100644 (file)
@@ -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 */
index ec16186462b862873fae497d0151a662148d94df..851a4a8da825285befa304cfe822feef2cb13fa6 100644 (file)
@@ -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;
        }
index 1fd06f868ef18ecb8184844996d247635aab83ed..71422cd9adbfd31df244fb0883e58add901220a6 100644 (file)
@@ -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;
 
index 5e870581117f3e62a3b28eeea1d5a9ee3a0f66f0..52dba2291be71614942f38cad75eddedaa49769b 100644 (file)
@@ -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];
        
index 45c0fe50973a11edb041153788a60e58f2a898b0..ea3bb10c226717dcb6dda0d904f20d91eba81564 100644 (file)
@@ -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;
 
index 87d35b3ef614c5752691a35c77651a21548590f1..986499731af6de8fec4e0b0eb8e3265ec2cc0d46 100644 (file)
@@ -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,
index 39d8def7ea67f04b4fcef3d2c16b06680009209a..b792de0aabbd89f0b56e91c22aa000b4f6e82144 100644 (file)
@@ -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) {