mirror of
https://github.com/samba-team/samba.git
synced 2025-03-27 22:50:26 +03:00
s4:torture/rpc: add test for invalid av_pair content in LogonSamLogonEx
A netapp diag tool uses a NTLMv2_CLIENT_CHALLENGE with invalid bytes as av_pair blob. Which is supposed to be ignored by DCs. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14932 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
0ef1254f44
commit
e7e521fe9b
14
selftest/knownfail.d/rpc.schannel
Normal file
14
selftest/knownfail.d/rpc.schannel
Normal file
@ -0,0 +1,14 @@
|
||||
^samba3.rpc.schannel.schannel.nt4_dc
|
||||
^samba3.rpc.schannel.schannel.ad_dc
|
||||
^samba4.rpc.schannel.on.ncalrpc.with.seal,padcheck.schannel.ad_dc_default:local
|
||||
^samba4.rpc.schannel.on.ncacn_np.with.seal,padcheck.schannel.ad_dc_default
|
||||
^samba4.rpc.schannel.on.ncacn_ip_tcp.with.seal,padcheck.schannel.ad_dc_default
|
||||
^samba4.rpc.schannel.on.ncalrpc.with.validate.schannel.ad_dc_default:local
|
||||
^samba4.rpc.schannel.on.ncacn_np.with.validate.schannel.ad_dc_default
|
||||
^samba4.rpc.schannel.on.ncacn_ip_tcp.with.validate.schannel.ad_dc_default
|
||||
^samba4.rpc.schannel.on.ncalrpc.with.bigendian.schannel.ad_dc_default:local
|
||||
^samba4.rpc.schannel.on.ncacn_np.with.bigendian.schannel.ad_dc_default
|
||||
^samba4.rpc.schannel.on.ncacn_ip_tcp.with.bigendian.schannel.ad_dc_default
|
||||
^samba4.rpc.schannel.with.seal,padcheck.schannel.ad_dc
|
||||
^samba4.rpc.schannel.with.validate.schannel.ad_dc
|
||||
^samba4.rpc.schannel.with.bigendian.schannel.ad_dc
|
@ -241,6 +241,211 @@ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_netlogon_ex_bug14932(struct dcerpc_pipe *p,
|
||||
struct torture_context *tctx,
|
||||
struct cli_credentials *credentials,
|
||||
struct netlogon_creds_CredentialState *creds)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct netr_LogonSamLogonEx r;
|
||||
struct netr_NetworkInfo ninfo;
|
||||
union netr_LogonLevel logon;
|
||||
union netr_Validation validation;
|
||||
uint8_t authoritative = 1;
|
||||
uint32_t _flags = 0;
|
||||
static const char *netapp_magic =
|
||||
"\x01\x01\x00\x00\x00\x00\x00\x00"
|
||||
"\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f"
|
||||
"\xb8\x82\x3a\xf1\xb3\xdd\x08\x15"
|
||||
"\x00\x00\x00\x00\x11\xa2\x08\x81"
|
||||
"\x50\x38\x22\x78\x2b\x94\x47\xfe"
|
||||
"\x54\x94\x7b\xff\x17\x27\x5a\xb4"
|
||||
"\xf4\x18\xba\xdc\x2c\x38\xfd\x5b"
|
||||
"\xfb\x0e\xc1\x85\x1e\xcc\x92\xbb"
|
||||
"\x9b\xb1\xc4\xd5\x53\x14\xff\x8c"
|
||||
"\x76\x49\xf5\x45\x90\x19\xa2";
|
||||
NTTIME timestamp = BVAL(netapp_magic, 8);
|
||||
DATA_BLOB names_blob = data_blob_string_const(netapp_magic + 28);
|
||||
DATA_BLOB chal, lm_resp, nt_resp;
|
||||
int i;
|
||||
int flags = CLI_CRED_NTLM_AUTH;
|
||||
struct dcerpc_binding_handle *b = p->binding_handle;
|
||||
struct netr_UserSessionKey key;
|
||||
struct netr_LMSessionKey LMSessKey;
|
||||
uint32_t validation_levels[] = { 2, 3 };
|
||||
struct netr_SamBaseInfo *base = NULL;
|
||||
const char *crypto_alg = "";
|
||||
bool can_do_validation_6 = true;
|
||||
enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
|
||||
|
||||
flags |= CLI_CRED_NTLMv2_AUTH;
|
||||
|
||||
cli_credentials_get_ntlm_username_domain(samba_cmdline_get_creds(),
|
||||
tctx,
|
||||
&ninfo.identity_info.account_name.string,
|
||||
&ninfo.identity_info.domain_name.string);
|
||||
|
||||
generate_random_buffer(ninfo.challenge,
|
||||
sizeof(ninfo.challenge));
|
||||
|
||||
chal = data_blob_const(ninfo.challenge,
|
||||
sizeof(ninfo.challenge));
|
||||
|
||||
status = cli_credentials_get_ntlm_response(
|
||||
samba_cmdline_get_creds(),
|
||||
tctx,
|
||||
&flags,
|
||||
chal,
|
||||
×tamp,
|
||||
names_blob,
|
||||
&lm_resp, &nt_resp,
|
||||
NULL, NULL);
|
||||
torture_assert_ntstatus_ok(tctx, status,
|
||||
"cli_credentials_get_ntlm_response failed");
|
||||
|
||||
ninfo.lm.data = lm_resp.data;
|
||||
ninfo.lm.length = lm_resp.length;
|
||||
|
||||
ninfo.nt.data = nt_resp.data;
|
||||
ninfo.nt.length = nt_resp.length;
|
||||
|
||||
ninfo.identity_info.parameter_control = 0;
|
||||
ninfo.identity_info.logon_id = 0;
|
||||
ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
|
||||
|
||||
logon.network = &ninfo;
|
||||
|
||||
r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
|
||||
r.in.computer_name = cli_credentials_get_workstation(credentials);
|
||||
r.in.logon_level = NetlogonNetworkInformation;
|
||||
r.in.logon= &logon;
|
||||
r.in.flags = &_flags;
|
||||
r.out.validation = &validation;
|
||||
r.out.authoritative = &authoritative;
|
||||
r.out.flags = &_flags;
|
||||
|
||||
/*
|
||||
- retrieve level6
|
||||
- save usrsession and lmsession key
|
||||
- retrieve level 2
|
||||
- calculate, compare
|
||||
- retrieve level 3
|
||||
- calculate, compare
|
||||
*/
|
||||
|
||||
if (creds != NULL) {
|
||||
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
crypto_alg = "AES";
|
||||
} else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
|
||||
crypto_alg = "ARCFOUR";
|
||||
}
|
||||
}
|
||||
|
||||
dcerpc_binding_handle_auth_info(b, NULL, &auth_level);
|
||||
if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
|
||||
r.in.validation_level = 6;
|
||||
|
||||
torture_comment(tctx,
|
||||
"Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
|
||||
ninfo.identity_info.account_name.string, crypto_alg,
|
||||
r.in.validation_level);
|
||||
|
||||
torture_assert_ntstatus_ok(tctx,
|
||||
dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
|
||||
"LogonSamLogonEx failed");
|
||||
} else {
|
||||
torture_comment(tctx,
|
||||
"Skip auth_level[%u] Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
|
||||
auth_level, ninfo.identity_info.account_name.string, crypto_alg,
|
||||
r.in.validation_level);
|
||||
r.out.result = NT_STATUS_INVALID_INFO_CLASS;
|
||||
}
|
||||
|
||||
if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
|
||||
can_do_validation_6 = false;
|
||||
} else {
|
||||
torture_assert_ntstatus_ok(tctx, r.out.result,
|
||||
"LogonSamLogonEx failed");
|
||||
|
||||
key = r.out.validation->sam6->base.key;
|
||||
LMSessKey = r.out.validation->sam6->base.LMSessKey;
|
||||
|
||||
DEBUG(1,("unencrypted session keys from validation_level 6:\n"));
|
||||
dump_data(1, r.out.validation->sam6->base.key.key, 16);
|
||||
dump_data(1, r.out.validation->sam6->base.LMSessKey.key, 8);
|
||||
}
|
||||
|
||||
for (i=0; i < ARRAY_SIZE(validation_levels); i++) {
|
||||
|
||||
r.in.validation_level = validation_levels[i];
|
||||
|
||||
torture_comment(tctx,
|
||||
"Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n",
|
||||
ninfo.identity_info.account_name.string, crypto_alg,
|
||||
r.in.validation_level);
|
||||
|
||||
torture_assert_ntstatus_ok(tctx,
|
||||
dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
|
||||
"LogonSamLogonEx failed");
|
||||
torture_assert_ntstatus_ok(tctx, r.out.result,
|
||||
"LogonSamLogonEx failed");
|
||||
|
||||
if (creds == NULL) {
|
||||
/* when this test is called without creds no point in
|
||||
* testing the session keys */
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (validation_levels[i]) {
|
||||
case 2:
|
||||
base = &r.out.validation->sam2->base;
|
||||
break;
|
||||
case 3:
|
||||
base = &r.out.validation->sam3->base;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG(1,("encrypted keys validation_level %d:\n",
|
||||
validation_levels[i]));
|
||||
dump_data(1, base->key.key, 16);
|
||||
dump_data(1, base->LMSessKey.key, 8);
|
||||
|
||||
if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
|
||||
netlogon_creds_aes_decrypt(creds, base->key.key, 16);
|
||||
netlogon_creds_aes_decrypt(creds, base->LMSessKey.key, 8);
|
||||
} else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
|
||||
netlogon_creds_arcfour_crypt(creds, base->key.key, 16);
|
||||
netlogon_creds_arcfour_crypt(creds, base->LMSessKey.key, 8);
|
||||
}
|
||||
|
||||
DEBUG(1,("decryped keys validation_level %d\n",
|
||||
validation_levels[i]));
|
||||
|
||||
dump_data(1, base->key.key, 16);
|
||||
dump_data(1, base->LMSessKey.key, 8);
|
||||
|
||||
if (!can_do_validation_6) {
|
||||
/* we cant compare against unencrypted keys */
|
||||
continue;
|
||||
}
|
||||
|
||||
torture_assert_mem_equal(tctx,
|
||||
base->key.key,
|
||||
key.key,
|
||||
16,
|
||||
"unexpected user session key\n");
|
||||
torture_assert_mem_equal(tctx,
|
||||
base->LMSessKey.key,
|
||||
LMSessKey.key,
|
||||
8,
|
||||
"unexpected LM session key\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
do some samr ops using the schannel connection
|
||||
*/
|
||||
@ -436,6 +641,10 @@ static bool test_schannel(struct torture_context *tctx,
|
||||
torture_assert(tctx, test_netlogon_ex_ops(p_netlogon, tctx, credentials, creds),
|
||||
"Failed to process schannel secured NETLOGON EX ops");
|
||||
|
||||
/* regression test for https://bugzilla.samba.org/show_bug.cgi?id=14932 */
|
||||
torture_assert(tctx, test_netlogon_ex_bug14932(p_netlogon, tctx, credentials, creds),
|
||||
"Failed to process schannel secured NETLOGON EX for BUG 14932");
|
||||
|
||||
/* we *MUST* use ncacn_np for openpolicy etc. */
|
||||
transport = dcerpc_binding_get_transport(b);
|
||||
status = dcerpc_binding_set_transport(b, NCACN_NP);
|
||||
|
Loading…
x
Reference in New Issue
Block a user