The branch, v3-6-test has been updated
       via  79d1684... s3-dcerpc: avoid talloc_move on schannel creds in 
cli_rpc_pipe_open_schannel_with_key().
      from  af953d6... Final part of fix for bug #7636 - winbind internal 
error, backtrace.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test


- Log -----------------------------------------------------------------
commit 79d16843acdfe72a73ba175604cdff0a3c4e2e19
Author: Günther Deschner <g...@samba.org>
Date:   Mon Aug 23 16:02:23 2010 +0200

    s3-dcerpc: avoid talloc_move on schannel creds in 
cli_rpc_pipe_open_schannel_with_key().
    
    Initially, the schannel creds were talloc memduped, then, during the 
netlogon
    creds client merge (baf7274fed2f1ae7a9e3a57160bf5471566e636c) they were 
first
    talloc_referenced and then later (53765c81f726a8c056cc4e57004592dd489975c9)
    talloc_moved.
    
    The issue with using talloc_move here is that users of that function in 
winbind
    will only be able to have two schanneled connections, as the cached schannel
    credentials pointer from the netlogon pipe will be set to NULL. Do a deep 
copy
    of the struct instead.
    
    Guenther
    (cherry picked from commit 898c6123355a3a11ec17f0396c4cb3018c75c184)

-----------------------------------------------------------------------

Summary of changes:
 libcli/auth/credentials.c     |   46 ++++++++++++++++++++++++++++++++++++++++-
 libcli/auth/proto.h           |    2 +
 source3/rpc_client/cli_pipe.c |   10 ++++++--
 3 files changed, 54 insertions(+), 4 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c
index 667a2fa..8130476 100644
--- a/libcli/auth/credentials.c
+++ b/libcli/auth/credentials.c
@@ -24,6 +24,7 @@
 #include "system/time.h"
 #include "../lib/crypto/crypto.h"
 #include "libcli/auth/libcli_auth.h"
+#include "../libcli/security/dom_sid.h"
 
 static void netlogon_creds_step_crypt(struct netlogon_creds_CredentialState 
*creds,
                                      const struct netr_Credential *in,
@@ -202,7 +203,7 @@ struct netlogon_creds_CredentialState 
*netlogon_creds_client_init(TALLOC_CTX *me
                                                                  struct 
netr_Credential *initial_credential,
                                                                  uint32_t 
negotiate_flags)
 {
-       struct netlogon_creds_CredentialState *creds = talloc(mem_ctx, struct 
netlogon_creds_CredentialState);
+       struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, 
struct netlogon_creds_CredentialState);
        
        if (!creds) {
                return NULL;
@@ -454,3 +455,46 @@ void netlogon_creds_decrypt_samlogon(struct 
netlogon_creds_CredentialState *cred
        }
 }      
 
+/*
+  copy a netlogon_creds_CredentialState struct
+*/
+
+struct netlogon_creds_CredentialState *netlogon_creds_copy(TALLOC_CTX *mem_ctx,
+                                                          struct 
netlogon_creds_CredentialState *creds_in)
+{
+       struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, 
struct netlogon_creds_CredentialState);
+
+       if (!creds) {
+               return NULL;
+       }
+
+       creds->sequence                 = creds_in->sequence;
+       creds->negotiate_flags          = creds_in->negotiate_flags;
+       creds->secure_channel_type      = creds_in->secure_channel_type;
+
+       creds->computer_name = talloc_strdup(creds, creds_in->computer_name);
+       if (!creds->computer_name) {
+               talloc_free(creds);
+               return NULL;
+       }
+       creds->account_name = talloc_strdup(creds, creds_in->account_name);
+       if (!creds->account_name) {
+               talloc_free(creds);
+               return NULL;
+       }
+
+       if (creds_in->sid) {
+               creds->sid = dom_sid_dup(creds, creds_in->sid);
+               if (!creds->sid) {
+                       talloc_free(creds);
+                       return NULL;
+               }
+       }
+
+       memcpy(creds->session_key, creds_in->session_key, 
sizeof(creds->session_key));
+       memcpy(creds->seed.data, creds_in->seed.data, sizeof(creds->seed.data));
+       memcpy(creds->client.data, creds_in->client.data, 
sizeof(creds->client.data));
+       memcpy(creds->server.data, creds_in->server.data, 
sizeof(creds->server.data));
+
+       return creds;
+}
diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h
index 2734db0..34a0052 100644
--- a/libcli/auth/proto.h
+++ b/libcli/auth/proto.h
@@ -35,6 +35,8 @@ void netlogon_creds_client_authenticator(struct 
netlogon_creds_CredentialState *
                                struct netr_Authenticator *next);
 bool netlogon_creds_client_check(struct netlogon_creds_CredentialState *creds,
                        const struct netr_Credential *received_credentials);
+struct netlogon_creds_CredentialState *netlogon_creds_copy(TALLOC_CTX *mem_ctx,
+                                                          struct 
netlogon_creds_CredentialState *creds_in);
 
 /*****************************************************************
 The above functions are common to the client and server interface
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index d3e0c60..0be71db 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -2198,7 +2198,7 @@ NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, 
const char *domain,
        result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
        result->a_u.schannel_auth->seq_num = 0;
        result->a_u.schannel_auth->initiator = true;
-       result->a_u.schannel_auth->creds = creds;
+       result->a_u.schannel_auth->creds = netlogon_creds_copy(result, creds);
 
        *presult = result;
        return NT_STATUS_OK;
@@ -2913,9 +2913,13 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct 
cli_state *cli,
 
        /*
         * The credentials on a new netlogon pipe are the ones we are passed
-        * in - reference them in
+        * in - copy them over
         */
-       result->dc = talloc_move(result, pdc);
+       result->dc = netlogon_creds_copy(result, *pdc);
+       if (result->dc == NULL) {
+               TALLOC_FREE(result);
+               return NT_STATUS_NO_MEMORY;
+       }
 
        DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to 
machine %s "
                  "for domain %s and bound using schannel.\n",


-- 
Samba Shared Repository

Reply via email to