samlogon.c
来自「samba最新软件」· C语言 代码 · 共 1,856 行 · 第 1/4 页
C
1,856 行
ret = false; } SAFE_FREE(error_string); } talloc_free(tmp_ctx); } } } } talloc_free(fn_ctx); return ret;}/* test an ADS style interactive domain logon*/bool test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct creds_CredentialState *creds, const char *comment, const char *workstation_name, const char *account_domain, const char *account_name, const char *plain_pass, uint32_t parameter_control, NTSTATUS expected_error){ 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; ZERO_STRUCT(a); ZERO_STRUCT(r); ZERO_STRUCT(ra); creds_client_authenticator(creds, &a); r.in.server_name = talloc_asprintf(fn_ctx, "\\\\%s", dcerpc_server_name(p)); r.in.computer_name = TEST_MACHINE_NAME; r.in.credential = &a; r.in.return_authenticator = &ra; r.in.logon_level = 5; r.in.logon.password = &pinfo; r.in.validation_level = 6; r.in.flags = 0; pinfo.identity_info.domain_name.string = account_domain; pinfo.identity_info.parameter_control = parameter_control; pinfo.identity_info.logon_id_low = 0; pinfo.identity_info.logon_id_high = 0; pinfo.identity_info.account_name.string = account_name; pinfo.identity_info.workstation.string = workstation_name; if (!E_deshash(plain_pass, pinfo.lmpassword.hash)) { ZERO_STRUCT(pinfo.lmpassword.hash); } E_md4hash(plain_pass, pinfo.ntpassword.hash); if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16); creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16); } else { creds_des_encrypt(creds, &pinfo.lmpassword); creds_des_encrypt(creds, &pinfo.ntpassword); } d_printf("Testing netr_LogonSamLogonWithFlags '%s' (Interactive Logon)\n", comment); status = dcerpc_netr_LogonSamLogonWithFlags(p, fn_ctx, &r); if (!r.out.return_authenticator || !creds_client_check(creds, &r.out.return_authenticator->cred)) { d_printf("Credential chaining failed\n"); talloc_free(fn_ctx); return false; } talloc_free(fn_ctx); if (!NT_STATUS_EQUAL(expected_error, status)) { d_printf("[%s]\\[%s] netr_LogonSamLogonWithFlags - expected %s got %s\n", account_domain, account_name, nt_errstr(expected_error), nt_errstr(status)); return false; } return true;}bool torture_rpc_samlogon(struct torture_context *torture){ NTSTATUS status; struct dcerpc_pipe *p; struct dcerpc_binding *b; struct cli_credentials *machine_credentials; TALLOC_CTX *mem_ctx = talloc_init("torture_rpc_netlogon"); bool ret = true; struct test_join *join_ctx = NULL; struct test_join *user_ctx = NULL, *user_ctx_wrong_wks = NULL, *user_ctx_wrong_time = NULL; char *user_password, *user_password_wrong_wks, *user_password_wrong_time; const char *old_user_password; char *test_machine_account; const char *userdomain; struct samr_SetUserInfo s; union samr_UserInfo u; int i; int ci; unsigned int credential_flags[] = { NETLOGON_NEG_AUTH2_FLAGS, NETLOGON_NEG_ARCFOUR, NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_128BIT, NETLOGON_NEG_AUTH2_ADS_FLAGS, 0 /* yes, this is a valid flag, causes the use of DES */ }; struct creds_CredentialState *creds; 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(torture, TEST_MACHINE_NAME, ACB_WSTRUST, &machine_credentials); if (!join_ctx) { d_printf("Failed to join as Workstation\n"); return false; } userdomain = torture_setting_string(torture, "userdomain", lp_workgroup(torture->lp_ctx)); user_ctx = torture_create_testuser(torture, TEST_USER_NAME, userdomain, ACB_NORMAL, (const char **)&user_password); if (!user_ctx) { d_printf("Failed to create a test user\n"); return false; } old_user_password = user_password; test_ChangePasswordUser3(torture_join_samr_pipe(user_ctx), mem_ctx, TEST_USER_NAME, 16 /* > 14 */, &user_password, NULL, 0, false); user_ctx_wrong_wks = torture_create_testuser(torture, TEST_USER_NAME_WRONG_WKS, userdomain, ACB_NORMAL, (const char **)&user_password_wrong_wks); if (!user_ctx_wrong_wks) { d_printf("Failed to create a test user (wrong workstation test)\n"); return false; } ZERO_STRUCT(u); s.in.user_handle = torture_join_samr_user_policy(user_ctx_wrong_wks); s.in.info = &u; s.in.level = 21; u.info21.fields_present = SAMR_FIELD_WORKSTATIONS; u.info21.workstations.string = "not" TEST_MACHINE_NAME; status = dcerpc_samr_SetUserInfo(torture_join_samr_pipe(user_ctx_wrong_wks), mem_ctx, &s); if (!NT_STATUS_IS_OK(status)) { printf("SetUserInfo (list of workstations) failed - %s\n", nt_errstr(status)); ret = false; goto failed; } user_ctx_wrong_time = torture_create_testuser(torture, TEST_USER_NAME_WRONG_TIME, userdomain, ACB_NORMAL, (const char **)&user_password_wrong_time); if (!user_ctx_wrong_time) { d_printf("Failed to create a test user (wrong workstation test)\n"); return false; } ZERO_STRUCT(u); s.in.user_handle = torture_join_samr_user_policy(user_ctx_wrong_time); s.in.info = &u; s.in.level = 21; u.info21.fields_present = SAMR_FIELD_WORKSTATIONS | SAMR_FIELD_LOGON_HOURS; u.info21.workstations.string = TEST_MACHINE_NAME; u.info21.logon_hours.units_per_week = 168; u.info21.logon_hours.bits = talloc_zero_array(mem_ctx, uint8_t, 168); status = dcerpc_samr_SetUserInfo(torture_join_samr_pipe(user_ctx_wrong_time), mem_ctx, &s); if (!NT_STATUS_IS_OK(status)) { printf("SetUserInfo (logon times and list of workstations) failed - %s\n", nt_errstr(status)); ret = false; goto failed; } status = torture_rpc_binding(torture, &b); if (!NT_STATUS_IS_OK(status)) { ret = false; goto failed; } /* We have to use schannel, otherwise the SamLogonEx fails * with INTERNAL_ERROR */ b->flags &= ~DCERPC_AUTH_OPTIONS; b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128; status = dcerpc_pipe_connect_b(mem_ctx, &p, b, &ndr_table_netlogon, machine_credentials, torture->ev, torture->lp_ctx); if (!NT_STATUS_IS_OK(status)) { d_printf("RPC pipe connect as domain member failed: %s\n", nt_errstr(status)); ret = false; goto failed; } status = dcerpc_schannel_creds(p->conn->security_state.generic_state, mem_ctx, &creds); if (!NT_STATUS_IS_OK(status)) { ret = false; goto failed; } { struct { const char *comment; const char *domain; const char *username; const char *password; bool network_login; NTSTATUS expected_interactive_error; NTSTATUS expected_network_error; uint32_t parameter_control; bool old_password; /* Allow an old password to be accepted or rejected without error, as well as session key bugs */ } usercreds[] = { { .comment = "domain\\user", .domain = cli_credentials_get_domain(cmdline_credentials), .username = cli_credentials_get_username(cmdline_credentials), .password = cli_credentials_get_password(cmdline_credentials), .network_login = true, .expected_interactive_error = NT_STATUS_OK, .expected_network_error = NT_STATUS_OK }, { .comment = "realm\\user", .domain = cli_credentials_get_realm(cmdline_credentials), .username = cli_credentials_get_username(cmdline_credentials), .password = cli_credentials_get_password(cmdline_credentials), .network_login = true, .expected_interactive_error = NT_STATUS_OK, .expected_network_error = NT_STATUS_OK }, { .comment = "user@domain", .domain = NULL, .username = talloc_asprintf(mem_ctx, "%s@%s", cli_credentials_get_username(cmdline_credentials), cli_credentials_get_domain(cmdline_credentials) ), .password = cli_credentials_get_password(cmdline_credentials), .network_login = false, /* works for some things, but not NTLMv2. Odd */ .expected_interactive_error = NT_STATUS_OK, .expected_network_error = NT_STATUS_OK }, { .comment = "user@realm", .domain = NULL, .username = talloc_asprintf(mem_ctx, "%s@%s", cli_credentials_get_username(cmdline_credentials), cli_credentials_get_realm(cmdline_credentials) ), .password = cli_credentials_get_password(cmdline_credentials), .network_login = true, .expected_interactive_error = NT_STATUS_OK, .expected_network_error = NT_STATUS_OK }, { .comment = "machine domain\\user", .domain = cli_credentials_get_domain(machine_credentials), .username = cli_credentials_get_username(machine_credentials), .password = cli_credentials_get_password(machine_credentials), .network_login = true, .expected_interactive_error = NT_STATUS_NO_SUCH_USER, .parameter_control = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT }, { .comment = "machine domain\\user", .domain = cli_credentials_get_domain(machine_credentials), .username = cli_credentials_get_username(machine_credentials), .password = cli_credentials_get_password(machine_credentials), .network_login = true, .expected_interactive_error = NT_STATUS_NO_SUCH_USER, .expected_network_error = NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, { .comment = "machine realm\\user", .domain = cli_credentials_get_realm(machine_credentials), .username = cli_credentials_get_username(machine_credentials), .password = cli_credentials_get_password(machine_credentials), .network_login = true, .expected_interactive_error = NT_STATUS_NO_SUCH_USER, .parameter_control = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT }, { .comment = "machine user@domain", .domain = NULL, .username = talloc_asprintf(mem_ctx, "%s@%s", cli_credentials_get_username(machine_credentials), cli_credentials_get_domain(machine_credentials) ), .password = cli_credentials_get_password(machine_credentials), .network_login = false, /* works for some things, but not NTLMv2. Odd */ .expected_interactive_error = NT_STATUS_NO_SUCH_USER, .parameter_control = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT }, { .comment = "machine user@realm", .domain = NULL, .username = talloc_asprintf(mem_ctx, "%s@%s", cli_credentials_get_username(machine_credentials), cli_credentials_get_realm(machine_credentials) ), .password = cli_credentials_get_password(machine_credentials), .network_login = true, .expected_interactive_error = NT_STATUS_NO_SUCH_USER, .parameter_control = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT }, { .comment = "test user (long pw): domain\\user", .domain = userdomain, .username = TEST_USER_NAME, .password = user_password, .network_login = true, .expected_interactive_error = NT_STATUS_OK, .expected_network_error = NT_STATUS_OK }, { .comment = "test user (long pw): user@realm", .domain = NULL, .username = talloc_asprintf(mem_ctx, "%s@%s", TEST_USER_NAME, lp_realm(torture->lp_ctx)), .password = user_password, .network_login = true, .expected_interactive_error = NT_STATUS_OK, .expected_network_error = NT_STATUS_OK }, { .comment = "test user (long pw): user@domain", .domain = NULL, .username = talloc_asprintf(mem_ctx, "%s@%s", TEST_USER_NAME, userdomain), .password = user_password, .network_login = false, /* works for some things, but not NTLMv2. Odd */ .expected_interactive_error = NT_STATUS_OK, .expected_network_error = NT_STATUS_OK }, /* Oddball, can we use the old password ? */ { .comment = "test user: user\\domain OLD PASSWORD", .domain = userdomain, .username = TEST_USER_NAME, .password = old_user_password, .network_login = true, .expected_interactive_error = NT_STATUS_WRONG_PASSWORD, .expected_network_error = NT_STATUS_OK, .old_password = true }, { .comment = "test user (wong workstation): domain\\user", .domain = userdomain, .username = TEST_USER_NAME_WRONG_WKS, .password = user_password_wrong_wks, .network_login = true, .expected_interactive_error = NT_STATUS_INVALID_WORKSTATION, .expected_network_error = NT_STATUS_INVALID_WORKSTATION } }; /* Try all the tests for different username forms */ for (ci = 0; ci < ARRAY_SIZE(usercreds); ci++) { if (!test_InteractiveLogon(p, mem_ctx, creds, usercreds[ci].comment, TEST_MACHINE_NAME, usercreds[ci].domain, usercreds[ci].username, usercreds[ci].password, usercreds[ci].parameter_control, usercreds[ci].expected_interactive_error)) { ret = false; } if (usercreds[ci].network_login) { if (!test_SamLogon(p, mem_ctx, torture, creds, usercreds[ci].comment, usercreds[ci].domain, usercreds[ci].username, usercreds[ci].password, usercreds[ci].parameter_control, usercreds[ci].expected_network_error, usercreds[ci].old_password, 0)) { ret = false; } } } /* Using the first username form, try the different * credentials flag setups, on only one of the tests (checks * session key encryption) */ for (i=0; i < ARRAY_SIZE(credential_flags); i++) { /* TODO: Somehow we lost setting up the different credential flags here! */ if (!test_InteractiveLogon(p, mem_ctx, creds, usercreds[0].comment, TEST_MACHINE_NAME, usercreds[0].domain, usercreds[0].username, usercreds[0].password, usercreds[0].parameter_control, usercreds[0].expected_interactive_error)) { ret = false; } if (usercreds[0].network_login) { if (!test_SamLogon(p, mem_ctx, torture, creds, usercreds[0].comment, usercreds[0].domain, usercreds[0].username, usercreds[0].password, usercreds[0].parameter_control, usercreds[0].expected_network_error, usercreds[0].old_password, 1)) { ret = false; } } } }failed: talloc_free(mem_ctx); torture_leave_domain(join_ctx); torture_leave_domain(user_ctx); torture_leave_domain(user_ctx_wrong_wks); torture_leave_domain(user_ctx_wrong_time); return ret;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?