📄 lsa.c
字号:
status = dcerpc_lsa_QuerySecret(p, mem_ctx, &r6); if (!NT_STATUS_IS_OK(status)) { printf("QuerySecret failed - %s\n", nt_errstr(status)); ret = false; secret4 = NULL; } else { if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL || r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) { printf("Both secret buffers and both times not returned\n"); ret = false; secret4 = NULL; } else { blob1.data = r6.out.new_val->buf->data; blob1.length = r6.out.new_val->buf->size; blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length); secret4 = sess_decrypt_string(mem_ctx, &blob1, &session_key); if (strcmp(secret3, secret4) != 0) { printf("Returned NEW secret %s doesn't match %s\n", secret4, secret3); ret = false; } blob1.data = r6.out.old_val->buf->data; blob1.length = r6.out.old_val->buf->length; blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length); secret2 = sess_decrypt_string(mem_ctx, &blob1, &session_key); if (strcmp(secret1, secret2) != 0) { printf("Returned OLD secret %s doesn't match %s\n", secret2, secret1); ret = false; } if (*r6.out.new_mtime == *r6.out.old_mtime) { printf("Returned secret %s had same mtime for both secrets: %s\n", secname[i], nt_time_string(mem_ctx, *r6.out.new_mtime)); ret = false; } } } enc_key = sess_encrypt_string(secret5, &session_key); r7.in.sec_handle = &sec_handle; r7.in.old_val = &buf1; r7.in.old_val->data = enc_key.data; r7.in.old_val->length = enc_key.length; r7.in.old_val->size = enc_key.length; r7.in.new_val = NULL; printf("Testing SetSecret of old Secret only\n"); status = dcerpc_lsa_SetSecret(p, mem_ctx, &r7); if (!NT_STATUS_IS_OK(status)) { printf("SetSecret failed - %s\n", nt_errstr(status)); ret = false; } data_blob_free(&enc_key); /* fetch the secret back again */ r8.in.sec_handle = &sec_handle; r8.in.new_val = &bufp1; r8.in.new_mtime = &new_mtime; r8.in.old_val = &bufp2; r8.in.old_mtime = &old_mtime; bufp1.buf = NULL; bufp2.buf = NULL; status = dcerpc_lsa_QuerySecret(p, mem_ctx, &r8); if (!NT_STATUS_IS_OK(status)) { printf("QuerySecret failed - %s\n", nt_errstr(status)); ret = false; } else { if (!r8.out.new_val || !r8.out.old_val) { printf("in/out pointers not returned, despite being set on in for QuerySecret\n"); ret = false; } else if (r8.out.new_val->buf == NULL) { if (i != LOCAL) { printf("NEW secret buffer not returned after GLOBAL OLD set\n"); ret = false; } } else if (r8.out.old_val->buf == NULL) { printf("OLD secret buffer not returned after OLD set\n"); ret = false; } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) { printf("Both times not returned after OLD set\n"); ret = false; } else { if (i == LOCAL) { printf("NEW secret buffer should not be returned after LOCAL OLD set\n"); ret = false; } blob1.data = r8.out.new_val->buf->data; blob1.length = r8.out.new_val->buf->length; blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length); secret6 = sess_decrypt_string(mem_ctx, &blob1, &session_key); if (strcmp(secret3, secret4) != 0) { printf("Returned NEW secret '%s' doesn't match '%s'\n", secret4, secret3); ret = false; } blob1.data = r8.out.old_val->buf->data; blob1.length = r8.out.old_val->buf->size; blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length); secret6 = sess_decrypt_string(mem_ctx, &blob1, &session_key); if (strcmp(secret5, secret6) != 0) { printf("Returned OLD secret %s doesn't match %s\n", secret5, secret6); ret = false; } if (*r8.out.new_mtime == *r8.out.old_mtime) { if (i != GLOBAL) { printf("Returned secret %s had same mtime for both secrets: %s\n", secname[i], nt_time_string(mem_ctx, *r8.out.new_mtime)); ret = false; } } else { printf("Returned secret %s should have had same mtime for both secrets: %s != %s\n", secname[i], nt_time_string(mem_ctx, *r8.out.old_mtime), nt_time_string(mem_ctx, *r8.out.new_mtime)); ret = false; } } } if (!test_Delete(p, mem_ctx, &sec_handle)) { ret = false; } d.in.handle = &sec_handle2; status = dcerpc_lsa_Delete(p, mem_ctx, &d); if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) { printf("Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status)); ret = false; } else { printf("Testing OpenSecret of just-deleted secret\n"); status = dcerpc_lsa_OpenSecret(p, mem_ctx, &r2); if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { printf("OpenSecret expected OBJECT_NAME_NOT_FOUND - %s\n", nt_errstr(status)); ret = false; } } } return ret;}static bool test_EnumAccountRights(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *acct_handle, struct dom_sid *sid){ NTSTATUS status; struct lsa_EnumAccountRights r; struct lsa_RightSet rights; printf("Testing EnumAccountRights\n"); r.in.handle = acct_handle; r.in.sid = sid; r.out.rights = &rights; status = dcerpc_lsa_EnumAccountRights(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("EnumAccountRights of %s failed - %s\n", dom_sid_string(mem_ctx, sid), nt_errstr(status)); return false; } return true;}static bool test_QuerySecurity(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *handle, struct policy_handle *acct_handle){ NTSTATUS status; struct lsa_QuerySecurity r; if (torture_setting_bool(tctx, "samba4", false)) { printf("skipping QuerySecurity test against Samba4\n"); return true; } printf("Testing QuerySecurity\n"); r.in.handle = acct_handle; r.in.sec_info = 7; status = dcerpc_lsa_QuerySecurity(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("QuerySecurity failed - %s\n", nt_errstr(status)); return false; } return true;}static bool test_OpenAccount(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct dom_sid *sid){ NTSTATUS status; struct lsa_OpenAccount r; struct policy_handle acct_handle; printf("Testing OpenAccount\n"); r.in.handle = handle; r.in.sid = sid; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.acct_handle = &acct_handle; status = dcerpc_lsa_OpenAccount(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("OpenAccount failed - %s\n", nt_errstr(status)); return false; } if (!test_EnumPrivsAccount(p, mem_ctx, handle, &acct_handle)) { return false; } if (!test_QuerySecurity(p, mem_ctx, handle, &acct_handle)) { return false; } return true;}static bool test_EnumAccounts(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle){ NTSTATUS status; struct lsa_EnumAccounts r; struct lsa_SidArray sids1, sids2; uint32_t resume_handle = 0; int i; bool ret = true; printf("\ntesting EnumAccounts\n"); r.in.handle = handle; r.in.resume_handle = &resume_handle; r.in.num_entries = 100; r.out.resume_handle = &resume_handle; r.out.sids = &sids1; resume_handle = 0; while (true) { status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r); if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) { break; } if (!NT_STATUS_IS_OK(status)) { printf("EnumAccounts failed - %s\n", nt_errstr(status)); return false; } if (!test_LookupSids(p, mem_ctx, handle, &sids1)) { return false; } if (!test_LookupSids2(p, mem_ctx, handle, &sids1)) { return false; } if (!test_LookupSids3(p, mem_ctx, &sids1)) { return false; } printf("testing all accounts\n"); for (i=0;i<sids1.num_sids;i++) { ret &= test_OpenAccount(p, mem_ctx, handle, sids1.sids[i].sid); ret &= test_EnumAccountRights(p, mem_ctx, handle, sids1.sids[i].sid); } printf("\n"); } if (sids1.num_sids < 3) { return ret; } printf("trying EnumAccounts partial listing (asking for 1 at 2)\n"); resume_handle = 2; r.in.num_entries = 1; r.out.sids = &sids2; status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("EnumAccounts failed - %s\n", nt_errstr(status)); return false; } if (sids2.num_sids != 1) { printf("Returned wrong number of entries (%d)\n", sids2.num_sids); return false; } return true;}static bool test_LookupPrivDisplayName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct lsa_String *priv_name){ struct lsa_LookupPrivDisplayName r; NTSTATUS status; /* produce a reasonable range of language output without screwing up terminals */ uint16_t language_id = (random() % 4) + 0x409; printf("testing LookupPrivDisplayName(%s)\n", priv_name->string); r.in.handle = handle; r.in.name = priv_name; r.in.language_id = &language_id; r.out.language_id = &language_id; r.in.unknown = 0; status = dcerpc_lsa_LookupPrivDisplayName(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("LookupPrivDisplayName failed - %s\n", nt_errstr(status)); return false; } printf("%s -> \"%s\" (language 0x%x/0x%x)\n", priv_name->string, r.out.disp_name->string, *r.in.language_id, *r.out.language_id); return true;}static bool test_EnumAccountsWithUserRight(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct lsa_String *priv_name){ struct lsa_EnumAccountsWithUserRight r; struct lsa_SidArray sids; NTSTATUS status; ZERO_STRUCT(sids); printf("testing EnumAccountsWithUserRight(%s)\n", priv_name->string); r.in.handle = handle; r.in.name = priv_name; r.out.sids = &sids; status = dcerpc_lsa_EnumAccountsWithUserRight(p, mem_ctx, &r); /* NT_STATUS_NO_MORE_ENTRIES means noone has this privilege */ if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) { return true; } if (!NT_STATUS_IS_OK(status)) { printf("EnumAccountsWithUserRight failed - %s\n", nt_errstr(status)); return false; } return true;}static bool test_EnumPrivs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle){ NTSTATUS status; struct lsa_EnumPrivs r; struct lsa_PrivArray privs1; uint32_t resume_handle = 0; int i; bool ret = true; printf("\ntesting EnumPrivs\n"); r.in.handle = handle; r.in.resume_handle = &resume_handle; r.in.max_count = 100; r.out.resume_handle = &resume_handle; r.out.privs = &privs1; resume_handle = 0; status = dcerpc_lsa_EnumPrivs(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("EnumPrivs failed - %s\n", nt_errstr(status)); return false; } for (i = 0; i< privs1.count; i++) { test_LookupPrivDisplayName(p, mem_ctx, handle, (struct lsa_String *)&privs1.privs[i].name); test_LookupPrivValue(p, mem_ctx, handle, (struct lsa_String *)&privs1.privs[i].name); if (!test_EnumAccountsWithUserRight(p, mem_ctx, handle, (struct lsa_String *)&privs1.privs[i].name)) { ret = false; } } return ret;}static bool test_QueryForestTrustInformation(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *handle, const char *trusted_domain_name){ bool ret = true; struct lsa_lsaRQueryForestTrustInformation r; NTSTATUS status; struct lsa_String string; struct lsa_ForestTrustInformation info, *info_ptr; printf("\nTesting lsaRQueryForestTrustInformation\n"); if (torture_setting_bool(tctx, "samba4", false)) { printf("skipping QueryForestTrustInformation against Samba4\n"); return true; } ZERO_STRUCT(string); if (trusted_domain_name) { init_lsa_String(&string, trusted_domain_name); } info_ptr = &info; r.in.handle = handle; r.in.trusted_domain_name = &string; r.in.unknown = 0; r.out.forest_trust_info = &info_ptr; status = dcerpc_lsa_lsaRQueryForestTrustInformation(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("lsaRQueryForestTrustInformation failed - %s\n", nt_errstr(status)); ret = false; } return ret;}static bool test_query_each_TrustDomEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct lsa_DomainListEx *domains) { int i; bool ret = true; for (i=0; i< domains->count; i++) { if (domains->domains[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) { ret &= test_QueryForestTrustInformation(p, mem_ctx, handle, domains->domains[i].domain_name.string); } } return ret;}static bool test_query_each_TrustDom(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct lsa_DomainList *domains) { NTSTATUS status; int i,j; bool ret = true; printf("\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n"); for (i=0; i< domains->count; i++) { struct lsa_OpenTrustedDomain trust; struct lsa_OpenTrustedDomainByName trust_by_name; struct policy_handle trustdom_handle; struct policy_handle handle2; struct lsa_Close c; struct lsa_CloseTrustedDomainEx c_trust; int levels [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; int ok[] = {1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1}; if (domains->domains[i].sid) { trust.in.handle = handle; trust.in.sid = domains->domains[i].sid; trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; trust.out.trustdom_handle = &trustdom_handle; status = dcerpc_lsa_OpenTrustedDomain(p, mem_ctx, &trust); if (!NT_STATUS_IS_OK(status)) { printf("OpenTrustedDomain failed - %s\n", nt_errstr(status)); return false; } c.in.handle = &trustdom_handle; c.out.handle = &handle2; c_trust.in.handle = &trustdom_handle; c_trust.out.handle = &handle2; for (j=0; j < ARRAY_SIZE(levels); j++) { struct lsa_QueryTrustedDomainInfo q; union lsa_TrustedDomainInfo info; q.in.trustdom_handle = &trustdom_handle; q.in.level = levels[j]; q.out.info = &info; status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q); if (!NT_STATUS_IS_OK(status) && ok[j]) { printf("QueryTrustedDomainInfo level %d failed - %s\n", levels[j], nt_errstr(status)); ret = false; } else if (NT_STATUS_IS_OK(status) && !ok[j]) { printf("QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n", levels[j], nt_errstr(status)); ret = false; } } status = dcerpc_lsa_CloseTrustedDomainEx(p, mem_ctx, &c_trust); if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { printf("Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(status)); return false; } c.in.handle = &trustdom_handle; c.out.handle = &handle2; status = dcerpc_lsa_Close(p, mem_ctx, &c); if (!NT_STATUS_IS_OK(status)) { printf("Close of trusted domain failed - %s\n", nt_errstr(status)); return false; } for (j=0; j < ARRAY_SIZE(levels); j++) { struct lsa_QueryTrustedDomainInfoBySid q; union lsa_TrustedDomainInfo info; if (!domains->domains[i].sid) { continue; } q.in.handle = handle; q.in.dom_sid = domains->domains[i].sid; q.in.level = levels[j]; q.out.info = &info; status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, mem_ctx, &q); if (!NT_STATUS_IS_OK(status) && ok[j]) { printf("QueryTrustedDomainInfoBySid level %d failed - %s\n", levels[j], nt_errstr(status)); ret = false; } else if (NT_STATUS_IS_OK(status) && !ok[j]) { printf("QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -