From 85e9412c4786ede6f94d879185d493756d37eebe Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 1 May 2005 19:29:00 +0000 Subject: r6565: Cludge, cludge, cludge... 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 (This used to be commit 8ee208a926d2b15fdc42753b1f9ee586564c6248) --- source4/auth/auth_domain.c | 2 +- source4/auth/auth_sam.c | 12 ++++-------- source4/include/credentials.h | 1 + source4/include/includes.h | 2 +- source4/include/structs.h | 1 - source4/lib/credentials.c | 31 ++++++++++++++++++++++++++++++- source4/librpc/idl/misc.idl | 9 +++++++++ source4/librpc/idl/netlogon.idl | 11 +---------- source4/librpc/rpc/dcerpc.h | 9 ++------- source4/librpc/rpc/dcerpc_schannel.c | 18 ++++-------------- source4/librpc/rpc/dcerpc_util.c | 6 +++--- source4/setup/provision.ldif | 1 + source4/torture/rpc/samlogon.c | 4 +++- source4/torture/rpc/samsync.c | 8 ++++++-- source4/torture/rpc/schannel.c | 26 ++++++++++++++++++-------- 15 files changed, 84 insertions(+), 57 deletions(-) diff --git a/source4/auth/auth_domain.c b/source4/auth/auth_domain.c index a6950445cb..4e5acf36e3 100644 --- a/source4/auth/auth_domain.c +++ b/source4/auth/auth_domain.c @@ -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, diff --git a/source4/auth/auth_sam.c b/source4/auth/auth_sam.c index b2aeff78d8..1e6c865361 100644 --- a/source4/auth/auth_sam.c +++ b/source4/auth/auth_sam.c @@ -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); diff --git a/source4/include/credentials.h b/source4/include/credentials.h index e7df58f217..309fff056e 100644 --- a/source4/include/credentials.h +++ b/source4/include/credentials.h @@ -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 */ diff --git a/source4/include/includes.h b/source4/include/includes.h index ce78e14d7d..65cbd1b777 100644 --- a/source4/include/includes.h +++ b/source4/include/includes.h @@ -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) diff --git a/source4/include/structs.h b/source4/include/structs.h index 80a1df8383..4e29ef8d50 100644 --- a/source4/include/structs.h +++ b/source4/include/structs.h @@ -201,4 +201,3 @@ struct wrepl_pull_table; struct wrepl_pull_names; struct arcfour_state; - diff --git a/source4/lib/credentials.c b/source4/lib/credentials.c index db796cde35..64e3b9958d 100644 --- a/source4/lib/credentials.c +++ b/source4/lib/credentials.c @@ -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 */ diff --git a/source4/librpc/idl/misc.idl b/source4/librpc/idl/misc.idl index 935032f305..45f4e25602 100644 --- a/source4/librpc/idl/misc.idl +++ b/source4/librpc/idl/misc.idl @@ -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; } diff --git a/source4/librpc/idl/netlogon.idl b/source4/librpc/idl/netlogon.idl index 0e601b372a..e32b1ee86d 100644 --- a/source4/librpc/idl/netlogon.idl +++ b/source4/librpc/idl/netlogon.idl @@ -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, diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index db7b76a779..89a969a118 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -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) diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c index 3ae2624ff9..cc6cbe7b46 100644 --- a/source4/librpc/rpc/dcerpc_schannel.c +++ b/source4/librpc/rpc/dcerpc_schannel.c @@ -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", diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index d1d9977b39..763ec55e50 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -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); diff --git a/source4/setup/provision.ldif b/source4/setup/provision.ldif index f6cce3e285..466f567cda 100644 --- a/source4/setup/provision.ldif +++ b/source4/setup/provision.ldif @@ -51,6 +51,7 @@ objectClass: top objectClass: domain objectClass: domainDNS name: ${DOMAIN} +flatname: ${DOMAIN} realm: ${REALM} dnsDomain: ${DNSDOMAIN} dc: ${DOMAIN} diff --git a/source4/torture/rpc/samlogon.c b/source4/torture/rpc/samlogon.c index 86bfe48a75..9a9c3039d2 100644 --- a/source4/torture/rpc/samlogon.c +++ b/source4/torture/rpc/samlogon.c @@ -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, diff --git a/source4/torture/rpc/samsync.c b/source4/torture/rpc/samsync.c index 412b27c8ec..0a17b2646b 100644 --- a/source4/torture/rpc/samsync.c +++ b/source4/torture/rpc/samsync.c @@ -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, diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c index de0e1caa64..75f9198106 100644 --- a/source4/torture/rpc/schannel.c +++ b/source4/torture/rpc/schannel.c @@ -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; -- cgit