s3:rpc_client: make use of the new netlogon_creds_cli_context
authorStefan Metzmacher <metze@samba.org>
Sat, 27 Jul 2013 09:30:13 +0000 (11:30 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 7 Jan 2014 11:47:06 +0000 (12:47 +0100)
This exchanges rpc_pipe_client->dc with rpc_pipe_client->netlogon_creds
and lets the secure channel session state be stored in node local database.

This is the proper fix for a large number of bugs:
https://bugzilla.samba.org/show_bug.cgi?id=6563
https://bugzilla.samba.org/show_bug.cgi?id=7944
https://bugzilla.samba.org/show_bug.cgi?id=7945
https://bugzilla.samba.org/show_bug.cgi?id=7568
https://bugzilla.samba.org/show_bug.cgi?id=8599

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
12 files changed:
source3/libnet/libnet_join.c
source3/libnet/libnet_samsync.c
source3/rpc_client/cli_netlogon.c
source3/rpc_client/cli_pipe.c
source3/rpc_client/cli_pipe.h
source3/rpc_client/cli_pipe_schannel.c
source3/rpc_client/rpc_client.h
source3/rpcclient/cmd_netlogon.c
source3/winbindd/winbindd.h
source3/winbindd/winbindd_cm.c
source3/winbindd/winbindd_pam.c
source3/wscript_build

index c1eccda1af1c24c78ddf1dad00a05360f2a61dea..5dc620f270eb6eb9c7e2b34fab04384c59a29bc1 100644 (file)
@@ -1279,7 +1279,8 @@ NTSTATUS libnet_join_ok(const char *netbios_domain_name,
        status = cli_rpc_pipe_open_schannel_with_key(
                cli, &ndr_table_netlogon, NCACN_NP,
                DCERPC_AUTH_LEVEL_PRIVACY,
-               netbios_domain_name, &netlogon_pipe->dc, &pipe_hnd);
+               netbios_domain_name,
+               netlogon_pipe->netlogon_creds, &pipe_hnd);
 
        cli_shutdown(cli);
 
index a10378558ca368621b4536723b9517a7c77a6741..02d3fc6ce7ff39d290e6e5ba46a77e6b8b85c433 100644 (file)
@@ -30,6 +30,7 @@
 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
 #include "../libcli/security/security.h"
 #include "messages.h"
+#include "../libcli/auth/netlogon_creds_cli.h"
 
 /**
  * Fix up the delta, dealing with encryption issues so that the final
@@ -213,8 +214,15 @@ static NTSTATUS libnet_samsync_delta(TALLOC_CTX *mem_ctx,
 
        do {
                struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
+               struct netlogon_creds_CredentialState *creds = NULL;
 
-               netlogon_creds_client_authenticator(ctx->cli->dc, &credential);
+               status = netlogon_creds_cli_lock(ctx->cli->netlogon_creds,
+                                                mem_ctx, &creds);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+
+               netlogon_creds_client_authenticator(creds, &credential);
 
                if (ctx->single_object_replication &&
                    !ctx->force_full_replication) {
@@ -254,28 +262,33 @@ static NTSTATUS libnet_samsync_delta(TALLOC_CTX *mem_ctx,
                }
 
                if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(creds);
                        return status;
                }
 
                /* Check returned credentials. */
-               if (!netlogon_creds_client_check(ctx->cli->dc,
+               if (!netlogon_creds_client_check(creds,
                                                 &return_authenticator.cred)) {
+                       TALLOC_FREE(creds);
                        DEBUG(0,("credentials chain check failed\n"));
                        return NT_STATUS_ACCESS_DENIED;
                }
 
                if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) {
+                       TALLOC_FREE(creds);
                        return result;
                }
 
                if (NT_STATUS_IS_ERR(result)) {
+                       TALLOC_FREE(creds);
                        break;
                }
 
                samsync_fix_delta_array(mem_ctx,
-                                       ctx->cli->dc,
+                                       creds,
                                        database_id,
                                        delta_enum_array);
+               TALLOC_FREE(creds);
 
                /* Process results */
                callback_status = ctx->ops->process_objects(mem_ctx, database_id,
index 5e8a2fca4122dd60bcf53e6ab77c0f543d394388..fcd24d6f4cc92f4bd06ae1f92cb7ed91600c1e2a 100644 (file)
 #include "includes.h"
 #include "rpc_client/rpc_client.h"
 #include "../libcli/auth/libcli_auth.h"
+#include "../libcli/auth/netlogon_creds_cli.h"
 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
 #include "rpc_client/cli_netlogon.h"
 #include "rpc_client/init_netlogon.h"
 #include "rpc_client/util_netlogon.h"
 #include "../libcli/security/security.h"
+#include "lib/param/param.h"
 
 /****************************************************************************
  Wrapper function that uses the auth and auth2 calls to set up a NETLOGON
@@ -44,113 +46,81 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli,
                                     enum netr_SchannelType sec_chan_type,
                                     uint32_t *neg_flags_inout)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct loadparm_context *lp_ctx;
        NTSTATUS status;
-       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       struct netr_Credential clnt_chal_send;
-       struct netr_Credential srv_chal_recv;
        struct samr_Password password;
-       bool retried = false;
        fstring mach_acct;
-       uint32_t neg_flags = *neg_flags_inout;
        struct dcerpc_binding_handle *b = cli->binding_handle;
+       struct netlogon_creds_CredentialState *creds = NULL;
 
        if (!ndr_syntax_id_equal(&cli->abstract_syntax,
                                 &ndr_table_netlogon.syntax_id)) {
+               TALLOC_FREE(frame);
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       TALLOC_FREE(cli->dc);
-
-       /* Store the machine account password we're going to use. */
-       memcpy(password.hash, machine_pwd, 16);
-
-       fstr_sprintf( mach_acct, "%s$", machine_account);
-
- again:
-       /* Create the client challenge. */
-       generate_random_buffer(clnt_chal_send.data, 8);
-
-       /* Get the server challenge. */
-       status = dcerpc_netr_ServerReqChallenge(b, talloc_tos(),
-                                               cli->srv_name_slash,
-                                               clnt_name,
-                                               &clnt_chal_send,
-                                               &srv_chal_recv,
-                                               &result);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-       if (!NT_STATUS_IS_OK(result)) {
-               return result;
+       if (!strequal(lp_netbios_name(), clnt_name)) {
+               TALLOC_FREE(frame);
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
-       /* Calculate the session key and client credentials */
+       TALLOC_FREE(cli->netlogon_creds);
 
-       cli->dc = netlogon_creds_client_init(cli,
-                                   mach_acct,
-                                   clnt_name,
-                                   sec_chan_type,
-                                   &clnt_chal_send,
-                                   &srv_chal_recv,
-                                   &password,
-                                   &clnt_chal_send,
-                                   neg_flags);
+       fstr_sprintf( mach_acct, "%s$", machine_account);
 
-       if (!cli->dc) {
+       lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
+       if (lp_ctx == NULL) {
+               TALLOC_FREE(frame);
                return NT_STATUS_NO_MEMORY;
        }
-
-       /*
-        * Send client auth-2 challenge and receive server repy.
-        */
-
-       status = dcerpc_netr_ServerAuthenticate2(b, talloc_tos(),
-                                                cli->srv_name_slash,
-                                                cli->dc->account_name,
-                                                sec_chan_type,
-                                                cli->dc->computer_name,
-                                                &clnt_chal_send, /* input. */
-                                                &srv_chal_recv, /* output. */
-                                                &neg_flags,
-                                                &result);
+       status = netlogon_creds_cli_context_global(lp_ctx,
+                                                  NULL, /* msg_ctx */
+                                                  mach_acct,
+                                                  sec_chan_type,
+                                                  server_name,
+                                                  domain,
+                                                  cli, &cli->netlogon_creds);
+       talloc_unlink(frame, lp_ctx);
        if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
                return status;
        }
-       /* 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;
-               TALLOC_FREE(cli->dc);
-               goto again;
+       status = netlogon_creds_cli_get(cli->netlogon_creds,
+                                       frame, &creds);
+       if (NT_STATUS_IS_OK(status)) {
+               DEBUG(5,("rpccli_netlogon_setup_creds: server %s using "
+                        "cached credential\n",
+                        cli->desthost));
+               *neg_flags_inout = creds->negotiate_flags;
+               TALLOC_FREE(frame);
+               return NT_STATUS_OK;
        }
 
-       if (!NT_STATUS_IS_OK(result)) {
-               return result;
-       }
-
-       /*
-        * Check the returned value using the initial
-        * server received challenge.
-        */
-
-       if (!netlogon_creds_client_check(cli->dc, &srv_chal_recv)) {
-               /*
-                * Server replied with bad credential. Fail.
-                */
-               DEBUG(0,("rpccli_netlogon_setup_creds: server %s "
-                       "replied with bad credential\n",
-                       cli->desthost ));
-               return NT_STATUS_ACCESS_DENIED;
-       }
+       /* Store the machine account password we're going to use. */
+       memcpy(password.hash, machine_pwd, 16);
 
        DEBUG(5,("rpccli_netlogon_setup_creds: server %s credential "
                "chain established.\n",
                cli->desthost ));
 
-       cli->dc->negotiate_flags = neg_flags;
-       *neg_flags_inout = neg_flags;
+       status = netlogon_creds_cli_auth(cli->netlogon_creds, b,
+                                        password, NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return status;
+       }
+
+       status = netlogon_creds_cli_get(cli->netlogon_creds,
+                                       frame, &creds);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return NT_STATUS_INTERNAL_ERROR;
+       }
 
+       *neg_flags_inout = creds->negotiate_flags;
+       TALLOC_FREE(frame);
        return NT_STATUS_OK;
 }
 
@@ -163,20 +133,16 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
                                   const char *username,
                                   const char *password,
                                   const char *workstation,
-                                  uint16_t validation_level,
+                                  uint16_t _ignored_validation_level,
                                   int logon_type)
 {
-       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        NTSTATUS status;
-       struct netr_Authenticator clnt_creds;
-       struct netr_Authenticator ret_creds;
        union netr_LogonLevel *logon;
-       union netr_Validation validation;
-       uint8_t authoritative;
+       uint16_t validation_level = 0;
+       union netr_Validation *validation = NULL;
+       uint8_t authoritative = 0;
+       uint32_t flags = 0;
        fstring clnt_name_slash;
-       struct dcerpc_binding_handle *b = cli->binding_handle;
-
-       ZERO_STRUCT(ret_creds);
 
        logon = talloc_zero(mem_ctx, union netr_LogonLevel);
        if (!logon) {
@@ -191,8 +157,6 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
 
        /* Initialise input parameters */
 
-       netlogon_creds_client_authenticator(cli->dc, &clnt_creds);
-
        switch (logon_type) {
        case NetlogonInteractiveInformation: {
 
@@ -208,17 +172,6 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
 
                nt_lm_owf_gen(password, ntpassword.hash, lmpassword.hash);
 
-               if (cli->dc->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
-                       netlogon_creds_aes_encrypt(cli->dc, lmpassword.hash, 16);
-                       netlogon_creds_aes_encrypt(cli->dc, ntpassword.hash, 16);
-               } else if (cli->dc->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
-                       netlogon_creds_arcfour_crypt(cli->dc, lmpassword.hash, 16);
-                       netlogon_creds_arcfour_crypt(cli->dc, ntpassword.hash, 16);
-               } else {
-                       netlogon_creds_des_encrypt(cli->dc, &lmpassword);
-                       netlogon_creds_des_encrypt(cli->dc, &ntpassword);
-               }
-
                password_info->identity_info.domain_name.string         = domain;
                password_info->identity_info.parameter_control          = logon_parameters;
                password_info->identity_info.logon_id_low               = 0xdead;
@@ -281,28 +234,20 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
                return NT_STATUS_INVALID_INFO_CLASS;
        }
 
-       status = dcerpc_netr_LogonSamLogon(b, mem_ctx,
-                                          cli->srv_name_slash,
-                                          lp_netbios_name(),
-                                          &clnt_creds,
-                                          &ret_creds,
-                                          logon_type,
-                                          logon,
-                                          validation_level,
-                                          &validation,
-                                          &authoritative,
-                                          &result);
+       status = netlogon_creds_cli_LogonSamLogon(cli->netlogon_creds,
+                                                 cli->binding_handle,
+                                                 logon_type,
+                                                 logon,
+                                                 mem_ctx,
+                                                 &validation_level,
+                                                 &validation,
+                                                 &authoritative,
+                                                 &flags);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       /* Always check returned credentials */
-       if (!netlogon_creds_client_check(cli->dc, &ret_creds.cred)) {
-               DEBUG(0,("rpccli_netlogon_sam_logon: credentials chain check failed\n"));
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
-       return result;
+       return NT_STATUS_OK;
 }
 
 static NTSTATUS map_validation_to_info3(TALLOC_CTX *mem_ctx,
@@ -366,29 +311,24 @@ 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,
+                                          uint16_t _ignored_validation_level,
                                           DATA_BLOB lm_response,
                                           DATA_BLOB nt_response,
                                           struct netr_SamInfo3 **info3)
 {
-       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        NTSTATUS status;
        const char *workstation_name_slash;
-       const char *server_name_slash;
-       struct netr_Authenticator clnt_creds;
-       struct netr_Authenticator ret_creds;
        union netr_LogonLevel *logon = NULL;
        struct netr_NetworkInfo *network_info;
-       uint8_t authoritative;
-       union netr_Validation validation;
+       uint16_t validation_level = 0;
+       union netr_Validation *validation = NULL;
+       uint8_t authoritative = 0;
+       uint32_t flags = 0;
        struct netr_ChallengeResponse lm;
        struct netr_ChallengeResponse nt;
-       struct dcerpc_binding_handle *b = cli->binding_handle;
 
        *info3 = NULL;
 
-       ZERO_STRUCT(ret_creds);
-
        ZERO_STRUCT(lm);
        ZERO_STRUCT(nt);
 
@@ -402,21 +342,13 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
                return NT_STATUS_NO_MEMORY;
        }
 
-       netlogon_creds_client_authenticator(cli->dc, &clnt_creds);
-
-       if (server[0] != '\\' && server[1] != '\\') {
-               server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server);
-       } else {
-               server_name_slash = server;
-       }
-
        if (workstation[0] != '\\' && workstation[1] != '\\') {
                workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
        } else {
                workstation_name_slash = workstation;
        }
 
-       if (!workstation_name_slash || !server_name_slash) {
+       if (!workstation_name_slash) {
                DEBUG(0, ("talloc_asprintf failed!\n"));
                return NT_STATUS_NO_MEMORY;
        }
@@ -443,40 +375,27 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
 
        /* Marshall data and send request */
 
-       status = dcerpc_netr_LogonSamLogon(b, mem_ctx,
-                                          server_name_slash,
-                                          lp_netbios_name(),
-                                          &clnt_creds,
-                                          &ret_creds,
-                                          NetlogonNetworkInformation,
-                                          logon,
-                                          validation_level,
-                                          &validation,
-                                          &authoritative,
-                                          &result);
+       status = netlogon_creds_cli_LogonSamLogon(cli->netlogon_creds,
+                                                 cli->binding_handle,
+                                                 NetlogonNetworkInformation,
+                                                 logon,
+                                                 mem_ctx,
+                                                 &validation_level,
+                                                 &validation,
+                                                 &authoritative,
+                                                 &flags);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       /* Always check returned credentials. */
-       if (!netlogon_creds_client_check(cli->dc, &ret_creds.cred)) {
-               DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n"));
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
-       if (!NT_STATUS_IS_OK(result)) {
-               return result;
-       }
-
-       netlogon_creds_decrypt_samlogon_validation(cli->dc, validation_level,
-                                                  &validation);
-
-       result = map_validation_to_info3(mem_ctx, validation_level, &validation, info3);
-       if (!NT_STATUS_IS_OK(result)) {
-               return result;
+       status = map_validation_to_info3(mem_ctx,
+                                        validation_level, validation,
+                                        info3);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
-       return result;
+       return NT_STATUS_OK;
 }
 
 NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli,
@@ -492,100 +411,18 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli,
                                              DATA_BLOB nt_response,
                                              struct netr_SamInfo3 **info3)
 {
-       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       NTSTATUS status;
-       const char *workstation_name_slash;
-       const char *server_name_slash;
-       union netr_LogonLevel *logon = NULL;
-       struct netr_NetworkInfo *network_info;
-       uint8_t authoritative;
-       union netr_Validation validation;
-       struct netr_ChallengeResponse lm;
-       struct netr_ChallengeResponse nt;
-       uint32_t flags = 0;
-       struct dcerpc_binding_handle *b = cli->binding_handle;
-
-       *info3 = NULL;
-
-       ZERO_STRUCT(lm);
-       ZERO_STRUCT(nt);
-
-       logon = talloc_zero(mem_ctx, union netr_LogonLevel);
-       if (!logon) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       network_info = talloc_zero(mem_ctx, struct netr_NetworkInfo);
-       if (!network_info) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (server[0] != '\\' && server[1] != '\\') {
-               server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server);
-       } else {
-               server_name_slash = server;
-       }
-
-       if (workstation[0] != '\\' && workstation[1] != '\\') {
-               workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
-       } else {
-               workstation_name_slash = workstation;
-       }
-
-       if (!workstation_name_slash || !server_name_slash) {
-               DEBUG(0, ("talloc_asprintf failed!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       /* Initialise input parameters */
-
-       lm.data = lm_response.data;
-       lm.length = lm_response.length;
-       nt.data = nt_response.data;
-       nt.length = nt_response.length;
-
-       network_info->identity_info.domain_name.string          = domain;
-       network_info->identity_info.parameter_control           = logon_parameters;
-       network_info->identity_info.logon_id_low                = 0xdead;
-       network_info->identity_info.logon_id_high               = 0xbeef;
-       network_info->identity_info.account_name.string         = username;
-       network_info->identity_info.workstation.string          = workstation_name_slash;
-
-       memcpy(network_info->challenge, chal, 8);
-       network_info->nt = nt;
-       network_info->lm = lm;
-
-       logon->network = network_info;
-
-        /* Marshall data and send request */
-
-       status = dcerpc_netr_LogonSamLogonEx(b, mem_ctx,
-                                            server_name_slash,
-                                            lp_netbios_name(),
-                                            NetlogonNetworkInformation,
-                                            logon,
-                                            validation_level,
-                                            &validation,
-                                            &authoritative,
-                                            &flags,
-                                            &result);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       if (!NT_STATUS_IS_OK(result)) {
-               return result;
-       }
-
-       netlogon_creds_decrypt_samlogon_validation(cli->dc, validation_level,
-                                                  &validation);
-
-       result = map_validation_to_info3(mem_ctx, validation_level, &validation, info3);
-       if (!NT_STATUS_IS_OK(result)) {
-               return result;
-       }
-
-       return result;
+       return rpccli_netlogon_sam_network_logon(cli,
+                                                mem_ctx,
+                                                logon_parameters,
+                                                server,
+                                                username,
+                                                domain,
+                                                workstation,
+                                                chal,
+                                                validation_level,
+                                                lm_response,
+                                                nt_response,
+                                                info3);
 }
 
 /*********************************************************
@@ -605,11 +442,9 @@ NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli,
                                            const unsigned char new_trust_passwd_hash[16],
                                            enum netr_SchannelType sec_channel_type)
 {
-       NTSTATUS result, status;
-       struct netr_Authenticator clnt_creds, srv_cred;
-       struct dcerpc_binding_handle *b = cli->binding_handle;
+       NTSTATUS result;
 
-       if (!cli->dc) {
+       if (cli->netlogon_creds == NULL) {
                uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS |
                                        NETLOGON_NEG_SUPPORTS_AES;
                result = rpccli_netlogon_setup_creds(cli,
@@ -627,77 +462,16 @@ NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli,
                }
        }
 
-       netlogon_creds_client_authenticator(cli->dc, &clnt_creds);
-
-       if (cli->dc->negotiate_flags & NETLOGON_NEG_PASSWORD_SET2) {
-
-               struct netr_CryptPassword new_password;
-               uint32_t old_timeout;
-
-               init_netr_CryptPassword(new_trust_pwd_cleartext,
-                                       cli->dc,
-                                       &new_password);
-
-               old_timeout = dcerpc_binding_handle_set_timeout(b, 600000);
-
-               status = dcerpc_netr_ServerPasswordSet2(b, mem_ctx,
-                                                       cli->srv_name_slash,
-                                                       cli->dc->account_name,
-                                                       sec_channel_type,
-                                                       cli->dc->computer_name,
-                                                       &clnt_creds,
-                                                       &srv_cred,
-                                                       &new_password,
-                                                       &result);
-
-               dcerpc_binding_handle_set_timeout(b, old_timeout);
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(0,("dcerpc_netr_ServerPasswordSet2 failed: %s\n",
-                               nt_errstr(status)));
-                       return status;
-               }
-       } else {
-
-               struct samr_Password new_password;
-               uint32_t old_timeout;
-
-               memcpy(new_password.hash, new_trust_passwd_hash, sizeof(new_password.hash));
-               netlogon_creds_des_encrypt(cli->dc, &new_password);
-
-               old_timeout = dcerpc_binding_handle_set_timeout(b, 600000);
-
-               status = dcerpc_netr_ServerPasswordSet(b, mem_ctx,
-                                                      cli->srv_name_slash,
-                                                      cli->dc->account_name,
-                                                      sec_channel_type,
-                                                      cli->dc->computer_name,
-                                                      &clnt_creds,
-                                                      &srv_cred,
-                                                      &new_password,
-                                                      &result);
-
-               dcerpc_binding_handle_set_timeout(b, old_timeout);
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(0,("dcerpc_netr_ServerPasswordSet failed: %s\n",
-                               nt_errstr(status)));
-                       return status;
-               }
-       }
-
-       /* Always check returned credentials. */
-       if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) {
-               DEBUG(0,("credentials chain check failed\n"));
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
+       result = netlogon_creds_cli_ServerPasswordSet(cli->netlogon_creds,
+                                                     cli->binding_handle,
+                                                     new_trust_pwd_cleartext,
+                                                     NULL); /* new_version */
        if (!NT_STATUS_IS_OK(result)) {
-               DEBUG(0,("dcerpc_netr_ServerPasswordSet{2} failed: %s\n",
+               DEBUG(0,("netlogon_creds_cli_ServerPasswordSet failed: %s\n",
                        nt_errstr(result)));
                return result;
        }
 
-       return result;
+       return NT_STATUS_OK;
 }
 
index b6908be7e28b11bc29333f213e1e7ac90ece9cdd..7f79046fc7c38dfdd71a84738944ceca37a9c911 100644 (file)
@@ -24,6 +24,7 @@
 #include "librpc/gen_ndr/ndr_epmapper_c.h"
 #include "../librpc/gen_ndr/ndr_dssetup.h"
 #include "../libcli/auth/schannel.h"
+#include "../libcli/auth/netlogon_creds_cli.h"
 #include "auth_generic.h"
 #include "librpc/gen_ndr/ndr_dcerpc.h"
 #include "librpc/gen_ndr/ndr_netlogon_c.h"
@@ -3024,34 +3025,39 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
                                             enum dcerpc_transport_t transport,
                                             enum dcerpc_AuthLevel auth_level,
                                             const char *domain,
-                                            struct netlogon_creds_CredentialState **pdc,
+                                            struct netlogon_creds_cli_context *netlogon_creds,
                                             struct rpc_pipe_client **_rpccli)
 {
        struct rpc_pipe_client *rpccli;
        struct pipe_auth_data *rpcauth;
+       struct netlogon_creds_CredentialState *creds = NULL;
        NTSTATUS status;
-       NTSTATUS result;
-       struct netlogon_creds_CredentialState save_creds;
-       struct netr_Authenticator auth;
-       struct netr_Authenticator return_auth;
-       union netr_Capabilities capabilities;
        const char *target_service = table->authservices->names[0];
+       int rpc_pipe_bind_dbglvl = 0;
 
        status = cli_rpc_pipe_open(cli, transport, table, &rpccli);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = netlogon_creds_cli_lock(netlogon_creds, rpccli, &creds);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("netlogon_creds_cli_get returned %s\n",
+                         nt_errstr(status)));
+               TALLOC_FREE(rpccli);
+               return status;
+       }
+
        status = rpccli_generic_bind_data(rpccli,
                                          DCERPC_AUTH_TYPE_SCHANNEL,
                                          auth_level,
                                          NULL,
                                          target_service,
                                          domain,
-                                         (*pdc)->computer_name,
+                                         creds->computer_name,
                                          NULL,
                                          CRED_AUTO_USE_KERBEROS,
-                                         *pdc,
+                                         creds,
                                          &rpcauth);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
@@ -3060,120 +3066,43 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
                return status;
        }
 
-       /*
-        * The credentials on a new netlogon pipe are the ones we are passed
-        * in - copy them over
-        *
-        * This may get overwritten... in rpc_pipe_bind()...
-        */
-       rpccli->dc = netlogon_creds_copy(rpccli, *pdc);
-       if (rpccli->dc == NULL) {
-               TALLOC_FREE(rpccli);
-               return NT_STATUS_NO_MEMORY;
-       }
-
        status = rpc_pipe_bind(rpccli, rpcauth);
+       if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
+               rpc_pipe_bind_dbglvl = 1;
+               netlogon_creds_cli_delete(netlogon_creds, &creds);
+       }
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
-                         "cli_rpc_pipe_bind failed with error %s\n",
-                         nt_errstr(status) ));
+               DEBUG(rpc_pipe_bind_dbglvl,
+                     ("cli_rpc_pipe_open_schannel_with_key: "
+                      "rpc_pipe_bind failed with error %s\n",
+                      nt_errstr(status)));
                TALLOC_FREE(rpccli);
                return status;
        }
 
-       if (!ndr_syntax_id_equal(&table->syntax_id, &ndr_table_netlogon.syntax_id)) {
-               goto done;
-       }
-
-       save_creds = *rpccli->dc;
-       ZERO_STRUCT(return_auth);
-       ZERO_STRUCT(capabilities);
+       TALLOC_FREE(creds);
 
-       netlogon_creds_client_authenticator(&save_creds, &auth);
-
-       status = dcerpc_netr_LogonGetCapabilities(rpccli->binding_handle,
-                                                 talloc_tos(),
-                                                 rpccli->srv_name_slash,
-                                                 save_creds.computer_name,
-                                                 &auth, &return_auth,
-                                                 1, &capabilities,
-                                                 &result);
-       if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
-               if (save_creds.negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
-                       DEBUG(5, ("AES was negotiated and the error was %s - "
-                                 "downgrade detected\n",
-                                 nt_errstr(status)));
-                       TALLOC_FREE(rpccli);
-                       return NT_STATUS_INVALID_NETWORK_RESPONSE;
-               }
-
-               /* This is probably an old Samba Version */
-               DEBUG(5, ("We are checking against an NT or old Samba - %s\n",
-                         nt_errstr(status)));
+       if (!ndr_syntax_id_equal(&table->syntax_id, &ndr_table_netlogon.syntax_id)) {
                goto done;
        }
 
+       status = netlogon_creds_cli_check(netlogon_creds,
+                                         rpccli->binding_handle);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("dcerpc_netr_LogonGetCapabilities failed with %s\n",
+               DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
                          nt_errstr(status)));
                TALLOC_FREE(rpccli);
                return status;
        }
 
-       if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) {
-               if (save_creds.negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
-                       /* This means AES isn't supported. */
-                       DEBUG(5, ("AES was negotiated and the result was %s - "
-                                 "downgrade detected\n",
-                                 nt_errstr(result)));
-                       TALLOC_FREE(rpccli);
-                       return NT_STATUS_INVALID_NETWORK_RESPONSE;
-               }
-
-               /* This is probably an old Windows version */
-               DEBUG(5, ("We are checking against an win2k3 or Samba - %s\n",
-                         nt_errstr(result)));
-               goto done;
-       }
-
-       /*
-        * We need to check the credential state here, cause win2k3 and earlier
-        * returns NT_STATUS_NOT_IMPLEMENTED
-        */
-       if (!netlogon_creds_client_check(&save_creds, &return_auth.cred)) {
-               /*
-                * Server replied with bad credential. Fail.
-                */
-               DEBUG(0,("cli_rpc_pipe_open_schannel_with_key: server %s "
-                        "replied with bad credential\n",
-                        rpccli->desthost));
-               TALLOC_FREE(rpccli);
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
-       }
-       *rpccli->dc = save_creds;
-
-       if (!NT_STATUS_IS_OK(result)) {
-               DEBUG(0, ("dcerpc_netr_LogonGetCapabilities failed with %s\n",
-                         nt_errstr(result)));
-               TALLOC_FREE(rpccli);
-               return result;
-       }
-
-       if (!(save_creds.negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
-               /* This means AES isn't supported. */
-               DEBUG(5, ("AES is not negotiated, but netr_LogonGetCapabilities "
-                         "was OK - downgrade detected\n"));
-               TALLOC_FREE(rpccli);
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
-       }
-
-       if (save_creds.negotiate_flags != capabilities.server_capabilities) {
-               DEBUG(0, ("The client capabilities don't match the server "
-                         "capabilities: local[0x%08X] remote[0x%08X]\n",
-                         save_creds.negotiate_flags,
-                         capabilities.server_capabilities));
+       status = netlogon_creds_cli_context_copy(netlogon_creds,
+                                                rpccli,
+                                                &rpccli->netlogon_creds);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("netlogon_creds_cli_context_copy failed with %s\n",
+                         nt_errstr(status)));
                TALLOC_FREE(rpccli);
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+               return status;
        }
 
 done:
index 1bfb551cf391f6a5e2d20b927b7b497fc6fc920e..4e9f84a333b5a92278713d7c4c9d32c9628bbcb1 100644 (file)
@@ -98,7 +98,7 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
                                             enum dcerpc_transport_t transport,
                                             enum dcerpc_AuthLevel auth_level,
                                             const char *domain,
-                                            struct netlogon_creds_CredentialState **pdc,
+                                            struct netlogon_creds_cli_context *netlogon_creds,
                                             struct rpc_pipe_client **presult);
 
 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
index aaae44b512e95676fcf2ae7ccacd7a614ab186ba..e3d65c86203567be125903ce4b36cd2701b2beb6 100644 (file)
@@ -112,7 +112,8 @@ NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
        }
 
        status = cli_rpc_pipe_open_schannel_with_key(
-               cli, table, transport, auth_level, domain, &netlogon_pipe->dc,
+               cli, table, transport, auth_level, domain,
+               netlogon_pipe->netlogon_creds,
                &result);
 
        /* Now we've bound using the session key we can close the netlog pipe. */
index 8024f0182158b6ce8863a0d9df5652e4ad0d8bb2..7c4cceb863dcfef1f8ccd8f3cca41b25af96fa8a 100644 (file)
@@ -50,7 +50,7 @@ struct rpc_pipe_client {
        struct pipe_auth_data *auth;
 
        /* The following is only non-null on a netlogon client pipe. */
-       struct netlogon_creds_CredentialState *dc;
+       struct netlogon_creds_cli_context *netlogon_creds;
 };
 
 #endif /* _RPC_CLIENT_H */
index d92434b23c7143f4e397e7104c5c054de3b7e884..2e0b5e5a8712bf09f6a5d33e74659b197401fa67 100644 (file)
@@ -26,6 +26,7 @@
 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
 #include "rpc_client/cli_netlogon.h"
 #include "secrets.h"
+#include "../libcli/auth/netlogon_creds_cli.h"
 
 static WERROR cmd_netlogon_logon_ctrl2(struct rpc_pipe_client *cli,
                                       TALLOC_CTX *mem_ctx, int argc,
@@ -630,8 +631,15 @@ static NTSTATUS cmd_netlogon_sam_sync(struct rpc_pipe_client *cli,
 
        do {
                struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
+               struct netlogon_creds_CredentialState *creds = NULL;
 
-               netlogon_creds_client_authenticator(cli->dc, &credential);
+               status = netlogon_creds_cli_lock(cli->netlogon_creds,
+                                                mem_ctx, &creds);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+
+               netlogon_creds_client_authenticator(creds, &credential);
 
                status = dcerpc_netr_DatabaseSync2(b, mem_ctx,
                                                   logon_server,
@@ -645,15 +653,18 @@ static NTSTATUS cmd_netlogon_sam_sync(struct rpc_pipe_client *cli,
                                                   0xffff,
                                                   &result);
                if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(creds);
                        return status;
                }
 
                /* Check returned credentials. */
-               if (!netlogon_creds_client_check(cli->dc,
+               if (!netlogon_creds_client_check(creds,
                                                 &return_authenticator.cred)) {
                        DEBUG(0,("credentials chain check failed\n"));
+                       TALLOC_FREE(creds);
                        return NT_STATUS_ACCESS_DENIED;
                }
+               TALLOC_FREE(creds);
 
                if (NT_STATUS_IS_ERR(result)) {
                        break;
@@ -699,8 +710,15 @@ static NTSTATUS cmd_netlogon_sam_deltas(struct rpc_pipe_client *cli,
 
        do {
                struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
+               struct netlogon_creds_CredentialState *creds = NULL;
+
+               status = netlogon_creds_cli_lock(cli->netlogon_creds,
+                                                mem_ctx, &creds);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
 
-               netlogon_creds_client_authenticator(cli->dc, &credential);
+               netlogon_creds_client_authenticator(creds, &credential);
 
                status = dcerpc_netr_DatabaseDeltas(b, mem_ctx,
                                                    logon_server,
@@ -713,15 +731,18 @@ static NTSTATUS cmd_netlogon_sam_deltas(struct rpc_pipe_client *cli,
                                                    0xffff,
                                                    &result);
                if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(creds);
                        return status;
                }
 
                /* Check returned credentials. */
-               if (!netlogon_creds_client_check(cli->dc,
+               if (!netlogon_creds_client_check(creds,
                                                 &return_authenticator.cred)) {
                        DEBUG(0,("credentials chain check failed\n"));
+                       TALLOC_FREE(creds);
                        return NT_STATUS_ACCESS_DENIED;
                }
+               TALLOC_FREE(creds);
 
                if (NT_STATUS_IS_ERR(result)) {
                        break;
@@ -1129,6 +1150,7 @@ static NTSTATUS cmd_netlogon_database_redo(struct rpc_pipe_client *cli,
        struct netr_ChangeLogEntry e;
        uint32_t rid = 500;
        struct dcerpc_binding_handle *b = cli->binding_handle;
+       struct netlogon_creds_CredentialState *creds = NULL;
 
        if (argc > 2) {
                fprintf(stderr, "Usage: %s <user rid>\n", argv[0]);
@@ -1158,7 +1180,13 @@ static NTSTATUS cmd_netlogon_database_redo(struct rpc_pipe_client *cli,
                return status;
        }
 
-       netlogon_creds_client_authenticator(cli->dc, &clnt_creds);
+       status = netlogon_creds_cli_lock(cli->netlogon_creds,
+                                        mem_ctx, &creds);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       netlogon_creds_client_authenticator(creds, &clnt_creds);
 
        ZERO_STRUCT(e);
 
@@ -1176,13 +1204,16 @@ static NTSTATUS cmd_netlogon_database_redo(struct rpc_pipe_client *cli,
                                          &delta_enum_array,
                                          &result);
        if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(creds);
                return status;
        }
 
-       if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) {
+       if (!netlogon_creds_client_check(creds, &srv_cred.cred)) {
                DEBUG(0,("credentials chain check failed\n"));
+               TALLOC_FREE(creds);
                return NT_STATUS_ACCESS_DENIED;
        }
+       TALLOC_FREE(creds);
 
        return result;
 }
@@ -1198,6 +1229,7 @@ static NTSTATUS cmd_netlogon_capabilities(struct rpc_pipe_client *cli,
        union netr_Capabilities capabilities;
        uint32_t level = 1;
        struct dcerpc_binding_handle *b = cli->binding_handle;
+       struct netlogon_creds_CredentialState *creds = NULL;
 
        if (argc > 2) {
                fprintf(stderr, "Usage: %s <level>\n", argv[0]);
@@ -1210,7 +1242,13 @@ static NTSTATUS cmd_netlogon_capabilities(struct rpc_pipe_client *cli,
 
        ZERO_STRUCT(return_authenticator);
 
-       netlogon_creds_client_authenticator(cli->dc, &credential);
+       status = netlogon_creds_cli_lock(cli->netlogon_creds,
+                                        mem_ctx, &creds);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       netlogon_creds_client_authenticator(creds, &credential);
 
        status = dcerpc_netr_LogonGetCapabilities(b, mem_ctx,
                                                  cli->desthost,
@@ -1221,14 +1259,17 @@ static NTSTATUS cmd_netlogon_capabilities(struct rpc_pipe_client *cli,
                                                  &capabilities,
                                                  &result);
        if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(creds);
                return status;
        }
 
-       if (!netlogon_creds_client_check(cli->dc,
+       if (!netlogon_creds_client_check(creds,
                                         &return_authenticator.cred)) {
                DEBUG(0,("credentials chain check failed\n"));
+               TALLOC_FREE(creds);
                return NT_STATUS_ACCESS_DENIED;
        }
+       TALLOC_FREE(creds);
 
        printf("capabilities: 0x%08x\n", capabilities.server_capabilities);
 
index afde6857f0a5b8d98bb6b5a7c520024161e3e617..b5fc010d07e4c7865f141b718391863787e3f6c3 100644 (file)
@@ -165,16 +165,7 @@ struct winbindd_domain {
        time_t startup_time;                   /* When we set "startup" true. monotonic clock */
        bool startup;                          /* are we in the first 30 seconds after startup_time ? */
 
-       bool can_do_samlogon_ex; /* Due to the lack of finer control what type
-                                 * of DC we have, let us try to do a
-                                 * credential-chain less samlogon_ex call
-                                 * with AD and schannel. If this fails with
-                                 * DCERPC_FAULT_OP_RNG_ERROR, then set this
-                                 * to False. This variable is around so that
-                                 * 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;
index 5d920d0a78215aca04c20b15706bfef23ceb557f..d08d7de13f8517728478e2adc38245cd3befdbdc 100644 (file)
@@ -2049,7 +2049,6 @@ static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
                                 domain->active_directory ? "" : "NOT "));
 
                        domain->can_do_ncacn_ip_tcp = domain->active_directory;
-                       domain->can_do_validation6 = domain->active_directory;
 
                        domain->initialized = True;
 
@@ -2250,7 +2249,6 @@ 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);
 
@@ -2291,7 +2289,7 @@ static void set_dc_type_and_flags( struct winbindd_domain *domain )
 ***********************************************************************/
 
 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
-                                  struct netlogon_creds_CredentialState **ppdc)
+                                  struct netlogon_creds_cli_context **ppdc)
 {
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        struct rpc_pipe_client *netlogon_pipe;
@@ -2308,11 +2306,11 @@ static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
        /* Return a pointer to the struct netlogon_creds_CredentialState from the
           netlogon pipe. */
 
-       if (!domain->conn.netlogon_pipe->dc) {
+       if (!domain->conn.netlogon_pipe->netlogon_creds) {
                return NT_STATUS_INTERNAL_ERROR; /* This shouldn't happen. */
        }
 
-       *ppdc = domain->conn.netlogon_pipe->dc;
+       *ppdc = domain->conn.netlogon_pipe->netlogon_creds;
        return NT_STATUS_OK;
 }
 
@@ -2321,7 +2319,7 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
 {
        struct winbindd_cm_conn *conn;
        NTSTATUS status, result;
-       struct netlogon_creds_CredentialState *p_creds;
+       struct netlogon_creds_cli_context *p_creds;
        char *machine_password = NULL;
        char *machine_account = NULL;
        const char *domain_name = NULL;
@@ -2433,7 +2431,7 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
        status = cli_rpc_pipe_open_schannel_with_key
                (conn->cli, &ndr_table_samr, NCACN_NP,
                 DCERPC_AUTH_LEVEL_PRIVACY,
-                domain->name, &p_creds, &conn->samr_pipe);
+                domain->name, p_creds, &conn->samr_pipe);
 
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
@@ -2536,7 +2534,7 @@ NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
                            struct rpc_pipe_client **cli)
 {
        struct winbindd_cm_conn *conn;
-       struct netlogon_creds_CredentialState *creds;
+       struct netlogon_creds_cli_context *creds;
        NTSTATUS status;
 
        DEBUG(10,("cm_connect_lsa_tcp\n"));
@@ -2567,7 +2565,7 @@ NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
                                                     NCACN_IP_TCP,
                                                     DCERPC_AUTH_LEVEL_PRIVACY,
                                                     domain->name,
-                                                    &creds,
+                                                    creds,
                                                     &conn->lsa_pipe_tcp);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
@@ -2591,7 +2589,7 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
 {
        struct winbindd_cm_conn *conn;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       struct netlogon_creds_CredentialState *p_creds;
+       struct netlogon_creds_cli_context *p_creds;
 
        result = init_dc_connection_rpc(domain);
        if (!NT_STATUS_IS_OK(result))
@@ -2664,7 +2662,7 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
        result = cli_rpc_pipe_open_schannel_with_key
                (conn->cli, &ndr_table_lsarpc, NCACN_NP,
                 DCERPC_AUTH_LEVEL_PRIVACY,
-                domain->name, &p_creds, &conn->lsa_pipe);
+                domain->name, p_creds, &conn->lsa_pipe);
 
        if (!NT_STATUS_IS_OK(result)) {
                DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
@@ -2828,10 +2826,6 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
  no_schannel:
        if ((lp_client_schannel() == False) ||
                        ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
-               /*
-                * NetSamLogonEx only works for schannel
-                */
-               domain->can_do_samlogon_ex = False;
 
                /* We're done - just keep the existing connection to NETLOGON
                 * open */
@@ -2847,7 +2841,8 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
 
        result = cli_rpc_pipe_open_schannel_with_key(
                conn->cli, &ndr_table_netlogon, NCACN_NP,
-               DCERPC_AUTH_LEVEL_PRIVACY, domain->name, &netlogon_pipe->dc,
+               DCERPC_AUTH_LEVEL_PRIVACY, domain->name,
+               netlogon_pipe->netlogon_creds,
                &conn->netlogon_pipe);
 
        /* We can now close the initial netlogon pipe. */
@@ -2861,15 +2856,6 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
                return result;
        }
 
-       /*
-        * Always try netr_LogonSamLogonEx. We will fall back for NT4
-        * which gives DCERPC_FAULT_OP_RNG_ERROR (function not
-        * supported). We used to only try SamLogonEx for AD, but
-        * Samba DCs can also do it. And because we don't distinguish
-        * between Samba and NT4, always try it once.
-        */
-       domain->can_do_samlogon_ex = true;
-
        *cli = conn->netlogon_pipe;
        return NT_STATUS_OK;
 }
index c356686488a83c9f46bd5df2629f8cce66f22396..39483a5d5e6341df5eb5f9563edab4b7792e0afe 100644 (file)
@@ -1228,8 +1228,6 @@ 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;
@@ -1278,75 +1276,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
                }
                netr_attempts = 0;
 
-               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
-                * one machine account from multiple physical
-                * computers.
-                *
-                * With a normal SamLogon call, we must keep the
-                * credentials chain updated and intact between all
-                * users of the machine account (which would imply
-                * cross-node communication for every NTLM logon).
-                *
-                * (The credentials chain is not per NETLOGON pipe
-                * connection, but globally on the server/client pair
-                * by machine name).
-                *
-                * When using SamLogonEx, the credentials are not
-                * supplied, but the session key is implied by the
-                * 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 && domain->can_do_validation6) {
-                       result = rpccli_netlogon_sam_network_logon_ex(
-                                       netlogon_pipe,
-                                       mem_ctx,
-                                       logon_parameters,
-                                       server,         /* server name */
-                                       username,       /* user name */
-                                       domainname,     /* target domain */
-                                       workstation,    /* workstation */
-                                       chal,
-                                       6,
-                                       lm_response,
-                                       nt_response,
-                                       info3);
-               } else {
-                       result = rpccli_netlogon_sam_network_logon(
+               result = rpccli_netlogon_sam_network_logon(
                                        netlogon_pipe,
                                        mem_ctx,
                                        logon_parameters,
@@ -1355,48 +1285,10 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
                                        domainname,     /* target domain */
                                        workstation,    /* workstation */
                                        chal,
-                                       domain->can_do_validation6 ? 6 : 3,
+                                       -1, /* ignored */
                                        lm_response,
                                        nt_response,
                                        info3);
-               }
-
-               if (NT_STATUS_EQUAL(result, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
-
-                       /*
-                        * It's likely that the server also does not support
-                        * validation level 6
-                        */
-                       domain->can_do_validation6 = false;
-
-                       if (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;
-                               retry = true;
-                               continue;
-                       }
-
-
-                       /* Got DCERPC_FAULT_OP_RNG_ERROR for SamLogon
-                        * (no Ex). This happens against old Samba
-                        * DCs. Drop the connection.
-                        */
-                       invalidate_cm_connection(&domain->conn);
-                       result = NT_STATUS_LOGON_FAILURE;
-                       break;
-               }
-
-               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"
@@ -1428,6 +1320,30 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
                        retry = true;
                }
 
+               if (NT_STATUS_EQUAL(result, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
+                       /*
+                        * Got DCERPC_FAULT_OP_RNG_ERROR for SamLogon
+                        * (no Ex). This happens against old Samba
+                        * DCs, if LogonSamLogonEx() fails with an error
+                        * e.g. NT_STATUS_NO_SUCH_USER or NT_STATUS_WRONG_PASSWORD.
+                        *
+                        * The server will log something like this:
+                        * api_net_sam_logon_ex: Failed to marshall NET_R_SAM_LOGON_EX.
+                        *
+                        * This sets the whole connection into a fault_state mode
+                        * and all following request get NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE.
+                        *
+                        * This also happens to our retry with LogonSamLogonWithFlags()
+                        * and LogonSamLogon().
+                        *
+                        * In order to recover from this situation, we need to
+                        * drop the connection.
+                        */
+                       invalidate_cm_connection(&domain->conn);
+                       result = NT_STATUS_LOGON_FAILURE;
+                       break;
+               }
+
        } while ( (attempts < 2) && retry );
 
        if (NT_STATUS_EQUAL(result, NT_STATUS_IO_TIMEOUT)) {
index ecddfd9dca6b6c59f54091ea9cd5007ace249661..c5dc521cf62b2c90cf6ef5e353835c8688632f7f 100755 (executable)
@@ -84,8 +84,8 @@ bld.SAMBA3_LIBRARY('msrpc3',
                    deps='''ndr ndr-standard
                     RPC_NDR_EPMAPPER NTLMSSP_COMMON COMMON_SCHANNEL LIBCLI_AUTH
                     LIBTSOCKET gse dcerpc-binding
-                    libsmb
-                    ndr-table''',
+                    libsmb ndr-table NETLOGON_CREDS_CLI
+                   ''',
                    private_library=True)
 
 bld.SAMBA3_LIBRARY('gpo',
@@ -763,7 +763,7 @@ bld.SAMBA3_LIBRARY('libcli_lsa3',
 
 bld.SAMBA3_LIBRARY('libcli_netlogon3',
                    source='rpc_client/cli_netlogon.c rpc_client/util_netlogon.c',
-                   deps='RPC_NDR_NETLOGON INIT_NETLOGON cliauth param',
+                   deps='msrpc3 RPC_NDR_NETLOGON INIT_NETLOGON cliauth param NETLOGON_CREDS_CLI',
                    private_library=True)
 
 bld.SAMBA3_LIBRARY('cli_spoolss',