summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2003-10-01 22:00:19 +0000
committerGerald Carter <jerry@samba.org>2003-10-01 22:00:19 +0000
commite9568f8df282a8de58d077fb88b54b43023795ca (patch)
treed1b06a99b783c59f282b004ca1cdbddf05585f59
parentb8092fbf99d01783110566b51dfaf26d4802f403 (diff)
downloadsamba-e9568f8df282a8de58d077fb88b54b43023795ca.tar.gz
samba-e9568f8df282a8de58d077fb88b54b43023795ca.tar.bz2
samba-e9568f8df282a8de58d077fb88b54b43023795ca.zip
commit sign only patch from Andrew; bug 167; tested using 2k & XP clientspreviously joined to the Samba domain
(This used to be commit 9d2e585e5e6f9066c6901aa8d8308734f8667296)
-rw-r--r--source3/include/rpc_dce.h11
-rw-r--r--source3/rpc_client/cli_pipe.c29
-rw-r--r--source3/rpc_parse/parse_prs.c147
-rw-r--r--source3/rpc_parse/parse_rpc.c6
-rw-r--r--source3/rpc_server/srv_pipe.c30
-rw-r--r--source3/rpcclient/rpcclient.c50
6 files changed, 159 insertions, 114 deletions
diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h
index 2e4a418bb7..52fe08d875 100644
--- a/source3/include/rpc_dce.h
+++ b/source3/include/rpc_dce.h
@@ -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 */
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index dedbf017a9..9ce10202db 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -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;
}
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
index 81a9573077..b30c41c090 100644
--- a/source3/rpc_parse/parse_prs.c
+++ b/source3/rpc_parse/parse_prs.c
@@ -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);
}
diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c
index 34ba62caa9..558378548a 100644
--- a/source3/rpc_parse/parse_rpc.c
+++ b/source3/rpc_parse/parse_rpc.c
@@ -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;
}
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index d1fb587d74..96261c665f 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -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)) {
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index 515489292b..773441a27c 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -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(),