📄 samsync.c
字号:
talloc_free(loop_ctx); } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)); } domain = samsync_state->domain_name[SAM_DATABASE_DOMAIN]; if (!domain) { printf("Never got a DOMAIN object in samsync!\n"); return false; } trustdom_ctx = talloc_named(mem_ctx, 0, "test_DatabaseSync Trusted domains context"); username = talloc_asprintf(trustdom_ctx, "%s$", domain); for (t=samsync_state->trusted_domains; t; t=t->next) { char *secret_name = talloc_asprintf(trustdom_ctx, "G$$%s", t->name); for (s=samsync_state->secrets; s; s=s->next) { if (strcasecmp_m(s->name, secret_name) == 0) { NTSTATUS nt_status; struct samr_Password nt_hash; mdfour(nt_hash.hash, s->secret.data, s->secret.length); printf("Checking password for %s\\%s\n", t->name, username); nt_status = test_SamLogon(samsync_state->p_netlogon_wksta, trustdom_ctx, samsync_state->creds_netlogon_wksta, t->name, username, TEST_WKSTA_MACHINE_NAME, NULL, &nt_hash, NULL); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_LOGON_SERVERS)) { printf("Verifiction of trust password to %s failed: %s (the trusted domain is not available)\n", t->name, nt_errstr(nt_status)); break; } if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) { printf("Verifiction of trust password to %s: should have failed (nologon interdomain trust account), instead: %s\n", t->name, nt_errstr(nt_status)); ret = false; } /* break it */ nt_hash.hash[0]++; nt_status = test_SamLogon(samsync_state->p_netlogon_wksta, trustdom_ctx, samsync_state->creds_netlogon_wksta, t->name, username, TEST_WKSTA_MACHINE_NAME, NULL, &nt_hash, NULL); if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) { printf("Verifiction of trust password to %s: should have failed (wrong password), instead: %s\n", t->name, nt_errstr(nt_status)); ret = false; } break; } } } talloc_free(trustdom_ctx); return ret;}/* try a netlogon DatabaseDeltas*/static bool test_DatabaseDeltas(struct samsync_state *samsync_state, TALLOC_CTX *mem_ctx){ NTSTATUS status; TALLOC_CTX *loop_ctx; struct netr_DatabaseDeltas r; const uint32_t database_ids[] = {0, 1, 2}; int i; bool ret = true; r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(samsync_state->p)); r.in.computername = TEST_MACHINE_NAME; r.in.preferredmaximumlength = (uint32_t)-1; ZERO_STRUCT(r.in.return_authenticator); for (i=0;i<ARRAY_SIZE(database_ids);i++) { r.in.database_id = database_ids[i]; r.in.sequence_num = samsync_state->seq_num[i]; if (r.in.sequence_num == 0) continue; /* this shows that the bdc doesn't need to do a single call for * each seqnumber, and the pdc doesn't need to know about old values * -- metze */ r.in.sequence_num -= 10; printf("Testing DatabaseDeltas of id %d at %llu\n", r.in.database_id, (long long)r.in.sequence_num); do { loop_ctx = talloc_named(mem_ctx, 0, "test_DatabaseDeltas loop context"); creds_client_authenticator(samsync_state->creds, &r.in.credential); status = dcerpc_netr_DatabaseDeltas(samsync_state->p, loop_ctx, &r); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_EQUAL(status, NT_STATUS_SYNCHRONIZATION_REQUIRED)) { printf("DatabaseDeltas - %s\n", nt_errstr(status)); ret = false; } if (!creds_client_check(samsync_state->creds, &r.out.return_authenticator.cred)) { printf("Credential chaining failed\n"); } r.in.sequence_num++; talloc_free(loop_ctx); } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)); } return ret;}/* try a netlogon DatabaseSync2*/static bool test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct creds_CredentialState *creds){ NTSTATUS status; TALLOC_CTX *loop_ctx; struct netr_DatabaseSync2 r; const uint32_t database_ids[] = {0, 1, 2}; int i; bool ret = true; r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); r.in.computername = TEST_MACHINE_NAME; r.in.preferredmaximumlength = (uint32_t)-1; ZERO_STRUCT(r.in.return_authenticator); for (i=0;i<ARRAY_SIZE(database_ids);i++) { r.in.sync_context = 0; r.in.database_id = database_ids[i]; r.in.restart_state = 0; printf("Testing DatabaseSync2 of id %d\n", r.in.database_id); do { loop_ctx = talloc_named(mem_ctx, 0, "test_DatabaseSync2 loop context"); creds_client_authenticator(creds, &r.in.credential); status = dcerpc_netr_DatabaseSync2(p, loop_ctx, &r); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { printf("DatabaseSync2 - %s\n", nt_errstr(status)); ret = false; } if (!creds_client_check(creds, &r.out.return_authenticator.cred)) { printf("Credential chaining failed\n"); } r.in.sync_context = r.out.sync_context; talloc_free(loop_ctx); } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)); } return ret;}bool torture_rpc_samsync(struct torture_context *torture){ NTSTATUS status; TALLOC_CTX *mem_ctx; bool ret = true; struct test_join *join_ctx; struct test_join *join_ctx2; struct test_join *user_ctx; const char *machine_password; const char *wksta_machine_password; struct dcerpc_binding *b; struct dcerpc_binding *b_netlogon_wksta; struct samr_Connect c; struct samr_SetDomainInfo s; struct policy_handle *domain_policy; struct lsa_ObjectAttribute attr; struct lsa_QosInfo qos; struct lsa_OpenPolicy2 r; struct cli_credentials *credentials; struct cli_credentials *credentials_wksta; struct samsync_state *samsync_state; char *test_machine_account; char *test_wksta_machine_account; mem_ctx = talloc_init("torture_rpc_netlogon"); test_machine_account = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME); join_ctx = torture_create_testuser(torture, test_machine_account, lp_workgroup(torture->lp_ctx), ACB_SVRTRUST, &machine_password); if (!join_ctx) { talloc_free(mem_ctx); printf("Failed to join as BDC\n"); return false; } test_wksta_machine_account = talloc_asprintf(mem_ctx, "%s$", TEST_WKSTA_MACHINE_NAME); join_ctx2 = torture_create_testuser(torture, test_wksta_machine_account, lp_workgroup(torture->lp_ctx), ACB_WSTRUST, &wksta_machine_password); if (!join_ctx2) { talloc_free(mem_ctx); printf("Failed to join as member\n"); return false; } user_ctx = torture_create_testuser(torture, TEST_USER_NAME, lp_workgroup(torture->lp_ctx), ACB_NORMAL, NULL); if (!user_ctx) { talloc_free(mem_ctx); printf("Failed to create test account\n"); return false; } samsync_state = talloc_zero(mem_ctx, struct samsync_state); samsync_state->p_samr = torture_join_samr_pipe(join_ctx); samsync_state->connect_handle = talloc_zero(samsync_state, struct policy_handle); samsync_state->lsa_handle = talloc_zero(samsync_state, struct policy_handle); c.in.system_name = NULL; c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; c.out.connect_handle = samsync_state->connect_handle; status = dcerpc_samr_Connect(samsync_state->p_samr, mem_ctx, &c); if (!NT_STATUS_IS_OK(status)) { printf("samr_Connect failed\n"); ret = false; goto failed; } domain_policy = samsync_open_domain(mem_ctx, samsync_state, lp_workgroup(torture->lp_ctx), NULL); if (!domain_policy) { printf("samrsync_open_domain failed\n"); ret = false; goto failed; } s.in.domain_handle = domain_policy; s.in.level = 4; s.in.info = talloc(mem_ctx, union samr_DomainInfo); s.in.info->info4.comment.string = talloc_asprintf(mem_ctx, "Tortured by Samba4: %s", timestring(mem_ctx, time(NULL))); status = dcerpc_samr_SetDomainInfo(samsync_state->p_samr, mem_ctx, &s); if (!test_samr_handle_Close(samsync_state->p_samr, mem_ctx, domain_policy)) { ret = false; goto failed; } if (!NT_STATUS_IS_OK(status)) { printf("SetDomainInfo level %u failed - %s\n", s.in.level, nt_errstr(status)); ret = false; goto failed; } status = torture_rpc_connection(torture, &samsync_state->p_lsa, &ndr_table_lsarpc); if (!NT_STATUS_IS_OK(status)) { ret = false; goto failed; } qos.len = 0; qos.impersonation_level = 2; qos.context_mode = 1; qos.effective_only = 0; attr.len = 0; attr.root_dir = NULL; attr.object_name = NULL; attr.attributes = 0; attr.sec_desc = NULL; attr.sec_qos = &qos; r.in.system_name = "\\"; r.in.attr = &attr; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.handle = samsync_state->lsa_handle; status = dcerpc_lsa_OpenPolicy2(samsync_state->p_lsa, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("OpenPolicy2 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; } b->flags &= ~DCERPC_AUTH_OPTIONS; b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN; credentials = cli_credentials_init(mem_ctx); cli_credentials_set_workstation(credentials, TEST_MACHINE_NAME, CRED_SPECIFIED); cli_credentials_set_domain(credentials, lp_workgroup(torture->lp_ctx), 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_BDC); status = dcerpc_pipe_connect_b(samsync_state, &samsync_state->p, b, &ndr_table_netlogon, credentials, torture->ev, torture->lp_ctx); if (!NT_STATUS_IS_OK(status)) { printf("Failed to connect to server as a BDC: %s\n", nt_errstr(status)); ret = false; goto failed; } status = dcerpc_schannel_creds(samsync_state->p->conn->security_state.generic_state, samsync_state, &samsync_state->creds); if (!NT_STATUS_IS_OK(status)) { ret = false; } status = torture_rpc_binding(torture, &b_netlogon_wksta); if (!NT_STATUS_IS_OK(status)) { ret = false; goto failed; } b_netlogon_wksta->flags &= ~DCERPC_AUTH_OPTIONS; b_netlogon_wksta->flags |= DCERPC_SCHANNEL | DCERPC_SIGN; credentials_wksta = cli_credentials_init(mem_ctx); cli_credentials_set_workstation(credentials_wksta, TEST_WKSTA_MACHINE_NAME, CRED_SPECIFIED); cli_credentials_set_domain(credentials_wksta, lp_workgroup(torture->lp_ctx), CRED_SPECIFIED); cli_credentials_set_username(credentials_wksta, test_wksta_machine_account, CRED_SPECIFIED); cli_credentials_set_password(credentials_wksta, wksta_machine_password, CRED_SPECIFIED); cli_credentials_set_secure_channel_type(credentials_wksta, SEC_CHAN_WKSTA); status = dcerpc_pipe_connect_b(samsync_state, &samsync_state->p_netlogon_wksta, b_netlogon_wksta, &ndr_table_netlogon, credentials_wksta, torture->ev, torture->lp_ctx); if (!NT_STATUS_IS_OK(status)) { printf("Failed to connect to server as a Workstation: %s\n", nt_errstr(status)); ret = false; goto failed; } status = dcerpc_schannel_creds(samsync_state->p_netlogon_wksta->conn->security_state.generic_state, samsync_state, &samsync_state->creds_netlogon_wksta); if (!NT_STATUS_IS_OK(status)) { printf("Failed to obtail schanel creds!\n"); ret = false; } if (!test_DatabaseSync(torture, samsync_state, mem_ctx)) { printf("DatabaseSync failed\n"); ret = false; } if (!test_DatabaseDeltas(samsync_state, mem_ctx)) { printf("DatabaseDeltas failed\n"); ret = false; } if (!test_DatabaseSync2(samsync_state->p, mem_ctx, samsync_state->creds)) { printf("DatabaseSync2 failed\n"); ret = false; }failed: torture_leave_domain(join_ctx); torture_leave_domain(join_ctx2); torture_leave_domain(user_ctx); talloc_free(mem_ctx); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -