r6565: Cludge, cludge, cludge...
authorAndrew Bartlett <abartlet@samba.org>
Sun, 1 May 2005 19:29:00 +0000 (19:29 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:16:26 +0000 (13:16 -0500)
We need to pass the 'secure channel type' to the NETLOGON layer, which
must match the account type.

(Yes, jelmer objects to this inclusion of the kitchen sink ;-)

Andrew Bartlett

15 files changed:
source/auth/auth_domain.c
source/auth/auth_sam.c
source/include/credentials.h
source/include/includes.h
source/include/structs.h
source/lib/credentials.c
source/librpc/idl/misc.idl
source/librpc/idl/netlogon.idl
source/librpc/rpc/dcerpc.h
source/librpc/rpc/dcerpc_schannel.c
source/librpc/rpc/dcerpc_util.c
source/setup/provision.ldif
source/torture/rpc/samlogon.c
source/torture/rpc/samsync.c
source/torture/rpc/schannel.c

index a6950445cbcf7fb16882c2e3ebbc97ecd5c7fa40..4e5acf36e3635b8555272a607d79ea0708cdcb26 100644 (file)
@@ -76,7 +76,7 @@ static NTSTATUS domain_check_password(struct auth_method_context *ctx,
 
        /* We like schannel */
        b->flags &= ~DCERPC_AUTH_OPTIONS;
-       b->flags |= DCERPC_SCHANNEL_WORKSTATION | DCERPC_SEAL | DCERPC_SCHANNEL_128;
+       b->flags |= DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_128;
 
        /* Setup schannel */
        status = dcerpc_pipe_connect_b(mem_ctx, &p, b, 
index b2aeff78d88b03fa42808de5e7fef0dd84536001..1e6c8653616063ddfa1898a72c0d93fda9d2cd88 100644 (file)
@@ -210,12 +210,12 @@ static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, void *sam_ctx,
                               NULL,
        };
 
-       const char *domain_attrs[] =  {"name", "objectSid"};
+       const char *domain_attrs[] =  {"flatname", "objectSid"};
 
        if (domain_name) {
                /* find the domain's DN */
                ret_domain = gendb_search(sam_ctx, mem_ctx, NULL, &msgs_domain, domain_attrs,
-                                         "(&(|(realm=%s)(name=%s))(objectclass=domain))", 
+                                         "(&(|(realm=%s)(flatname=%s))(objectclass=domain))", 
                                          domain_name, domain_name);
                if (ret_domain == -1) {
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
@@ -410,13 +410,9 @@ static NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, void *sam_ctx,
        server_info->n_domain_groups = group_ret;
        server_info->domain_groups = groupSIDs;
 
-       str = samdb_result_string(msgs[0], "sAMAccountName", "");
-       server_info->account_name = talloc_strdup(server_info, str);
-       NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
+       server_info->account_name = talloc_reference(server_info, samdb_result_string(msgs[0], "sAMAccountName", NULL));
 
-       str = samdb_result_string(msgs_domain[0], "name", "");
-       server_info->domain_name = talloc_strdup(server_info, str);
-       NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
+       server_info->domain_name = talloc_reference(server_info, samdb_result_string(msgs_domain[0], "flatname", NULL));
 
        str = samdb_result_string(msgs[0], "displayName", "");
        server_info->full_name = talloc_strdup(server_info, str);
index e7df58f2179a0c3e7f2e7fa31bd3dc14883d78f1..309fff056e04ee32d299e1ef5f9049c1ab0cb138 100644 (file)
@@ -55,6 +55,7 @@ struct cli_credentials {
        void *priv_data;
 
        struct creds_CredentialState *netlogon_creds;
+       enum netr_SchannelType secure_channel_type;
 
        /* We are flagged to get machine account details from the
         * secrets.ldb when we are asked for a username or password */
index ce78e14d7db2022d351612a9edcc7d10a251a3ce..65cbd1b7778163855d3b8107d48d52c2cf372193 100644 (file)
@@ -123,7 +123,6 @@ extern int errno;
 #include "smb.h"
 #include "byteorder.h"
 #include "module.h"
-#include "credentials.h"
 #include "librpc/ndr/libndr.h"
 #include "librpc/gen_ndr/ndr_misc.h"
 #include "librpc/gen_ndr/ndr_dcerpc.h"
@@ -134,6 +133,7 @@ extern int errno;
 #include "ntvfs/ntvfs.h"
 #include "cli_context.h"
 #include "lib/com/com.h"
+#include "credentials.h"
 
 #define malloc_p(type) (type *)malloc(sizeof(type))
 #define malloc_array_p(type, count) (type *)realloc_array(NULL, sizeof(type), count)
index 80a1df8383bf25d608be909d30c1c29226e4b514..4e29ef8d507b848725b4c8cd158b5646c45c9145 100644 (file)
@@ -201,4 +201,3 @@ struct wrepl_pull_table;
 struct wrepl_pull_names;
 
 struct arcfour_state;
-
index db796cde3543549100c3cb88fbcff4c4fe39006c..64e3b9958d2cf2bfb504ddcfa47624f9c625152c 100644 (file)
@@ -465,6 +465,7 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
        const char *password;
        const char *domain;
        const char *realm;
+       enum netr_SchannelType sct;
        
        /* ok, we are going to get it now, don't recurse back here */
        cred->machine_account_pending = False;
@@ -510,6 +511,15 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
                return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
        }
        
+       sct = ldb_msg_find_int(msgs[0], "secureChannelType", 0);
+       if (!sct) {
+               cli_credentials_set_secure_channel_type(cred, sct);
+       } else {
+               DEBUG(1, ("Domain join for acocunt %s did not have a secureChannelType set!\n",
+                         machine_account));
+               return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+       }
+       
        domain = ldb_msg_find_string(msgs[0], "flatname", NULL);
        if (domain) {
                cli_credentials_set_domain(cred, domain, CRED_SPECIFIED);
@@ -519,7 +529,7 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
        if (realm) {
                cli_credentials_set_realm(cred, realm, CRED_SPECIFIED);
        }
-       
+
        cli_credentials_set_username(cred, machine_account, CRED_SPECIFIED);
        cli_credentials_set_password(cred, password, CRED_SPECIFIED);
        talloc_free(mem_ctx);
@@ -560,6 +570,25 @@ struct creds_CredentialState *cli_credentials_get_netlogon_creds(struct cli_cred
        return cred->netlogon_creds;
 }
 
+/** 
+ * Set NETLOGON secure channel type
+ */
+
+void cli_credentials_set_secure_channel_type(struct cli_credentials *cred,
+                                            enum netr_SchannelType secure_channel_type)
+{
+       cred->secure_channel_type = secure_channel_type;
+}
+
+/**
+ * Return NETLOGON secure chanel type
+ */
+
+enum netr_SchannelType cli_credentials_get_secure_channel_type(struct cli_credentials *cred)
+{
+       return cred->secure_channel_type;
+}
+
 /**
  * Fill in a credentials structure as the anonymous user
  */
index 935032f30575ab5b08b7cee325b06d2cc4406bbe..45f4e256020f7b94978edea15fdcdc93fdd020e7 100644 (file)
@@ -22,4 +22,13 @@ interface misc
                uint32 handle_type;
                GUID   uuid;
        } policy_handle;
+
+       /* secure channel types */
+       /* Only SEC_CHAN_WKSTA can forward requests to other domains. */
+
+       typedef [public] enum {
+               SEC_CHAN_WKSTA   = 2,
+               SEC_CHAN_DOMAIN  = 4,
+               SEC_CHAN_BDC     = 6
+       } netr_SchannelType;
 }
index 0e601b372a278f1c0993e49c6c32b5026ff0fb57..e32b1ee86d5c68b6757c0a928f4d30b09d51258b 100644 (file)
@@ -248,7 +248,7 @@ interface netlogon
                [in] uint16 logon_level,
                [in] [switch_is(logon_level)] netr_LogonLevel logon
                );
-
+       
 
 
        /*****************/
@@ -264,15 +264,6 @@ interface netlogon
        /*****************/
        /* Function 0x05 */
 
-       /* secure channel types */
-       /* Only SEC_CHAN_WKSTA can forward requests to other domains. */
-
-       typedef enum {
-               SEC_CHAN_WKSTA   = 2,
-               SEC_CHAN_DOMAIN  = 4,
-               SEC_CHAN_BDC     = 6
-       } netr_SchannelType;
-
        NTSTATUS netr_ServerAuthenticate(
                [in]         unistr *server_name,
                [in]         unistr account_name,
index db7b76a7796fd1891fb70e9608144d608287a7ff..89a969a118da24c5e8325da92647e8087ae15e28 100644 (file)
@@ -113,12 +113,7 @@ struct dcerpc_pipe {
 #define DCERPC_PUSH_BIGENDIAN          (1<<7)
 #define DCERPC_PULL_BIGENDIAN          (1<<8)
 
-#define DCERPC_SCHANNEL_BDC            (1<<9)
-#define DCERPC_SCHANNEL_WORKSTATION    (1<<10)
-#define DCERPC_SCHANNEL_DOMAIN         (1<<11)
-#define DCERPC_SCHANNEL_ANY            (DCERPC_SCHANNEL_BDC| \
-                                       DCERPC_SCHANNEL_DOMAIN| \
-                                       DCERPC_SCHANNEL_WORKSTATION)
+#define DCERPC_SCHANNEL                (1<<9)
 
 /* use a 128 bit session key */
 #define DCERPC_SCHANNEL_128            (1<<12)
@@ -129,7 +124,7 @@ struct dcerpc_pipe {
 /* set LIBNDR_FLAG_REF_ALLOC flag when decoding NDR */
 #define DCERPC_NDR_REF_ALLOC           (1<<14)
 
-#define DCERPC_AUTH_OPTIONS    (DCERPC_SEAL|DCERPC_SIGN|DCERPC_SCHANNEL_ANY|DCERPC_AUTH_SPNEGO|DCERPC_AUTH_KRB5)
+#define DCERPC_AUTH_OPTIONS    (DCERPC_SEAL|DCERPC_SIGN|DCERPC_SCHANNEL|DCERPC_AUTH_SPNEGO|DCERPC_AUTH_KRB5)
 
 /* enable spnego auth */
 #define DCERPC_AUTH_SPNEGO             (1<<15)
index 3ae2624ff9df208b407b138cc76b027c1406f1a5..cc6cbe7b4685209fc7c525f3f6f591e8923ebeb7 100644 (file)
@@ -30,8 +30,7 @@
 */
 static NTSTATUS dcerpc_schannel_key(TALLOC_CTX *tmp_ctx, 
                                    struct dcerpc_pipe *p,
-                                   struct cli_credentials *credentials,
-                                   int chan_type)
+                                   struct cli_credentials *credentials)
 {
        NTSTATUS status;
        struct dcerpc_binding *b;
@@ -109,7 +108,8 @@ static NTSTATUS dcerpc_schannel_key(TALLOC_CTX *tmp_ctx,
 
        a.in.server_name = r.in.server_name;
        a.in.account_name = cli_credentials_get_username(credentials);
-       a.in.secure_channel_type = chan_type;
+       a.in.secure_channel_type = 
+               cli_credentials_get_secure_channel_type(credentials);
        a.in.computer_name = cli_credentials_get_workstation(credentials);
        a.in.negotiate_flags = &negotiate_flags;
        a.out.negotiate_flags = &negotiate_flags;
@@ -143,20 +143,10 @@ NTSTATUS dcerpc_bind_auth_schannel(TALLOC_CTX *tmp_ctx,
                                   struct cli_credentials *credentials)
 {
        NTSTATUS status;
-       int chan_type = 0;
-
-       if (p->conn->flags & DCERPC_SCHANNEL_BDC) {
-               chan_type = SEC_CHAN_BDC;
-       } else if (p->conn->flags & DCERPC_SCHANNEL_WORKSTATION) {
-               chan_type = SEC_CHAN_WKSTA;
-       } else if (p->conn->flags & DCERPC_SCHANNEL_DOMAIN) {
-               chan_type = SEC_CHAN_DOMAIN;
-       }
 
        /* Fills in NETLOGON credentials */
        status = dcerpc_schannel_key(tmp_ctx, 
-                                    p, credentials,
-                                    chan_type);
+                                    p, credentials);
 
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to setup credentials for account %s: %s\n",
index d1d9977b39946eac73680b97eedf28cf8efe2f95..763ec55e5009d379eff1f4326a70fbc2b259e733 100644 (file)
@@ -927,7 +927,7 @@ NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p,
        p->conn->binding_string = dcerpc_binding_string(p, binding);
 
        if (!cli_credentials_is_anonymous(credentials) &&
-               (binding->flags & DCERPC_SCHANNEL_ANY) && 
+               (binding->flags & DCERPC_SCHANNEL) && 
                !cli_credentials_get_netlogon_creds(credentials)) {
                
                /* If we don't already have netlogon credentials for
@@ -952,7 +952,7 @@ NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p,
                        auth_type = DCERPC_AUTH_TYPE_SPNEGO;
                } else if (binding->flags & DCERPC_AUTH_KRB5) {
                        auth_type = DCERPC_AUTH_TYPE_KRB5;
-               } else if (binding->flags & DCERPC_SCHANNEL_ANY) {
+               } else if (binding->flags & DCERPC_SCHANNEL) {
                        auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
                } else {
                        auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
@@ -986,7 +986,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(TALLOC_CTX *tmp_ctx,
        struct smbcli_state *cli;
        const char *pipe_name = NULL;
 
-       if (binding->flags & DCERPC_SCHANNEL_ANY) {
+       if (binding->flags & DCERPC_SCHANNEL) {
                struct cli_credentials *anon_creds
                        = cli_credentials_init(tmp_ctx);
                cli_credentials_set_anonymous(anon_creds);
index f6cce3e2859ff02abb75401d75255b17f37f3f9d..466f567cda7779e729968da2b82eb118bcc5d626 100644 (file)
@@ -51,6 +51,7 @@ objectClass: top
 objectClass: domain
 objectClass: domainDNS
 name: ${DOMAIN}
+flatname: ${DOMAIN}
 realm: ${REALM}
 dnsDomain: ${DNSDOMAIN}
 dc: ${DOMAIN}
index 86bfe48a7585248255fbffeb3e2251d47b9be886..9a9c3039d2f69841db88d5c18999fd8e70da8ffc 100644 (file)
@@ -1345,12 +1345,14 @@ BOOL torture_rpc_samlogon(void)
         * with INTERNAL_ERROR */
 
        b->flags &= ~DCERPC_AUTH_OPTIONS;
-       b->flags |= DCERPC_SCHANNEL_WORKSTATION | DCERPC_SIGN | DCERPC_SCHANNEL_128;
+       b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
 
        cli_credentials_set_workstation(credentials, TEST_MACHINE_NAME, CRED_SPECIFIED);
        cli_credentials_set_domain(credentials, lp_workgroup(), CRED_SPECIFIED);
        cli_credentials_set_username(credentials, test_machine_account, CRED_SPECIFIED);
        cli_credentials_set_password(credentials, machine_password, CRED_SPECIFIED);
+       cli_credentials_set_secure_channel_type(credentials,
+                                               SEC_CHAN_WKSTA);
 
        status = dcerpc_pipe_connect_b(mem_ctx, &p, b, 
                                       DCERPC_NETLOGON_UUID,
index 412b27c8ec0e50213606892023b77a4f8edf5245..0a17b2646bd0c328caf517f85e6c7b79a8ef7f06 100644 (file)
@@ -1499,7 +1499,7 @@ BOOL torture_rpc_samsync(void)
        }
 
        b->flags &= ~DCERPC_AUTH_OPTIONS;
-       b->flags |= DCERPC_SCHANNEL_BDC | DCERPC_SIGN;
+       b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN;
 
        credentials = cli_credentials_init(mem_ctx);
 
@@ -1507,6 +1507,8 @@ BOOL torture_rpc_samsync(void)
        cli_credentials_set_domain(credentials, lp_workgroup(), CRED_SPECIFIED);
        cli_credentials_set_username(credentials, test_machine_account, CRED_SPECIFIED);
        cli_credentials_set_password(credentials, machine_password, CRED_SPECIFIED);
+       cli_credentials_set_secure_channel_type(credentials,
+                                               SEC_CHAN_BDC);
 
        status = dcerpc_pipe_connect_b(samsync_state,
                                       &samsync_state->p, b, 
@@ -1536,7 +1538,7 @@ BOOL torture_rpc_samsync(void)
        }
 
        b_netlogon_wksta->flags &= ~DCERPC_AUTH_OPTIONS;
-       b_netlogon_wksta->flags |= DCERPC_SCHANNEL_WORKSTATION | DCERPC_SIGN;
+       b_netlogon_wksta->flags |= DCERPC_SCHANNEL | DCERPC_SIGN;
 
        credentials_wksta = cli_credentials_init(mem_ctx);
 
@@ -1544,6 +1546,8 @@ BOOL torture_rpc_samsync(void)
        cli_credentials_set_domain(credentials_wksta, lp_workgroup(), CRED_SPECIFIED);
        cli_credentials_set_username(credentials_wksta, test_wksta_machine_account, CRED_SPECIFIED);
        cli_credentials_set_password(credentials_wksta, wksta_machine_password, CRED_SPECIFIED);
+       cli_credentials_set_secure_channel_type(credentials_wksta,
+                                               SEC_CHAN_WKSTA);
 
        status = dcerpc_pipe_connect_b(samsync_state, 
                                       &samsync_state->p_netlogon_wksta, 
index de0e1caa64131c3d717648fa5fde6c2366d86808..75f91981062bd664d7f72397f899b96c22123814 100644 (file)
@@ -157,6 +157,16 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx,
        cli_credentials_set_username(credentials, test_machine_account, CRED_SPECIFIED);
        cli_credentials_set_password(credentials, machine_password, CRED_SPECIFIED);
 
+       if (acct_flags == ACB_WSTRUST) {
+               cli_credentials_set_secure_channel_type(credentials,
+                                                       SEC_CHAN_WKSTA);
+       } else if (acct_flags == ACB_SVRTRUST) {
+               cli_credentials_set_secure_channel_type(credentials,
+                                                       SEC_CHAN_BDC);
+       } else {
+               goto failed;
+       }
+
        status = dcerpc_pipe_connect_b(test_ctx, 
                                       &p, b, 
                                       DCERPC_SAMR_UUID,
@@ -238,14 +248,14 @@ BOOL torture_rpc_schannel(void)
                uint32_t dcerpc_flags;
                uint32_t schannel_type;
        } tests[] = {
-               { ACB_WSTRUST,   DCERPC_SCHANNEL_WORKSTATION | DCERPC_SIGN,                       3 },
-               { ACB_WSTRUST,   DCERPC_SCHANNEL_WORKSTATION | DCERPC_SEAL,                       3 },
-               { ACB_WSTRUST,   DCERPC_SCHANNEL_WORKSTATION | DCERPC_SIGN | DCERPC_SCHANNEL_128, 3 },
-               { ACB_WSTRUST,   DCERPC_SCHANNEL_WORKSTATION | DCERPC_SEAL | DCERPC_SCHANNEL_128, 3 },
-               { ACB_SVRTRUST,  DCERPC_SCHANNEL_BDC | DCERPC_SIGN,                               3 },
-               { ACB_SVRTRUST,  DCERPC_SCHANNEL_BDC | DCERPC_SEAL,                               3 },
-               { ACB_SVRTRUST,  DCERPC_SCHANNEL_BDC | DCERPC_SIGN | DCERPC_SCHANNEL_128,         3 },
-               { ACB_SVRTRUST,  DCERPC_SCHANNEL_BDC | DCERPC_SEAL | DCERPC_SCHANNEL_128,         3 }
+               { ACB_WSTRUST,   DCERPC_SCHANNEL | DCERPC_SIGN,                       3 },
+               { ACB_WSTRUST,   DCERPC_SCHANNEL | DCERPC_SEAL,                       3 },
+               { ACB_WSTRUST,   DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128, 3 },
+               { ACB_WSTRUST,   DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_128, 3 },
+               { ACB_SVRTRUST,  DCERPC_SCHANNEL | DCERPC_SIGN,                               3 },
+               { ACB_SVRTRUST,  DCERPC_SCHANNEL | DCERPC_SEAL,                               3 },
+               { ACB_SVRTRUST,  DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128,         3 },
+               { ACB_SVRTRUST,  DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_128,         3 }
        };
        int i;