#include "librpc/gen_ndr/ndr_netlogon.h"
#include "auth/auth.h"
#include "lib/crypto/crypto.h"
+#include "lib/cmdline/popt_common.h"
#define TEST_MACHINE_NAME "samlogontest"
+#define TEST_USER_NAME "samlogontestuser"
enum ntlm_break {
BREAK_BOTH,
struct netr_LogonSamLogonWithFlags *r_flags = &samlogon_state->r_flags;
struct netr_NetworkInfo ninfo;
struct netr_SamBaseInfo *base = NULL;
- uint16 validation_level = 0;
+ uint16_t validation_level = 0;
samlogon_state->r.in.logon.network = &ninfo;
samlogon_state->r_ex.in.logon.network = &ninfo;
const char *name;
BOOL expect_fail;
} test_table[] = {
+ {test_lmv2_ntlmv2, "NTLMv2 and LMv2", False},
{test_lm, "LM", False},
{test_lm_ntlm, "LM and NTLM", False},
{test_lm_ntlm_both_broken, "LM and NTLM, both broken", False},
{test_ntlm_in_lm, "NTLM in LM", False},
{test_ntlm_in_both, "NTLM in both", False},
{test_ntlmv2, "NTLMv2", False},
- {test_lmv2_ntlmv2, "NTLMv2 and LMv2", False},
{test_lmv2, "LMv2", False},
{test_ntlmv2_lmv2_broken, "NTLMv2 and LMv2, LMv2 broken", False},
{test_ntlmv2_ntlmv2_broken, "NTLMv2 and LMv2, NTLMv2 broken", False},
try a netlogon SamLogon
*/
static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct creds_CredentialState *creds)
+ struct creds_CredentialState *creds,
+ const char *account_domain, const char *account_name,
+ const char *plain_pass,
+ int n_subtests)
{
+ TALLOC_CTX *fn_ctx = talloc_named(mem_ctx, 0, "test_SamLogon function-level context");
int i, v, l, f;
BOOL ret = True;
int validation_levels[] = {2,3,6};
printf("testing netr_LogonSamLogon and netr_LogonSamLogonWithFlags\n");
- samlogon_state.mem_ctx = mem_ctx;
- samlogon_state.account_name = lp_parm_string(-1, "torture", "username");
- samlogon_state.account_domain = lp_parm_string(-1, "torture", "userdomain");
- samlogon_state.password = lp_parm_string(-1, "torture", "password");
+ samlogon_state.account_name = account_name;
+ samlogon_state.account_domain = account_domain;
+ samlogon_state.password = plain_pass;
samlogon_state.p = p;
samlogon_state.creds = creds;
- samlogon_state.chall = data_blob_talloc(mem_ctx, NULL, 8);
+ samlogon_state.chall = data_blob_talloc(fn_ctx, NULL, 8);
generate_random_buffer(samlogon_state.chall.data, 8);
- samlogon_state.r_flags.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
+ samlogon_state.r_flags.in.server_name = talloc_asprintf(fn_ctx, "\\\\%s", dcerpc_server_name(p));
samlogon_state.r_flags.in.workstation = TEST_MACHINE_NAME;
samlogon_state.r_flags.in.credential = &samlogon_state.auth;
samlogon_state.r_flags.in.return_authenticator = &samlogon_state.auth2;
samlogon_state.r_flags.in.flags = 0;
- samlogon_state.r_ex.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
+ samlogon_state.r_ex.in.server_name = talloc_asprintf(fn_ctx, "\\\\%s", dcerpc_server_name(p));
samlogon_state.r_ex.in.workstation = TEST_MACHINE_NAME;
samlogon_state.r_ex.in.flags = 0;
- samlogon_state.r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
+ samlogon_state.r.in.server_name = talloc_asprintf(fn_ctx, "\\\\%s", dcerpc_server_name(p));
samlogon_state.r.in.workstation = TEST_MACHINE_NAME;
samlogon_state.r.in.credential = &samlogon_state.auth;
samlogon_state.r.in.return_authenticator = &samlogon_state.auth2;
for (f=0;f<ARRAY_SIZE(function_levels);f++) {
for (i=0; test_table[i].fn; i++) {
+ if (n_subtests && (i > n_subtests)) {
+ continue;
+ }
for (v=0;v<ARRAY_SIZE(validation_levels);v++) {
for (l=0;l<ARRAY_SIZE(logon_levels);l++) {
char *error_string = NULL;
+ TALLOC_CTX *tmp_ctx = talloc_named(fn_ctx, 0, "test_SamLogon inner loop");
+ samlogon_state.mem_ctx = tmp_ctx;
samlogon_state.function_level = function_levels[f];
samlogon_state.r.in.validation_level = validation_levels[v];
samlogon_state.r.in.logon_level = logon_levels[l];
samlogon_state.r_flags.in.validation_level = validation_levels[v];
samlogon_state.r_flags.in.logon_level = logon_levels[l];
if (!test_table[i].fn(&samlogon_state, &error_string)) {
- printf("Testing '%s' at validation level %d, logon level %d, function %d: \n",
+ printf("Testing [%s]\\[%s] '%s' at validation level %d, logon level %d, function %d: \n",
+ samlogon_state.account_domain,
+ samlogon_state.account_name,
test_table[i].name, validation_levels[v],
logon_levels[l], function_levels[f]);
}
SAFE_FREE(error_string);
}
+ talloc_free(tmp_ctx);
}
}
}
}
-
+ talloc_free(fn_ctx);
return ret;
}
test an ADS style interactive domain logon
*/
static BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct creds_CredentialState *creds)
+ struct creds_CredentialState *creds,
+ const char *account_domain, const char *account_name,
+ const char *plain_pass)
{
NTSTATUS status;
+ TALLOC_CTX *fn_ctx = talloc_named(mem_ctx, 0, "test_InteractiveLogon function-level context");
struct netr_LogonSamLogonWithFlags r;
struct netr_Authenticator a, ra;
struct netr_PasswordInfo pinfo;
- const char *plain_pass;
ZERO_STRUCT(a);
ZERO_STRUCT(r);
creds_client_authenticator(creds, &a);
- r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
+ r.in.server_name = talloc_asprintf(fn_ctx, "\\\\%s", dcerpc_server_name(p));
r.in.workstation = TEST_MACHINE_NAME;
r.in.credential = &a;
r.in.return_authenticator = &ra;
r.in.validation_level = 6;
r.in.flags = 0;
- pinfo.identity_info.domain_name.string = lp_parm_string(-1, "torture", "userdomain");
+ pinfo.identity_info.domain_name.string = account_domain;
pinfo.identity_info.parameter_control = 0;
pinfo.identity_info.logon_id_low = 0;
pinfo.identity_info.logon_id_high = 0;
- pinfo.identity_info.account_name.string = lp_parm_string(-1, "torture", "username");
+ pinfo.identity_info.account_name.string = account_name;
pinfo.identity_info.workstation.string = TEST_MACHINE_NAME;
- plain_pass = lp_parm_string(-1, "torture", "password");
-
E_deshash(plain_pass, pinfo.lmpassword.hash);
E_md4hash(plain_pass, pinfo.ntpassword.hash);
printf("Testing netr_LogonSamLogonWithFlags (Interactive Logon)\n");
- status = dcerpc_netr_LogonSamLogonWithFlags(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- printf("netr_LogonSamLogonWithFlags - %s\n", nt_errstr(status));
+ status = dcerpc_netr_LogonSamLogonWithFlags(p, fn_ctx, &r);
+ if (!r.out.return_authenticator || !creds_client_check(creds, &r.out.return_authenticator->cred)) {
+ printf("Credential chaining failed\n");
+ talloc_free(fn_ctx);
return False;
}
- if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {
- printf("Credential chaining failed\n");
+ talloc_free(fn_ctx);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("[%s]\\[%s] netr_LogonSamLogonWithFlags - %s\n", account_name, account_domain, nt_errstr(status));
return False;
}
{
NTSTATUS status;
struct dcerpc_pipe *p;
- struct dcerpc_binding b;
- TALLOC_CTX *mem_ctx;
+ struct dcerpc_binding *b;
+ struct cli_credentials *credentials;
+ TALLOC_CTX *mem_ctx = talloc_init("torture_rpc_netlogon");
BOOL ret = True;
- void *join_ctx;
+ struct test_join *join_ctx;
+#if 0
+ struct test_join *user_ctx;
+ const char *user_password;
+#endif
+ char *test_machine_account;
const char *machine_password;
const char *binding = lp_parm_string(-1, "torture", "binding");
int i;
-
+ int ci;
+
unsigned int credential_flags[] = {
NETLOGON_NEG_AUTH2_FLAGS,
NETLOGON_NEG_ARCFOUR,
struct creds_CredentialState *creds;
- mem_ctx = talloc_init("torture_rpc_netlogon");
+ struct {
+ const char *domain;
+ const char *username;
+ const char *password;
+ BOOL network_login;
+ } usercreds[] = {
+ {
+ cli_credentials_get_domain(cmdline_credentials),
+ cli_credentials_get_username(cmdline_credentials),
+ cli_credentials_get_password(cmdline_credentials),
+ True
+ },
+ {
+ cli_credentials_get_realm(cmdline_credentials),
+ cli_credentials_get_username(cmdline_credentials),
+ cli_credentials_get_password(cmdline_credentials),
+ True
+ },
+ {
+ NULL,
+ talloc_asprintf(mem_ctx,
+ "%s@%s",
+ cli_credentials_get_username(cmdline_credentials),
+ cli_credentials_get_domain(cmdline_credentials)
+ ),
+ cli_credentials_get_password(cmdline_credentials),
+ False
+ },
+ {
+ NULL,
+ talloc_asprintf(mem_ctx,
+ "%s@%s",
+ cli_credentials_get_username(cmdline_credentials),
+ cli_credentials_get_realm(cmdline_credentials)
+ ),
+ cli_credentials_get_password(cmdline_credentials),
+ True
+ },
+#if 0
+ {
+ lp_parm_string(-1, "torture", "userdomain"),
+ TEST_USER_NAME,
+ NULL,
+ True
+ },
+ {
+ NULL,
+ talloc_asprintf(mem_ctx,
+ "%s@%s",
+ TEST_USER_NAME,
+ lp_realm()),
+ NULL,
+ True
+ },
+ {
+ NULL,
+ talloc_asprintf(mem_ctx,
+ "%s@%s",
+ TEST_USER_NAME,
+ lp_parm_string(-1, "torture", "userdomain")),
+ NULL,
+ False
+ }
+#endif
+ };
+
+ credentials = cli_credentials_init(mem_ctx);
+ test_machine_account = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
/* We only need to join as a workstation here, and in future,
* if we wish to test against trusted domains, we must be a
* workstation here */
- join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_WSTRUST,
- &machine_password);
+ join_ctx = torture_create_testuser(test_machine_account, lp_workgroup(), ACB_WSTRUST,
+ &machine_password);
if (!join_ctx) {
printf("Failed to join as Workstation\n");
return False;
}
+#if 0
+ user_ctx = torture_create_testuser(TEST_USER_NAME,
+ lp_parm_string(-1, "torture", "userdomain"),
+ ACB_NORMAL,
+ &user_password);
+ if (!user_ctx) {
+ printf("Failed to join as Workstation\n");
+ return False;
+ }
+
+ usercreds[3].password = user_password;
+ usercreds[4].password = user_password;
+ usercreds[5].password = user_password;
+#endif
status = dcerpc_parse_binding(mem_ctx, binding, &b);
if (!NT_STATUS_IS_OK(status)) {
/* We have to use schannel, otherwise the SamLogonEx fails
* with INTERNAL_ERROR */
- b.flags &= ~DCERPC_AUTH_OPTIONS;
- b.flags |= DCERPC_SCHANNEL_WORKSTATION | DCERPC_SIGN | DCERPC_SCHANNEL_128;
+ b->flags &= ~DCERPC_AUTH_OPTIONS;
+ 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(&p, &b,
+ status = dcerpc_pipe_connect_b(mem_ctx, &p, b,
DCERPC_NETLOGON_UUID,
DCERPC_NETLOGON_VERSION,
- lp_workgroup(),
- TEST_MACHINE_NAME,
- machine_password);
+ credentials);
if (!NT_STATUS_IS_OK(status)) {
+ printf("RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
ret = False;
goto failed;
}
goto failed;
}
- if (!test_InteractiveLogon(p, mem_ctx, creds)) {
- ret = False;
- }
-
- if (!test_SamLogon(p, mem_ctx, creds)) {
- ret = False;
- }
-
- for (i=0; i < ARRAY_SIZE(credential_flags); i++) {
+ for (ci = 0; ci < ARRAY_SIZE(usercreds); ci++) {
- if (!test_SetupCredentials2(p, mem_ctx, credential_flags[i],
- TEST_MACHINE_NAME, machine_password,
- SEC_CHAN_WKSTA, creds)) {
- return False;
+ if (!test_InteractiveLogon(p, mem_ctx, creds,
+ usercreds[ci].domain,
+ usercreds[ci].username,
+ usercreds[ci].password)) {
+ ret = False;
}
- if (!test_InteractiveLogon(p, mem_ctx, creds)) {
- ret = False;
+ if (usercreds[ci].network_login) {
+ if (!test_SamLogon(p, mem_ctx, creds,
+ usercreds[ci].domain,
+ usercreds[ci].username,
+ usercreds[ci].password,
+ 0)) {
+ ret = False;
+ }
}
+ }
+
+ for (i=0; i < ARRAY_SIZE(credential_flags); i++) {
- if (!test_SamLogon(p, mem_ctx, creds)) {
- ret = False;
+ for (ci = 0; ci < ARRAY_SIZE(usercreds); ci++) {
+
+ if (!test_InteractiveLogon(p, mem_ctx, creds,
+ usercreds[ci].domain,
+ usercreds[ci].username,
+ usercreds[ci].password)) {
+ ret = False;
+ }
+
+ if (usercreds[ci].network_login) {
+ if (!test_SamLogon(p, mem_ctx, creds,
+ usercreds[ci].domain,
+ usercreds[ci].username,
+ usercreds[ci].password,
+ 1)) {
+ ret = False;
+ }
+ }
}
}
failed:
- talloc_destroy(mem_ctx);
-
- torture_rpc_close(p);
+ talloc_free(mem_ctx);
torture_leave_domain(join_ctx);
-
+#if 0
+ torture_leave_domain(user_ctx);
+#endif
return ret;
}