mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
commit sign only patch from Andrew; bug 167; tested using 2k & XP clientspreviously joined to the Samba domain
This commit is contained in:
parent
202d4e4652
commit
9d2e585e5e
@ -61,8 +61,14 @@ enum RPC_PKT_TYPE
|
||||
|
||||
/* Netlogon schannel auth type and level */
|
||||
#define NETSEC_AUTH_TYPE 0x44
|
||||
#define NETSEC_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 }
|
||||
#define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 }
|
||||
#define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 }
|
||||
#define RPC_AUTH_NETSEC_CHK_LEN 0x20
|
||||
|
||||
/* The 7 here seems to be required to get Win2k not to downgrade us
|
||||
to NT4. Actually, anything other than 1ff would seem to do... */
|
||||
#define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff
|
||||
|
||||
#define NETLOGON_NEG_SCHANNEL 0x40000000
|
||||
|
||||
enum netsec_direction
|
||||
@ -239,13 +245,14 @@ typedef struct rpc_auth_netsec_chk_info
|
||||
uint8 sig [8]; /* 77 00 7a 00 ff ff 00 00 */
|
||||
uint8 packet_digest[8]; /* checksum over the packet, MD5'ed with session key */
|
||||
uint8 seq_num[8]; /* verifier, seq num */
|
||||
uint8 data8[8]; /* random 8-byte nonce */
|
||||
uint8 confounder[8]; /* random 8-byte nonce */
|
||||
} RPC_AUTH_NETSEC_CHK;
|
||||
|
||||
struct netsec_auth_struct
|
||||
{
|
||||
uchar sess_key[16];
|
||||
uint32 seq_num;
|
||||
int auth_flags;
|
||||
};
|
||||
|
||||
/* RPC_BIND_REQ - ms req bind */
|
||||
|
@ -29,7 +29,9 @@
|
||||
|
||||
extern struct pipe_id_info pipe_names[];
|
||||
|
||||
static void get_auth_type_level(int pipe_auth_flags, int *auth_type, int *auth_level)
|
||||
/* convert pipe auth flags into the RPC auth type and level */
|
||||
|
||||
void get_auth_type_level(int pipe_auth_flags, int *auth_type, int *auth_level)
|
||||
{
|
||||
*auth_type = 0;
|
||||
*auth_level = 0;
|
||||
@ -938,7 +940,6 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
|
||||
uint32 data_len, send_size;
|
||||
uint8 flags = 0;
|
||||
uint32 auth_padding = 0;
|
||||
RPC_AUTH_NETSEC_CHK verf;
|
||||
DATA_BLOB sign_blob;
|
||||
|
||||
/*
|
||||
@ -1022,14 +1023,10 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
|
||||
|
||||
}
|
||||
else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
|
||||
static const uchar netsec_sig[8] = NETSEC_SIGNATURE;
|
||||
static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 };
|
||||
size_t parse_offset_marker;
|
||||
RPC_AUTH_NETSEC_CHK verf;
|
||||
DEBUG(10,("SCHANNEL seq_num=%d\n", cli->auth_info.seq_num));
|
||||
|
||||
init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes,
|
||||
nullbytes, nullbytes);
|
||||
|
||||
netsec_encode(&cli->auth_info,
|
||||
cli->pipe_auth_flags,
|
||||
SENDER_IS_INITIATOR,
|
||||
@ -1277,8 +1274,10 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32
|
||||
prs_init(&rpc_out, RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN, /* need at least this much */
|
||||
cli->mem_ctx, MARSHALL);
|
||||
|
||||
create_rpc_bind_resp(cli, rpc_call_id,
|
||||
&rpc_out);
|
||||
if (!NT_STATUS_IS_OK(create_rpc_bind_resp(cli, rpc_call_id,
|
||||
&rpc_out))) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if ((ret = cli_write(cli, cli->nt_pipe_fnum, 0x8, prs_data_p(&rpc_out),
|
||||
0, (size_t)prs_offset(&rpc_out))) != (ssize_t)prs_offset(&rpc_out)) {
|
||||
@ -1493,9 +1492,7 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
|
||||
const uchar trust_password[16])
|
||||
{
|
||||
NTSTATUS result;
|
||||
/* The 7 here seems to be required to get Win2k not to downgrade us
|
||||
to NT4. Actually, anything other than 1ff would seem to do... */
|
||||
uint32 neg_flags = 0x000701ff;
|
||||
uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
|
||||
int fnum;
|
||||
|
||||
cli_nt_netlogon_netsec_session_close(cli);
|
||||
@ -1584,13 +1581,11 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan,
|
||||
NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, int auth_flags,
|
||||
const uchar trust_password[16])
|
||||
{
|
||||
NTSTATUS result;
|
||||
/* The 7 here seems to be required to get Win2k not to downgrade us
|
||||
to NT4. Actually, anything other than 1ff would seem to do... */
|
||||
uint32 neg_flags = 0x000701ff;
|
||||
uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
|
||||
cli->pipe_auth_flags = 0;
|
||||
|
||||
if (lp_client_schannel() == False) {
|
||||
@ -1632,7 +1627,7 @@ NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan,
|
||||
cli->nt_pipe_fnum = 0;
|
||||
|
||||
/* doing schannel, not per-user auth */
|
||||
cli->pipe_auth_flags = AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL;
|
||||
cli->pipe_auth_flags = auth_flags;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
@ -3,7 +3,8 @@
|
||||
Samba memory buffer functions
|
||||
Copyright (C) Andrew Tridgell 1992-1997
|
||||
Copyright (C) Luke Kenneth Casson Leighton 1996-1997
|
||||
Copyright (C) Jeremy Allison 1999.
|
||||
Copyright (C) Jeremy Allison 1999
|
||||
Copyright (C) Andrew Bartlett 2003.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -1337,47 +1338,6 @@ BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len)
|
||||
return True;
|
||||
}
|
||||
|
||||
static void netsechash(uchar * key, uchar * data, int data_len)
|
||||
{
|
||||
uchar hash[256];
|
||||
uchar index_i = 0;
|
||||
uchar index_j = 0;
|
||||
uchar j = 0;
|
||||
int ind;
|
||||
|
||||
for (ind = 0; ind < 256; ind++)
|
||||
{
|
||||
hash[ind] = (uchar) ind;
|
||||
}
|
||||
|
||||
for (ind = 0; ind < 256; ind++)
|
||||
{
|
||||
uchar tc;
|
||||
|
||||
j += (hash[ind] + key[ind % 16]);
|
||||
|
||||
tc = hash[ind];
|
||||
hash[ind] = hash[j];
|
||||
hash[j] = tc;
|
||||
}
|
||||
|
||||
for (ind = 0; ind < data_len; ind++)
|
||||
{
|
||||
uchar tc;
|
||||
uchar t;
|
||||
|
||||
index_i++;
|
||||
index_j += hash[index_i];
|
||||
|
||||
tc = hash[index_i];
|
||||
hash[index_i] = hash[index_j];
|
||||
hash[index_j] = tc;
|
||||
|
||||
t = hash[index_i] + hash[index_j];
|
||||
data[ind] ^= hash[t];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
Create a digest over the entire packet (including the data), and
|
||||
@ -1400,7 +1360,7 @@ static void netsec_digest(struct netsec_auth_struct *a,
|
||||
MD5Update(&ctx3, zeros, sizeof(zeros));
|
||||
MD5Update(&ctx3, verf->sig, sizeof(verf->sig));
|
||||
if (auth_flags & AUTH_PIPE_SEAL) {
|
||||
MD5Update(&ctx3, verf->data8, sizeof(verf->data8));
|
||||
MD5Update(&ctx3, verf->confounder, sizeof(verf->confounder));
|
||||
}
|
||||
MD5Update(&ctx3, (const unsigned char *)data, data_len);
|
||||
MD5Final(whole_packet_digest, &ctx3);
|
||||
@ -1456,10 +1416,29 @@ static void netsec_deal_with_seq_num(struct netsec_auth_struct *a,
|
||||
dump_data_pw("sequence_key:\n", sequence_key, sizeof(sequence_key));
|
||||
|
||||
dump_data_pw("seq_num (before):\n", verf->seq_num, sizeof(verf->seq_num));
|
||||
netsechash(sequence_key, verf->seq_num, 8);
|
||||
SamOEMhash(verf->seq_num, sequence_key, 8);
|
||||
dump_data_pw("seq_num (after):\n", verf->seq_num, sizeof(verf->seq_num));
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
creates an RPC_AUTH_NETSEC_CHK structure.
|
||||
********************************************************************/
|
||||
static BOOL init_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
|
||||
const uchar sig[8],
|
||||
const uchar packet_digest[8],
|
||||
const uchar seq_num[8], const uchar confounder[8])
|
||||
{
|
||||
if (chk == NULL)
|
||||
return False;
|
||||
|
||||
memcpy(chk->sig, sig, sizeof(chk->sig));
|
||||
memcpy(chk->packet_digest, packet_digest, sizeof(chk->packet_digest));
|
||||
memcpy(chk->seq_num, seq_num, sizeof(chk->seq_num));
|
||||
memcpy(chk->confounder, confounder, sizeof(chk->confounder));
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
Encode a blob of data using the netsec (schannel) alogrithm, also produceing
|
||||
@ -1469,26 +1448,47 @@ static void netsec_deal_with_seq_num(struct netsec_auth_struct *a,
|
||||
********************************************************************/
|
||||
void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
|
||||
enum netsec_direction direction,
|
||||
RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len)
|
||||
RPC_AUTH_NETSEC_CHK * verf,
|
||||
char *data, size_t data_len)
|
||||
{
|
||||
uchar digest_final[16];
|
||||
uchar confounder[8];
|
||||
uchar seq_num[8];
|
||||
static const uchar nullbytes[8];
|
||||
|
||||
static const uchar netsec_seal_sig[8] = NETSEC_SEAL_SIGNATURE;
|
||||
static const uchar netsec_sign_sig[8] = NETSEC_SIGN_SIGNATURE;
|
||||
const uchar *netsec_sig;
|
||||
|
||||
DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
|
||||
|
||||
if (auth_flags & AUTH_PIPE_SEAL) {
|
||||
netsec_sig = netsec_seal_sig;
|
||||
} else if (auth_flags & AUTH_PIPE_SIGN) {
|
||||
netsec_sig = netsec_sign_sig;
|
||||
}
|
||||
|
||||
/* fill the 'confounder' with random data */
|
||||
generate_random_buffer(confounder, sizeof(confounder), False);
|
||||
|
||||
dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
|
||||
|
||||
RSIVAL(verf->seq_num, 0, a->seq_num);
|
||||
RSIVAL(seq_num, 0, a->seq_num);
|
||||
|
||||
switch (direction) {
|
||||
case SENDER_IS_INITIATOR:
|
||||
SIVAL(verf->seq_num, 4, 0x80);
|
||||
SIVAL(seq_num, 4, 0x80);
|
||||
break;
|
||||
case SENDER_IS_ACCEPTOR:
|
||||
SIVAL(verf->seq_num, 4, 0x0);
|
||||
SIVAL(seq_num, 4, 0x0);
|
||||
break;
|
||||
}
|
||||
|
||||
dump_data_pw("verf->seq_num:\n", verf->seq_num, sizeof(verf->seq_num));
|
||||
dump_data_pw("verf->seq_num:\n", seq_num, sizeof(verf->seq_num));
|
||||
|
||||
init_rpc_auth_netsec_chk(verf, netsec_sig, nullbytes,
|
||||
seq_num, confounder);
|
||||
|
||||
/* produce a digest of the packet to prove it's legit (before we seal it) */
|
||||
netsec_digest(a, auth_flags, verf, data, data_len, digest_final);
|
||||
memcpy(verf->packet_digest, digest_final, sizeof(verf->packet_digest));
|
||||
@ -1500,14 +1500,14 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
|
||||
netsec_get_sealing_key(a, verf, sealing_key);
|
||||
|
||||
/* encode the verification data */
|
||||
dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8));
|
||||
netsechash(sealing_key, verf->data8, 8);
|
||||
dump_data_pw("verf->confounder:\n", verf->confounder, sizeof(verf->confounder));
|
||||
SamOEMhash(verf->confounder, sealing_key, 8);
|
||||
|
||||
dump_data_pw("verf->data8_enc:\n", verf->data8, sizeof(verf->data8));
|
||||
dump_data_pw("verf->confounder_enc:\n", verf->confounder, sizeof(verf->confounder));
|
||||
|
||||
/* encode the packet payload */
|
||||
dump_data_pw("data:\n", (const unsigned char *)data, data_len);
|
||||
netsechash(sealing_key, (unsigned char *)data, data_len);
|
||||
SamOEMhash((unsigned char *)data, sealing_key, data_len);
|
||||
dump_data_pw("data_enc:\n", (const unsigned char *)data, data_len);
|
||||
}
|
||||
|
||||
@ -1531,8 +1531,21 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
|
||||
{
|
||||
uchar digest_final[16];
|
||||
|
||||
/* Create the expected sequence number for comparison */
|
||||
static const uchar netsec_seal_sig[8] = NETSEC_SEAL_SIGNATURE;
|
||||
static const uchar netsec_sign_sig[8] = NETSEC_SIGN_SIGNATURE;
|
||||
const uchar *netsec_sig;
|
||||
|
||||
uchar seq_num[8];
|
||||
|
||||
DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
|
||||
|
||||
if (auth_flags & AUTH_PIPE_SEAL) {
|
||||
netsec_sig = netsec_seal_sig;
|
||||
} else if (auth_flags & AUTH_PIPE_SIGN) {
|
||||
netsec_sig = netsec_sign_sig;
|
||||
}
|
||||
|
||||
/* Create the expected sequence number for comparison */
|
||||
RSIVAL(seq_num, 0, a->seq_num);
|
||||
|
||||
switch (direction) {
|
||||
@ -1560,6 +1573,20 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
|
||||
digest, as supplied by the client. We check that it's a valid
|
||||
checksum after the decode, below
|
||||
*/
|
||||
DEBUG(2, ("netsec_decode: FAILED: packet sequence number:\n"));
|
||||
dump_data(2, verf->seq_num, sizeof(verf->seq_num));
|
||||
DEBUG(2, ("should be:\n"));
|
||||
dump_data(2, seq_num, sizeof(seq_num));
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
if (memcmp(verf->sig, netsec_sig, sizeof(verf->sig))) {
|
||||
/* Validate that the other end sent the expected header */
|
||||
DEBUG(2, ("netsec_decode: FAILED: packet header:\n"));
|
||||
dump_data(2, verf->sig, sizeof(verf->sig));
|
||||
DEBUG(2, ("should be:\n"));
|
||||
dump_data(2, netsec_sig, sizeof(netsec_sig));
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -1570,16 +1597,16 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
|
||||
netsec_get_sealing_key(a, verf, sealing_key);
|
||||
|
||||
/* extract the verification data */
|
||||
dump_data_pw("verf->data8:\n", verf->data8,
|
||||
sizeof(verf->data8));
|
||||
netsechash(sealing_key, verf->data8, 8);
|
||||
dump_data_pw("verf->confounder:\n", verf->confounder,
|
||||
sizeof(verf->confounder));
|
||||
SamOEMhash(verf->confounder, sealing_key, 8);
|
||||
|
||||
dump_data_pw("verf->data8_dec:\n", verf->data8,
|
||||
sizeof(verf->data8));
|
||||
dump_data_pw("verf->confounder_dec:\n", verf->confounder,
|
||||
sizeof(verf->confounder));
|
||||
|
||||
/* extract the packet payload */
|
||||
dump_data_pw("data :\n", (const unsigned char *)data, data_len);
|
||||
netsechash(sealing_key, (unsigned char *)data, data_len);
|
||||
SamOEMhash((unsigned char *)data, sealing_key, data_len);
|
||||
dump_data_pw("datadec:\n", (const unsigned char *)data, data_len);
|
||||
}
|
||||
|
||||
|
@ -1175,7 +1175,7 @@ creates an RPC_AUTH_NETSEC_CHK structure.
|
||||
BOOL init_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
|
||||
const uchar sig[8],
|
||||
const uchar packet_digest[8],
|
||||
const uchar seq_num[8], const uchar data8[8])
|
||||
const uchar seq_num[8], const uchar confounder[8])
|
||||
{
|
||||
if (chk == NULL)
|
||||
return False;
|
||||
@ -1183,7 +1183,7 @@ BOOL init_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
|
||||
memcpy(chk->sig, sig, sizeof(chk->sig));
|
||||
memcpy(chk->packet_digest, packet_digest, sizeof(chk->packet_digest));
|
||||
memcpy(chk->seq_num, seq_num, sizeof(chk->seq_num));
|
||||
memcpy(chk->data8, data8, sizeof(chk->data8));
|
||||
memcpy(chk->confounder, confounder, sizeof(chk->confounder));
|
||||
|
||||
return True;
|
||||
}
|
||||
@ -1203,7 +1203,7 @@ BOOL smb_io_rpc_auth_netsec_chk(const char *desc, RPC_AUTH_NETSEC_CHK * chk,
|
||||
prs_uint8s(False, "sig ", ps, depth, chk->sig, sizeof(chk->sig));
|
||||
prs_uint8s(False, "seq_num", ps, depth, chk->seq_num, sizeof(chk->seq_num));
|
||||
prs_uint8s(False, "packet_digest", ps, depth, chk->packet_digest, sizeof(chk->packet_digest));
|
||||
prs_uint8s(False, "data8", ps, depth, chk->data8, sizeof(chk->data8));
|
||||
prs_uint8s(False, "data8", ps, depth, chk->confounder, sizeof(chk->confounder));
|
||||
|
||||
return True;
|
||||
}
|
||||
|
@ -254,18 +254,19 @@ BOOL create_next_pdu(pipes_struct *p)
|
||||
}
|
||||
|
||||
if (p->netsec_auth_validated) {
|
||||
int auth_type, auth_level;
|
||||
char *data;
|
||||
RPC_HDR_AUTH auth_info;
|
||||
static const uchar netsec_sig[8] = NETSEC_SIGNATURE;
|
||||
static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 };
|
||||
|
||||
RPC_AUTH_NETSEC_CHK verf;
|
||||
prs_struct rverf;
|
||||
prs_struct rauth;
|
||||
|
||||
data = prs_data_p(&outgoing_pdu) + data_pos;
|
||||
/* Check it's the type of reply we were expecting to decode */
|
||||
|
||||
init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL,
|
||||
get_auth_type_level(p->netsec_auth.auth_flags, &auth_type, &auth_level);
|
||||
init_rpc_hdr_auth(&auth_info, auth_type, auth_level,
|
||||
RPC_HDR_AUTH_LEN, 1);
|
||||
|
||||
if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
|
||||
@ -277,10 +278,8 @@ BOOL create_next_pdu(pipes_struct *p)
|
||||
prs_init(&rverf, 0, p->mem_ctx, MARSHALL);
|
||||
prs_init(&rauth, 0, p->mem_ctx, MARSHALL);
|
||||
|
||||
init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, nullbytes, nullbytes);
|
||||
|
||||
netsec_encode(&p->netsec_auth,
|
||||
AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL,
|
||||
p->netsec_auth.auth_flags,
|
||||
SENDER_IS_ACCEPTOR,
|
||||
&verf, data, data_len);
|
||||
|
||||
@ -1337,10 +1336,19 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in)
|
||||
return False;
|
||||
}
|
||||
|
||||
if ((auth_info.auth_type != NETSEC_AUTH_TYPE) ||
|
||||
(auth_info.auth_level != RPC_PIPE_AUTH_SEAL_LEVEL)) {
|
||||
DEBUG(0,("Invalid auth info %d or level %d on schannel\n",
|
||||
auth_info.auth_type, auth_info.auth_level));
|
||||
if (auth_info.auth_type != NETSEC_AUTH_TYPE) {
|
||||
DEBUG(0,("Invalid auth info %d on schannel\n",
|
||||
auth_info.auth_type));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (auth_info.auth_level == RPC_PIPE_AUTH_SEAL_LEVEL) {
|
||||
p->netsec_auth.auth_flags = AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL;
|
||||
} else if (auth_info.auth_level == RPC_PIPE_AUTH_SIGN_LEVEL) {
|
||||
p->netsec_auth.auth_flags = AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN;
|
||||
} else {
|
||||
DEBUG(0,("Invalid auth level %d on schannel\n",
|
||||
auth_info.auth_level));
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -1350,7 +1358,7 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in)
|
||||
}
|
||||
|
||||
if (!netsec_decode(&p->netsec_auth,
|
||||
AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL,
|
||||
p->netsec_auth.auth_flags,
|
||||
SENDER_IS_INITIATOR,
|
||||
&netsec_chk,
|
||||
prs_data_p(rpc_in)+old_offset, data_len)) {
|
||||
|
@ -352,38 +352,33 @@ static NTSTATUS cmd_none(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS cmd_schannel(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
int argc, const char **argv)
|
||||
static NTSTATUS setup_schannel(struct cli_state *cli, int pipe_auth_flags,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
NTSTATUS ret;
|
||||
static uchar zeros[16];
|
||||
uchar trust_password[16];
|
||||
uint32 sec_channel_type;
|
||||
static uchar zeros[16];
|
||||
|
||||
if (argc == 2) {
|
||||
strhex_to_str((char *)cli->auth_info.sess_key,
|
||||
strlen(argv[1]),
|
||||
argv[1]);
|
||||
memcpy(cli->sess_key, cli->auth_info.sess_key, sizeof(cli->sess_key));
|
||||
|
||||
cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
|
||||
cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
|
||||
cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
|
||||
|
||||
cli->pipe_auth_flags = pipe_auth_flags;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
|
||||
if ((memcmp(cli->auth_info.sess_key, zeros, sizeof(cli->auth_info.sess_key)) != 0)) {
|
||||
if (cli->pipe_auth_flags == (AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL)) {
|
||||
if (cli->pipe_auth_flags == pipe_auth_flags) {
|
||||
/* already in this mode nothing to do */
|
||||
return NT_STATUS_OK;
|
||||
} else {
|
||||
/* schannel is setup, just need to use it again */
|
||||
cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
|
||||
cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
|
||||
cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
|
||||
/* schannel is setup, just need to use it again with new flags */
|
||||
cli->pipe_auth_flags = pipe_auth_flags;
|
||||
|
||||
if (cli->nt_pipe_fnum != 0)
|
||||
cli_nt_session_close(cli);
|
||||
return NT_STATUS_OK;
|
||||
@ -393,17 +388,13 @@ static NTSTATUS cmd_schannel(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
if (cli->nt_pipe_fnum != 0)
|
||||
cli_nt_session_close(cli);
|
||||
|
||||
cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
|
||||
cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
|
||||
cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
|
||||
|
||||
if (!secrets_fetch_trust_account_password(lp_workgroup(),
|
||||
trust_password,
|
||||
NULL, &sec_channel_type)) {
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
ret = cli_nt_setup_netsec(cli, sec_channel_type, trust_password);
|
||||
ret = cli_nt_setup_netsec(cli, sec_channel_type, pipe_auth_flags, trust_password);
|
||||
if (NT_STATUS_IS_OK(ret)) {
|
||||
char *hex_session_key;
|
||||
hex_encode(cli->auth_info.sess_key,
|
||||
@ -415,6 +406,24 @@ static NTSTATUS cmd_schannel(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS cmd_schannel(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
d_printf("Setting schannel - sign and seal\n");
|
||||
return setup_schannel(cli, AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
static NTSTATUS cmd_schannel_sign(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
d_printf("Setting schannel - sign only\n");
|
||||
return setup_schannel(cli, AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
|
||||
/* Built in rpcclient commands */
|
||||
|
||||
static struct cmd_set rpcclient_commands[] = {
|
||||
@ -430,6 +439,7 @@ static struct cmd_set rpcclient_commands[] = {
|
||||
{ "sign", RPC_RTYPE_NTSTATUS, cmd_sign, NULL, -1, "Force RPC pipe connections to be signed", "" },
|
||||
{ "seal", RPC_RTYPE_NTSTATUS, cmd_seal, NULL, -1, "Force RPC pipe connections to be sealed", "" },
|
||||
{ "schannel", RPC_RTYPE_NTSTATUS, cmd_schannel, NULL, -1, "Force RPC pipe connections to be sealed with 'schannel' (NETSEC). Assumes valid machine account to this domain controller.", "" },
|
||||
{ "schannelsign", RPC_RTYPE_NTSTATUS, cmd_schannel_sign, NULL, -1, "Force RPC pipe connections to be signed (not sealed) with 'schannel' (NETSEC). Assumes valid machine account to this domain controller.", "" },
|
||||
{ "none", RPC_RTYPE_NTSTATUS, cmd_none, NULL, -1, "Force RPC pipe connections to have no special properties", "" },
|
||||
|
||||
{ NULL }
|
||||
@ -522,9 +532,7 @@ static NTSTATUS do_cmd(struct cli_state *cli,
|
||||
/* some of the DsXXX commands use the netlogon pipe */
|
||||
|
||||
if (lp_client_schannel() && (cmd_entry->pipe_idx == PI_NETLOGON) && !(cli->pipe_auth_flags & AUTH_PIPE_NETSEC)) {
|
||||
/* The 7 here seems to be required to get Win2k not to downgrade us
|
||||
to NT4. Actually, anything other than 1ff would seem to do... */
|
||||
uint32 neg_flags = 0x000001ff;
|
||||
uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
|
||||
uint32 sec_channel_type;
|
||||
|
||||
if (!secrets_fetch_trust_account_password(lp_workgroup(),
|
||||
|
Loading…
Reference in New Issue
Block a user