mirror of
https://github.com/samba-team/samba.git
synced 2025-01-21 18:04:06 +03:00
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)
This commit is contained in:
parent
7fca1d46ce
commit
85e9412c47
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -201,4 +201,3 @@ struct wrepl_pull_table;
|
||||
struct wrepl_pull_names;
|
||||
|
||||
struct arcfour_state;
|
||||
|
||||
|
@ -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);
|
||||
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -51,6 +51,7 @@ objectClass: top
|
||||
objectClass: domain
|
||||
objectClass: domainDNS
|
||||
name: ${DOMAIN}
|
||||
flatname: ${DOMAIN}
|
||||
realm: ${REALM}
|
||||
dnsDomain: ${DNSDOMAIN}
|
||||
dc: ${DOMAIN}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user