Index: rpc_client/cli_pipe.c =================================================================== --- rpc_client/cli_pipe.c (revision 655) +++ rpc_client/cli_pipe.c (working copy) @@ -332,13 +332,24 @@ if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { RPC_AUTH_NETSEC_CHK chk; - if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { + if ( (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN) + && (auth_len != RPC_AUTH_NETSEC_SIGN_ONLY_CHK_LEN) ) + { DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len)); return False; } - if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", - &chk, &auth_verf, 0)) { + /* can't seal with no nonce */ + if ( (cli->pipe_auth_flags & AUTH_PIPE_SEAL) + && (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN) ) + { + DEBUG(0,("rpc_auth_pipe: sealing not supported with schannel auth len %d\n", auth_len)); + return False; + } + + + if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", auth_len, &chk, &auth_verf, 0)) + { DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling " "RPC_AUTH_NETSECK_CHK failed\n")); return False; @@ -918,7 +929,7 @@ auth_len = RPC_AUTH_NTLMSSP_CHK_LEN; } if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { - auth_len = RPC_AUTH_NETSEC_CHK_LEN; + auth_len = RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN; } auth_hdr_len = RPC_HDR_AUTH_LEN; } @@ -1034,8 +1045,9 @@ /* write auth footer onto the packet */ parse_offset_marker = prs_offset(&sec_blob); - if (!smb_io_rpc_auth_netsec_chk("", &verf, - &sec_blob, 0)) { + if (!smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN, + &verf, &sec_blob, 0)) + { prs_mem_free(&sec_blob); return False; } Index: rpc_server/srv_pipe.c =================================================================== --- rpc_server/srv_pipe.c (revision 655) +++ rpc_server/srv_pipe.c (working copy) @@ -124,7 +124,7 @@ if(p->ntlmssp_auth_validated) { data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN); } else if(p->netsec_auth_validated) { - data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN); + data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN); } /* @@ -177,8 +177,8 @@ } else if (p->netsec_auth_validated) { p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + ss_padding_len + - RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN; - p->hdr.auth_len = RPC_AUTH_NETSEC_CHK_LEN; + RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN; + p->hdr.auth_len = RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN; } else { p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len; p->hdr.auth_len = 0; @@ -1339,7 +1339,7 @@ auth_len = p->hdr.auth_len; - if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { + if (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN) { DEBUG(0,("Incorrect auth_len %d.\n", auth_len )); return False; } Index: rpc_parse/parse_rpc.c =================================================================== --- rpc_parse/parse_rpc.c (revision 655) +++ rpc_parse/parse_rpc.c (working copy) @@ -1189,7 +1189,8 @@ /******************************************************************* reads or writes an RPC_AUTH_NETSEC_CHK structure. ********************************************************************/ -BOOL smb_io_rpc_auth_netsec_chk(const char *desc, RPC_AUTH_NETSEC_CHK * chk, +BOOL smb_io_rpc_auth_netsec_chk(const char *desc, int auth_len, + RPC_AUTH_NETSEC_CHK * chk, prs_struct *ps, int depth) { if (chk == NULL) @@ -1198,10 +1199,19 @@ prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_chk"); depth++; - 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, "confounder", ps, depth, chk->confounder, sizeof(chk->confounder)); + if ( !prs_uint8s(False, "sig ", ps, depth, chk->sig, sizeof(chk->sig)) ) + return False; + + if ( !prs_uint8s(False, "seq_num", ps, depth, chk->seq_num, sizeof(chk->seq_num)) ) + return False; + + if ( !prs_uint8s(False, "packet_digest", ps, depth, chk->packet_digest, sizeof(chk->packet_digest)) ) + return False; + + if ( auth_len == RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN ) { + if ( !prs_uint8s(False, "confounder", ps, depth, chk->confounder, sizeof(chk->confounder)) ) + return False; + } return True; } Index: include/rpc_dce.h =================================================================== --- include/rpc_dce.h (revision 655) +++ include/rpc_dce.h (working copy) @@ -63,8 +63,10 @@ #define NETSEC_AUTH_TYPE 0x44 #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 +#define RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN 0x20 +#define RPC_AUTH_NETSEC_SIGN_ONLY_CHK_LEN 0x18 + /* 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