X-Git-Url: http://git.samba.org/samba.git/?p=kai%2Fsamba.git;a=blobdiff_plain;f=source4%2Ftorture%2Frpc%2Flsa.c;h=69df965f1975e105415a1e2e235f094e9d234bac;hp=1250743955e75ea70c27e6d474b8337c87bd5741;hb=85acd7eccca127ab701f1515a27747b8af089cab;hpb=2151cde58014ea2e822c13d2f8a369b45dc19ca8 diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index 1250743955e..69df965f197 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -23,11 +23,14 @@ #include "torture/torture.h" #include "librpc/gen_ndr/ndr_lsa_c.h" #include "librpc/gen_ndr/netlogon.h" +#include "librpc/gen_ndr/ndr_drsblobs.h" #include "lib/events/events.h" #include "libcli/security/security.h" #include "libcli/auth/libcli_auth.h" #include "torture/rpc/rpc.h" #include "param/param.h" +#include "../lib/crypto/crypto.h" +#define TEST_MACHINENAME "lsatestmach" static void init_lsa_String(struct lsa_String *name, const char *s) { @@ -43,7 +46,7 @@ static bool test_OpenPolicy(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) NTSTATUS status; uint16_t system_name = '\\'; - printf("\ntesting OpenPolicy\n"); + printf("\nTesting OpenPolicy\n"); qos.len = 0; qos.impersonation_level = 2; @@ -85,7 +88,7 @@ bool test_lsa_OpenPolicy2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct lsa_OpenPolicy2 r; NTSTATUS status; - printf("\ntesting OpenPolicy2\n"); + printf("\nTesting OpenPolicy2\n"); *handle = talloc(mem_ctx, struct policy_handle); if (!*handle) { @@ -125,9 +128,27 @@ bool test_lsa_OpenPolicy2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return true; } + +static const char *sid_type_lookup(enum lsa_SidType r) +{ + switch (r) { + case SID_NAME_USE_NONE: return "SID_NAME_USE_NONE"; break; + case SID_NAME_USER: return "SID_NAME_USER"; break; + case SID_NAME_DOM_GRP: return "SID_NAME_DOM_GRP"; break; + case SID_NAME_DOMAIN: return "SID_NAME_DOMAIN"; break; + case SID_NAME_ALIAS: return "SID_NAME_ALIAS"; break; + case SID_NAME_WKN_GRP: return "SID_NAME_WKN_GRP"; break; + case SID_NAME_DELETED: return "SID_NAME_DELETED"; break; + case SID_NAME_INVALID: return "SID_NAME_INVALID"; break; + case SID_NAME_UNKNOWN: return "SID_NAME_UNKNOWN"; break; + case SID_NAME_COMPUTER: return "SID_NAME_COMPUTER"; break; + } + return "Invalid sid type\n"; +} + static bool test_LookupNames(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - struct policy_handle *handle, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, struct lsa_TransNameArray *tnames) { struct lsa_LookupNames r; @@ -157,11 +178,34 @@ static bool test_LookupNames(struct dcerpc_pipe *p, r.out.sids = &sids; status = dcerpc_lsa_LookupNames(p, mem_ctx, &r); - if (!NT_STATUS_IS_OK(status)) { + + if (NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED) || + NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) { + for (i=0;i< tnames->count;i++) { + if (i < count && sids.sids[i].sid_type == SID_NAME_UNKNOWN) { + printf("LookupName of %s was unmapped\n", + tnames->names[i].name.string); + } else if (i >=count) { + printf("LookupName of %s failed to return a result\n", + tnames->names[i].name.string); + } + } + printf("LookupNames failed - %s\n", nt_errstr(status)); + return false; + } else if (!NT_STATUS_IS_OK(status)) { printf("LookupNames failed - %s\n", nt_errstr(status)); return false; } - + + for (i=0;i< tnames->count;i++) { + if (i < count && sids.sids[i].sid_type != tnames->names[i].sid_type) { + printf("LookupName of %s got unexpected name type: %s\n", + tnames->names[i].name.string, sid_type_lookup(sids.sids[i].sid_type)); + } else if (i >=count) { + printf("LookupName of %s failed to return a result\n", + tnames->names[i].name.string); + } + } printf("\n"); return true; @@ -178,12 +222,13 @@ static bool test_LookupNames_bogus(struct dcerpc_pipe *p, NTSTATUS status; int i; - struct lsa_TranslatedName name; + struct lsa_TranslatedName name[2]; struct lsa_TransNameArray tnames; - tnames.names = &name; - tnames.count = 1; - name.name.string = "NT AUTHORITY\\BOGUS"; + tnames.names = name; + tnames.count = 2; + name[0].name.string = "NT AUTHORITY\\BOGUS"; + name[1].name.string = NULL; printf("\nTesting LookupNames with bogus names\n"); @@ -228,30 +273,39 @@ static bool test_LookupNames_wellknown(struct dcerpc_pipe *p, tnames.names = &name; tnames.count = 1; name.name.string = "NT AUTHORITY\\SYSTEM"; + name.sid_type = SID_NAME_WKN_GRP; ret &= test_LookupNames(p, mem_ctx, handle, &tnames); name.name.string = "NT AUTHORITY\\ANONYMOUS LOGON"; + name.sid_type = SID_NAME_WKN_GRP; ret &= test_LookupNames(p, mem_ctx, handle, &tnames); name.name.string = "NT AUTHORITY\\Authenticated Users"; + name.sid_type = SID_NAME_WKN_GRP; ret &= test_LookupNames(p, mem_ctx, handle, &tnames); +#if 0 name.name.string = "NT AUTHORITY"; ret &= test_LookupNames(p, mem_ctx, handle, &tnames); name.name.string = "NT AUTHORITY\\"; ret &= test_LookupNames(p, mem_ctx, handle, &tnames); +#endif name.name.string = "BUILTIN\\"; + name.sid_type = SID_NAME_DOMAIN; ret &= test_LookupNames(p, mem_ctx, handle, &tnames); name.name.string = "BUILTIN\\Administrators"; + name.sid_type = SID_NAME_ALIAS; ret &= test_LookupNames(p, mem_ctx, handle, &tnames); name.name.string = "SYSTEM"; + name.sid_type = SID_NAME_WKN_GRP; ret &= test_LookupNames(p, mem_ctx, handle, &tnames); name.name.string = "Everyone"; + name.sid_type = SID_NAME_WKN_GRP; ret &= test_LookupNames(p, mem_ctx, handle, &tnames); return ret; } @@ -284,8 +338,8 @@ static bool test_LookupNames2(struct dcerpc_pipe *p, r.in.sids = &sids; r.in.level = 1; r.in.count = &count; - r.in.unknown1 = 0; - r.in.unknown2 = 0; + r.in.lookup_options = 0; + r.in.client_revision = 0; r.out.count = &count; r.out.sids = &sids; @@ -329,8 +383,8 @@ static bool test_LookupNames3(struct dcerpc_pipe *p, r.in.sids = &sids; r.in.level = 1; r.in.count = &count; - r.in.unknown1 = 0; - r.in.unknown2 = 0; + r.in.lookup_options = 0; + r.in.client_revision = 0; r.out.count = &count; r.out.sids = &sids; @@ -371,8 +425,8 @@ static bool test_LookupNames4(struct dcerpc_pipe *p, r.in.sids = &sids; r.in.level = 1; r.in.count = &count; - r.in.unknown1 = 0; - r.in.unknown2 = 0; + r.in.lookup_options = 0; + r.in.client_revision = 0; r.out.count = &count; r.out.sids = &sids; @@ -562,7 +616,8 @@ bool test_many_LookupSids(struct dcerpc_pipe *p, if (!test_LookupNames(p, mem_ctx, handle, &names)) { return false; } - } else { + } else if (p->conn->security_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL && + p->conn->security_state.auth_info->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { struct lsa_LookupSids3 r; struct lsa_TransNameArray2 names; @@ -726,7 +781,8 @@ static bool test_LookupPrivName(struct dcerpc_pipe *p, } static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, struct policy_handle *acct_handle, struct lsa_LUID *luid) { @@ -735,7 +791,7 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, struct lsa_PrivilegeSet privs; bool ret = true; - printf("Testing RemovePrivilegesFromAccount\n"); + printf("\nTesting RemovePrivilegesFromAccount\n"); r.in.handle = acct_handle; r.in.remove_all = 0; @@ -749,7 +805,25 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, status = dcerpc_lsa_RemovePrivilegesFromAccount(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("RemovePrivilegesFromAccount failed - %s\n", nt_errstr(status)); + + struct lsa_LookupPrivName r_name; + + r_name.in.handle = handle; + r_name.in.luid = luid; + + status = dcerpc_lsa_LookupPrivName(p, mem_ctx, &r_name); + if (!NT_STATUS_IS_OK(status)) { + printf("\nLookupPrivName failed - %s\n", nt_errstr(status)); + return false; + } + /* Windows 2008 does not allow this to be removed */ + if (strcmp("SeAuditPrivilege", r_name.out.name->string) == 0) { + return ret; + } + + printf("RemovePrivilegesFromAccount failed to remove %s - %s\n", + r_name.out.name->string, + nt_errstr(status)); return false; } @@ -757,7 +831,7 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, } static bool test_AddPrivilegesToAccount(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, struct policy_handle *acct_handle, struct lsa_LUID *luid) { @@ -766,7 +840,7 @@ static bool test_AddPrivilegesToAccount(struct dcerpc_pipe *p, struct lsa_PrivilegeSet privs; bool ret = true; - printf("Testing AddPrivilegesToAccount\n"); + printf("\nTesting AddPrivilegesToAccount\n"); r.in.handle = acct_handle; r.in.privs = &privs; @@ -787,7 +861,7 @@ static bool test_AddPrivilegesToAccount(struct dcerpc_pipe *p, } static bool test_EnumPrivsAccount(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct policy_handle *acct_handle) { @@ -795,7 +869,7 @@ static bool test_EnumPrivsAccount(struct dcerpc_pipe *p, struct lsa_EnumPrivsAccount r; bool ret = true; - printf("Testing EnumPrivsAccount\n"); + printf("\nTesting EnumPrivsAccount\n"); r.in.handle = acct_handle; @@ -812,7 +886,7 @@ static bool test_EnumPrivsAccount(struct dcerpc_pipe *p, &r.out.privs->set[i].luid); } - ret &= test_RemovePrivilegesFromAccount(p, mem_ctx, acct_handle, + ret &= test_RemovePrivilegesFromAccount(p, mem_ctx, handle, acct_handle, &r.out.privs->set[0].luid); ret &= test_AddPrivilegesToAccount(p, mem_ctx, acct_handle, &r.out.privs->set[0].luid); @@ -821,6 +895,60 @@ static bool test_EnumPrivsAccount(struct dcerpc_pipe *p, return ret; } +static bool test_GetSystemAccessAccount(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + struct policy_handle *acct_handle) +{ + NTSTATUS status; + uint32_t access_mask; + struct lsa_GetSystemAccessAccount r; + + printf("\nTesting GetSystemAccessAccount\n"); + + r.in.handle = acct_handle; + r.out.access_mask = &access_mask; + + status = dcerpc_lsa_GetSystemAccessAccount(p, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status)) { + printf("GetSystemAccessAccount failed - %s\n", nt_errstr(status)); + return false; + } + + if (r.out.access_mask != NULL) { + printf("Rights:"); + if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE) + printf(" LSA_POLICY_MODE_INTERACTIVE"); + if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK) + printf(" LSA_POLICY_MODE_NETWORK"); + if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH) + printf(" LSA_POLICY_MODE_BATCH"); + if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE) + printf(" LSA_POLICY_MODE_SERVICE"); + if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY) + printf(" LSA_POLICY_MODE_PROXY"); + if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE) + printf(" LSA_POLICY_MODE_DENY_INTERACTIVE"); + if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK) + printf(" LSA_POLICY_MODE_DENY_NETWORK"); + if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH) + printf(" LSA_POLICY_MODE_DENY_BATCH"); + if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE) + printf(" LSA_POLICY_MODE_DENY_SERVICE"); + if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE) + printf(" LSA_POLICY_MODE_REMOTE_INTERACTIVE"); + if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE) + printf(" LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE"); + if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL) + printf(" LSA_POLICY_MODE_ALL"); + if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4) + printf(" LSA_POLICY_MODE_ALL_NT4"); + printf("\n"); + } + + return true; +} + static bool test_Delete(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle) @@ -828,12 +956,32 @@ static bool test_Delete(struct dcerpc_pipe *p, NTSTATUS status; struct lsa_Delete r; - printf("testing Delete\n"); + printf("\nTesting Delete\n"); r.in.handle = handle; status = dcerpc_lsa_Delete(p, mem_ctx, &r); + if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { + printf("Delete should have failed NT_STATUS_NOT_SUPPORTED - %s\n", nt_errstr(status)); + return false; + } + + return true; +} + +static bool test_DeleteObject(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle) +{ + NTSTATUS status; + struct lsa_DeleteObject r; + + printf("\nTesting DeleteObject\n"); + + r.in.handle = handle; + r.out.handle = handle; + status = dcerpc_lsa_DeleteObject(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("Delete failed - %s\n", nt_errstr(status)); + printf("DeleteObject failed - %s\n", nt_errstr(status)); return false; } @@ -852,7 +1000,7 @@ static bool test_CreateAccount(struct dcerpc_pipe *p, newsid = dom_sid_parse_talloc(mem_ctx, "S-1-5-12349876-4321-2854"); - printf("Testing CreateAccount\n"); + printf("\nTesting CreateAccount\n"); r.in.handle = handle; r.in.sid = newsid; @@ -860,7 +1008,19 @@ static bool test_CreateAccount(struct dcerpc_pipe *p, r.out.acct_handle = &acct_handle; status = dcerpc_lsa_CreateAccount(p, mem_ctx, &r); - if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { + struct lsa_OpenAccount r_o; + r_o.in.handle = handle; + r_o.in.sid = newsid; + r_o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + r_o.out.acct_handle = &acct_handle; + + status = dcerpc_lsa_OpenAccount(p, mem_ctx, &r_o); + if (!NT_STATUS_IS_OK(status)) { + printf("OpenAccount failed - %s\n", nt_errstr(status)); + return false; + } + } else if (!NT_STATUS_IS_OK(status)) { printf("CreateAccount failed - %s\n", nt_errstr(status)); return false; } @@ -869,6 +1029,10 @@ static bool test_CreateAccount(struct dcerpc_pipe *p, return false; } + if (!test_DeleteObject(p, mem_ctx, &acct_handle)) { + return false; + } + return true; } @@ -888,7 +1052,7 @@ static bool test_DeleteTrustedDomain(struct dcerpc_pipe *p, status = dcerpc_lsa_OpenTrustedDomainByName(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("lsa_OpenTrustedDomainByName failed - %s\n", nt_errstr(status)); + printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status)); return false; } @@ -896,6 +1060,10 @@ static bool test_DeleteTrustedDomain(struct dcerpc_pipe *p, return false; } + if (!test_DeleteObject(p, mem_ctx, &trustdom_handle)) { + return false; + } + return true; } @@ -912,7 +1080,7 @@ static bool test_DeleteTrustedDomainBySid(struct dcerpc_pipe *p, status = dcerpc_lsa_DeleteTrustedDomain(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("lsa_DeleteTrustedDomain failed - %s\n", nt_errstr(status)); + printf("DeleteTrustedDomain failed - %s\n", nt_errstr(status)); return false; } @@ -934,7 +1102,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, struct lsa_SetSecret r7; struct lsa_QuerySecret r8; struct policy_handle sec_handle, sec_handle2, sec_handle3; - struct lsa_Delete d; + struct lsa_DeleteObject d_o; struct lsa_DATA_BUF buf1; struct lsa_DATA_BUF_PTR bufp1; struct lsa_DATA_BUF_PTR bufp2; @@ -958,7 +1126,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, secname[GLOBAL] = talloc_asprintf(mem_ctx, "G$torturesecret-%u", (uint_t)random()); for (i=0; i< 2; i++) { - printf("Testing CreateSecret of %s\n", secname[i]); + printf("\nTesting CreateSecret of %s\n", secname[i]); init_lsa_String(&r.in.name, secname[i]); @@ -1069,7 +1237,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, &blob1, &session_key); if (strcmp(secret1, secret2) != 0) { - printf("Returned secret '%s' doesn't match '%s'\n", + printf("Returned secret (r4) '%s' doesn't match '%s'\n", secret2, secret1); ret = false; } @@ -1084,7 +1252,9 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, r5.in.new_val->data = enc_key.data; r5.in.new_val->length = enc_key.length; r5.in.new_val->size = enc_key.length; - + + + msleep(200); printf("Testing SetSecret (existing value should move to old)\n"); status = dcerpc_lsa_SetSecret(p, mem_ctx, &r5); @@ -1148,8 +1318,10 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, } if (*r6.out.new_mtime == *r6.out.old_mtime) { - printf("Returned secret %s had same mtime for both secrets: %s\n", + printf("Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n", + i, secname[i], + nt_time_string(mem_ctx, *r6.out.old_mtime), nt_time_string(mem_ctx, *r6.out.new_mtime)); ret = false; } @@ -1193,35 +1365,16 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, 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.new_val->buf != NULL) { + printf("NEW secret buffer must not be returned after OLD set\n"); + ret = false; } else if (r8.out.old_val->buf == NULL) { - printf("OLD secret buffer not returned after OLD set\n"); + printf("OLD secret buffer was 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; @@ -1235,15 +1388,8 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, 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", + if (*r8.out.new_mtime != *r8.out.old_mtime) { + printf("Returned secret (r8) %s did not 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)); @@ -1256,8 +1402,13 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, ret = false; } - d.in.handle = &sec_handle2; - status = dcerpc_lsa_Delete(p, mem_ctx, &d); + if (!test_DeleteObject(p, mem_ctx, &sec_handle)) { + return false; + } + + d_o.in.handle = &sec_handle2; + d_o.out.handle = &sec_handle2; + status = dcerpc_lsa_DeleteObject(p, mem_ctx, &d_o); if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) { printf("Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status)); ret = false; @@ -1287,7 +1438,7 @@ static bool test_EnumAccountRights(struct dcerpc_pipe *p, struct lsa_EnumAccountRights r; struct lsa_RightSet rights; - printf("Testing EnumAccountRights\n"); + printf("\nTesting EnumAccountRights\n"); r.in.handle = acct_handle; r.in.sid = sid; @@ -1305,24 +1456,24 @@ static bool test_EnumAccountRights(struct dcerpc_pipe *p, static bool test_QuerySecurity(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, + struct torture_context *tctx, struct policy_handle *handle, struct policy_handle *acct_handle) { NTSTATUS status; struct lsa_QuerySecurity r; - if (lp_parm_bool(global_loadparm, NULL, "torture", "samba4", false)) { - printf("skipping QuerySecurity test against Samba4\n"); + if (torture_setting_bool(tctx, "samba4", false)) { + printf("\nskipping QuerySecurity test against Samba4\n"); return true; } - printf("Testing QuerySecurity\n"); + printf("\nTesting QuerySecurity\n"); r.in.handle = acct_handle; r.in.sec_info = 7; - status = dcerpc_lsa_QuerySecurity(p, mem_ctx, &r); + status = dcerpc_lsa_QuerySecurity(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("QuerySecurity failed - %s\n", nt_errstr(status)); return false; @@ -1340,7 +1491,7 @@ static bool test_OpenAccount(struct dcerpc_pipe *p, struct lsa_OpenAccount r; struct policy_handle acct_handle; - printf("Testing OpenAccount\n"); + printf("\nTesting OpenAccount\n"); r.in.handle = handle; r.in.sid = sid; @@ -1357,6 +1508,10 @@ static bool test_OpenAccount(struct dcerpc_pipe *p, return false; } + if (!test_GetSystemAccessAccount(p, mem_ctx, handle, &acct_handle)) { + return false; + } + if (!test_QuerySecurity(p, mem_ctx, handle, &acct_handle)) { return false; } @@ -1375,7 +1530,7 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p, int i; bool ret = true; - printf("\ntesting EnumAccounts\n"); + printf("\nTesting EnumAccounts\n"); r.in.handle = handle; r.in.resume_handle = &resume_handle; @@ -1402,11 +1557,11 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p, return false; } - if (!test_LookupSids3(p, mem_ctx, &sids1)) { - return false; - } + /* Can't test lookupSids3 here, as clearly we must not + * be on schannel, or we would not be able to do the + * rest */ - printf("testing all accounts\n"); + printf("Testing all accounts\n"); for (i=0;istring); + printf("\nTesting LookupPrivDisplayName(%s)\n", priv_name->string); r.in.handle = handle; r.in.name = priv_name; @@ -1479,7 +1634,7 @@ static bool test_EnumAccountsWithUserRight(struct dcerpc_pipe *p, ZERO_STRUCT(sids); - printf("testing EnumAccountsWithUserRight(%s)\n", priv_name->string); + printf("\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string); r.in.handle = handle; r.in.name = priv_name; @@ -1512,7 +1667,7 @@ static bool test_EnumPrivs(struct dcerpc_pipe *p, int i; bool ret = true; - printf("\ntesting EnumPrivs\n"); + printf("\nTesting EnumPrivs\n"); r.in.handle = handle; r.in.resume_handle = &resume_handle; @@ -1539,7 +1694,7 @@ static bool test_EnumPrivs(struct dcerpc_pipe *p, } static bool test_QueryForestTrustInformation(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, + struct torture_context *tctx, struct policy_handle *handle, const char *trusted_domain_name) { @@ -1551,7 +1706,7 @@ static bool test_QueryForestTrustInformation(struct dcerpc_pipe *p, printf("\nTesting lsaRQueryForestTrustInformation\n"); - if (lp_parm_bool(global_loadparm, NULL, "torture", "samba4", false)) { + if (torture_setting_bool(tctx, "samba4", false)) { printf("skipping QueryForestTrustInformation against Samba4\n"); return true; } @@ -1569,10 +1724,10 @@ static bool test_QueryForestTrustInformation(struct dcerpc_pipe *p, r.in.unknown = 0; r.out.forest_trust_info = &info_ptr; - status = dcerpc_lsa_lsaRQueryForestTrustInformation(p, mem_ctx, &r); + status = dcerpc_lsa_lsaRQueryForestTrustInformation(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("lsaRQueryForestTrustInformation failed - %s\n", nt_errstr(status)); + printf("lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(status)); ret = false; } @@ -1615,8 +1770,8 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p, 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}; + int levels [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; + int ok[] = {1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1}; if (domains->domains[i].sid) { trust.in.handle = handle; @@ -1770,6 +1925,27 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, printf("\nTesting EnumTrustDom\n"); + r.in.handle = handle; + r.in.resume_handle = &resume_handle; + r.in.max_size = 0; + r.out.domains = &domains; + r.out.resume_handle = &resume_handle; + + enum_status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r); + + if (NT_STATUS_IS_OK(enum_status)) { + if (domains.count == 0) { + printf("EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n"); + return false; + } + } else if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) { + printf("EnumTrustDom of zero size failed - %s\n", nt_errstr(enum_status)); + return false; + } + + /* Start from the bottom again */ + resume_handle = 0; + do { r.in.handle = handle; r.in.resume_handle = &resume_handle; @@ -1781,7 +1957,11 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, /* NO_MORE_ENTRIES is allowed */ if (NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES)) { - return true; + if (domains.count == 0) { + return true; + } + printf("EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n"); + return false; } else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) { /* Windows 2003 gets this off by one on the first run */ if (r.out.domains->count < 3 || r.out.domains->count > 4) { @@ -1796,12 +1976,30 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, return false; } + if (domains.count == 0) { + printf("EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n"); + return false; + } + ret &= test_query_each_TrustDom(p, mem_ctx, handle, &domains); } while ((NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES))); printf("\nTesting EnumTrustedDomainsEx\n"); + r_ex.in.handle = handle; + r_ex.in.resume_handle = &resume_handle; + r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3; + r_ex.out.domains = &domains_ex; + r_ex.out.resume_handle = &resume_handle; + + enum_status = dcerpc_lsa_EnumTrustedDomainsEx(p, mem_ctx, &r_ex); + + if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) { + printf("EnumTrustedDomainEx of zero size failed - %s\n", nt_errstr(enum_status)); + return false; + } + resume_handle = 0; do { r_ex.in.handle = handle; @@ -1814,7 +2012,11 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, /* NO_MORE_ENTRIES is allowed */ if (NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES)) { - return true; + if (domains_ex.count == 0) { + return true; + } + printf("EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n"); + return false; } else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) { /* Windows 2003 gets this off by one on the first run */ if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) { @@ -1824,14 +2026,17 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, r_ex.in.max_size, LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER, r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER); - ret = false; - exit(1); } } else if (!NT_STATUS_IS_OK(enum_status)) { printf("EnumTrustedDomainEx failed - %s\n", nt_errstr(enum_status)); return false; } + if (domains_ex.count == 0) { + printf("EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n"); + return false; + } + ret &= test_query_each_TrustDomEx(p, mem_ctx, handle, &domains_ex); } while ((NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES))); @@ -1852,8 +2057,12 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p, struct lsa_QueryTrustedDomainInfo q; int i; - printf("Testing CreateTrustedDomain for 12 domains\n"); + printf("\nTesting CreateTrustedDomain for 12 domains\n"); + if (!test_EnumTrustDom(p, mem_ctx, handle)) { + ret = false; + } + for (i=0; i< 12; i++) { char *trust_name = talloc_asprintf(mem_ctx, "torturedom%02d", i); char *trust_sid = talloc_asprintf(mem_ctx, "S-1-5-21-97398-379795-100%02d", i); @@ -1863,7 +2072,7 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p, trustinfo.sid = domsid[i]; init_lsa_String((struct lsa_String *)&trustinfo.name, trust_name); - r.in.handle = handle; + r.in.policy_handle = handle; r.in.info = &trustinfo; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.trustdom_handle = &trustdom_handle[i]; @@ -1879,7 +2088,7 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p, } else { q.in.trustdom_handle = &trustdom_handle[i]; - q.in.level = LSA_TRUSTED_DOMAIN_INFO_NAME; + q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX; status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q); if (!NT_STATUS_IS_OK(status)) { printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status)); @@ -1887,9 +2096,24 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p, } else if (!q.out.info) { ret = false; } else { - if (strcmp(q.out.info->name.netbios_name.string, trustinfo.name.string) != 0) { + if (strcmp(q.out.info->info_ex.netbios_name.string, trustinfo.name.string) != 0) { printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n", - q.out.info->name.netbios_name.string, trustinfo.name.string); + q.out.info->info_ex.netbios_name.string, trustinfo.name.string); + ret = false; + } + if (q.out.info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) { + printf("QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n", + trust_name, q.out.info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL); + ret = false; + } + if (q.out.info->info_ex.trust_attributes != 0) { + printf("QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n", + trust_name, q.out.info->info_ex.trust_attributes, 0); + ret = false; + } + if (q.out.info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) { + printf("QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n", + trust_name, q.out.info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND); ret = false; } } @@ -1910,18 +2134,149 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p, return ret; } +static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, + struct torture_context *tctx, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle) +{ + NTSTATUS status; + bool ret = true; + struct lsa_CreateTrustedDomainEx2 r; + struct lsa_TrustDomainInfoInfoEx trustinfo; + struct lsa_TrustDomainInfoAuthInfoInternal authinfo; + struct trustDomainPasswords auth_struct; + DATA_BLOB auth_blob; + struct dom_sid *domsid[12]; + struct policy_handle trustdom_handle[12]; + struct lsa_QueryTrustedDomainInfo q; + DATA_BLOB session_key; + enum ndr_err_code ndr_err; + int i; + + printf("\nTesting CreateTrustedDomainEx2 for 12 domains\n"); + + status = dcerpc_fetch_session_key(p, &session_key); + if (!NT_STATUS_IS_OK(status)) { + printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status)); + return false; + } + + for (i=0; i< 12; i++) { + char *trust_name = talloc_asprintf(mem_ctx, "torturedom%02d", i); + char *trust_name_dns = talloc_asprintf(mem_ctx, "torturedom%02d.samba.example.com", i); + char *trust_sid = talloc_asprintf(mem_ctx, "S-1-5-21-97398-379795-100%02d", i); + + domsid[i] = dom_sid_parse_talloc(mem_ctx, trust_sid); + + trustinfo.sid = domsid[i]; + trustinfo.netbios_name.string = trust_name; + trustinfo.domain_name.string = trust_name_dns; + + /* Create inbound, some outbound, and some + * bi-directional trusts in a repeating pattern based + * on i */ + + /* 1 == inbound, 2 == outbound, 3 == both */ + trustinfo.trust_direction = (i % 3) + 1; + + /* Try different trust types too */ + + /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */ + trustinfo.trust_type = (((i / 3) + 1) % 3) + 1; + + trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION; + + generate_random_buffer(auth_struct.confounder, sizeof(auth_struct.confounder)); + + auth_struct.outgoing.count = 0; + auth_struct.incoming.count = 0; + + ndr_err = ndr_push_struct_blob(&auth_blob, mem_ctx, lp_iconv_convenience(tctx->lp_ctx), &auth_struct, + (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + printf("ndr_push_struct_blob of trustDomainPasswords structure failed"); + ret = false; + } + + arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key); + + authinfo.auth_blob.size = auth_blob.length; + authinfo.auth_blob.data = auth_blob.data; + + r.in.policy_handle = handle; + r.in.info = &trustinfo; + r.in.auth_info = &authinfo; + r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + r.out.trustdom_handle = &trustdom_handle[i]; + + status = dcerpc_lsa_CreateTrustedDomainEx2(p, mem_ctx, &r); + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { + test_DeleteTrustedDomain(p, mem_ctx, handle, trustinfo.netbios_name); + status = dcerpc_lsa_CreateTrustedDomainEx2(p, mem_ctx, &r); + } + if (!NT_STATUS_IS_OK(status)) { + printf("CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status)); + ret = false; + } else { + + q.in.trustdom_handle = &trustdom_handle[i]; + q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX; + status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q); + if (!NT_STATUS_IS_OK(status)) { + printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status)); + ret = false; + } else if (!q.out.info) { + printf("QueryTrustedDomainInfo level 1 failed to return an info pointer\n"); + ret = false; + } else { + if (strcmp(q.out.info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) { + printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n", + q.out.info->info_ex.netbios_name.string, trustinfo.netbios_name.string); + ret = false; + } + if (q.out.info->info_ex.trust_type != trustinfo.trust_type) { + printf("QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n", + trust_name, q.out.info->info_ex.trust_type, trustinfo.trust_type); + ret = false; + } + if (q.out.info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) { + printf("QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n", + trust_name, q.out.info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION); + ret = false; + } + if (q.out.info->info_ex.trust_direction != trustinfo.trust_direction) { + printf("QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n", + trust_name, q.out.info->info_ex.trust_direction, trustinfo.trust_direction); + ret = false; + } + } + } + } + + /* now that we have some domains to look over, we can test the enum calls */ + if (!test_EnumTrustDom(p, mem_ctx, handle)) { + printf("test_EnumTrustDom failed\n"); + ret = false; + } + + for (i=0; i<12; i++) { + if (!test_DeleteTrustedDomainBySid(p, mem_ctx, handle, domsid[i])) { + printf("test_DeleteTrustedDomainBySid failed\n"); + ret = false; + } + } + + return ret; +} + static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, + struct torture_context *tctx, struct policy_handle *handle) { struct lsa_QueryDomainInformationPolicy r; NTSTATUS status; int i; bool ret = true; - if (lp_parm_bool(global_loadparm, NULL, "torture", "samba4", false)) { - printf("skipping QueryDomainInformationPolicy test against Samba4\n"); - return true; - } printf("\nTesting QueryDomainInformationPolicy\n"); @@ -1929,11 +2284,14 @@ static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p, r.in.handle = handle; r.in.level = i; - printf("\ntrying QueryDomainInformationPolicy level %d\n", i); + printf("\nTrying QueryDomainInformationPolicy level %d\n", i); - status = dcerpc_lsa_QueryDomainInformationPolicy(p, mem_ctx, &r); + status = dcerpc_lsa_QueryDomainInformationPolicy(p, tctx, &r); - if (!NT_STATUS_IS_OK(status)) { + /* If the server does not support EFS, then this is the correct return */ + if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + continue; + } else if (!NT_STATUS_IS_OK(status)) { printf("QueryDomainInformationPolicy failed - %s\n", nt_errstr(status)); ret = false; continue; @@ -1944,133 +2302,141 @@ static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p, } -static bool test_QueryInfoPolicy(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - struct policy_handle *handle) +static bool test_QueryInfoPolicyCalls( bool version2, + struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *handle) { struct lsa_QueryInfoPolicy r; NTSTATUS status; int i; bool ret = true; - printf("\nTesting QueryInfoPolicy\n"); - if (lp_parm_bool(global_loadparm, NULL, "torture", "samba4", false)) { - printf("skipping QueryInfoPolicy against Samba4\n"); - return true; - } + if (version2) + printf("\nTesting QueryInfoPolicy2\n"); + else + printf("\nTesting QueryInfoPolicy\n"); - for (i=1;i<13;i++) { + for (i=1;i<=14;i++) { r.in.handle = handle; r.in.level = i; - printf("\ntrying QueryInfoPolicy level %d\n", i); + if (version2) + printf("\nTrying QueryInfoPolicy2 level %d\n", i); + else + printf("\nTrying QueryInfoPolicy level %d\n", i); - status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r); + if (version2) + /* We can perform the cast, because both types are + structurally equal */ + status = dcerpc_lsa_QueryInfoPolicy2(p, tctx, + (struct lsa_QueryInfoPolicy2*) &r); + else + status = dcerpc_lsa_QueryInfoPolicy(p, tctx, &r); switch (i) { - case LSA_POLICY_INFO_DB: + case LSA_POLICY_INFO_MOD: case LSA_POLICY_INFO_AUDIT_FULL_SET: case LSA_POLICY_INFO_AUDIT_FULL_QUERY: if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { - printf("server should have failed level %u: %s\n", i, nt_errstr(status)); + printf("Server should have failed level %u: %s\n", i, nt_errstr(status)); ret = false; } break; case LSA_POLICY_INFO_DOMAIN: case LSA_POLICY_INFO_ACCOUNT_DOMAIN: + case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN: + case LSA_POLICY_INFO_DNS_INT: case LSA_POLICY_INFO_DNS: + case LSA_POLICY_INFO_REPLICA: + case LSA_POLICY_INFO_QUOTA: + case LSA_POLICY_INFO_ROLE: + case LSA_POLICY_INFO_AUDIT_LOG: + case LSA_POLICY_INFO_AUDIT_EVENTS: + case LSA_POLICY_INFO_PD: if (!NT_STATUS_IS_OK(status)) { - printf("QueryInfoPolicy failed - %s\n", nt_errstr(status)); + if (version2) + printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status)); + else + printf("QueryInfoPolicy failed - %s\n", nt_errstr(status)); ret = false; } break; default: - if (lp_parm_bool(global_loadparm, NULL, "torture", "samba4", false)) { + if (torture_setting_bool(tctx, "samba4", false)) { /* Other levels not implemented yet */ if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) { - printf("QueryInfoPolicy failed - %s\n", nt_errstr(status)); + if (version2) + printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status)); + else + printf("QueryInfoPolicy failed - %s\n", nt_errstr(status)); ret = false; } } else if (!NT_STATUS_IS_OK(status)) { - printf("QueryInfoPolicy failed - %s\n", nt_errstr(status)); + if (version2) + printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status)); + else + printf("QueryInfoPolicy failed - %s\n", nt_errstr(status)); ret = false; } break; } - if (NT_STATUS_IS_OK(status) && i == LSA_POLICY_INFO_DNS) { + if (NT_STATUS_IS_OK(status) && (i == LSA_POLICY_INFO_DNS + || i == LSA_POLICY_INFO_DNS_INT)) { /* Let's look up some of these names */ struct lsa_TransNameArray tnames; - tnames.count = 10; - tnames.names = talloc_array(mem_ctx, struct lsa_TranslatedName, tnames.count); + tnames.count = 14; + tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count); tnames.names[0].name.string = r.out.info->dns.name.string; + tnames.names[0].sid_type = SID_NAME_DOMAIN; tnames.names[1].name.string = r.out.info->dns.dns_domain.string; - tnames.names[2].name.string = talloc_asprintf(mem_ctx, "%s\\", r.out.info->dns.name.string); - tnames.names[3].name.string = talloc_asprintf(mem_ctx, "%s\\", r.out.info->dns.dns_domain.string); - tnames.names[4].name.string = talloc_asprintf(mem_ctx, "%s\\guest", r.out.info->dns.name.string); - tnames.names[5].name.string = talloc_asprintf(mem_ctx, "%s\\krbtgt", r.out.info->dns.name.string); - tnames.names[6].name.string = talloc_asprintf(mem_ctx, "%s\\guest", r.out.info->dns.dns_domain.string); - tnames.names[7].name.string = talloc_asprintf(mem_ctx, "%s\\krbtgt", r.out.info->dns.dns_domain.string); - tnames.names[8].name.string = talloc_asprintf(mem_ctx, "krbtgt@%s", r.out.info->dns.name.string); - tnames.names[9].name.string = talloc_asprintf(mem_ctx, "krbtgt@%s", r.out.info->dns.dns_domain.string); - ret &= test_LookupNames(p, mem_ctx, handle, &tnames); + tnames.names[1].sid_type = SID_NAME_DOMAIN; + tnames.names[2].name.string = talloc_asprintf(tctx, "%s\\", r.out.info->dns.name.string); + tnames.names[2].sid_type = SID_NAME_DOMAIN; + tnames.names[3].name.string = talloc_asprintf(tctx, "%s\\", r.out.info->dns.dns_domain.string); + tnames.names[3].sid_type = SID_NAME_DOMAIN; + tnames.names[4].name.string = talloc_asprintf(tctx, "%s\\guest", r.out.info->dns.name.string); + tnames.names[4].sid_type = SID_NAME_USER; + tnames.names[5].name.string = talloc_asprintf(tctx, "%s\\krbtgt", r.out.info->dns.name.string); + tnames.names[5].sid_type = SID_NAME_USER; + tnames.names[6].name.string = talloc_asprintf(tctx, "%s\\guest", r.out.info->dns.dns_domain.string); + tnames.names[6].sid_type = SID_NAME_USER; + tnames.names[7].name.string = talloc_asprintf(tctx, "%s\\krbtgt", r.out.info->dns.dns_domain.string); + tnames.names[7].sid_type = SID_NAME_USER; + tnames.names[8].name.string = talloc_asprintf(tctx, "krbtgt@%s", r.out.info->dns.name.string); + tnames.names[8].sid_type = SID_NAME_USER; + tnames.names[9].name.string = talloc_asprintf(tctx, "krbtgt@%s", r.out.info->dns.dns_domain.string); + tnames.names[9].sid_type = SID_NAME_USER; + tnames.names[10].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", r.out.info->dns.name.string); + tnames.names[10].sid_type = SID_NAME_USER; + tnames.names[11].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", r.out.info->dns.dns_domain.string); + tnames.names[11].sid_type = SID_NAME_USER; + tnames.names[12].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", r.out.info->dns.name.string); + tnames.names[12].sid_type = SID_NAME_USER; + tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", r.out.info->dns.dns_domain.string); + tnames.names[13].sid_type = SID_NAME_USER; + ret &= test_LookupNames(p, tctx, handle, &tnames); + } } return ret; } +static bool test_QueryInfoPolicy(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *handle) +{ + return test_QueryInfoPolicyCalls(false, p, tctx, handle); +} + static bool test_QueryInfoPolicy2(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, + struct torture_context *tctx, struct policy_handle *handle) { - struct lsa_QueryInfoPolicy2 r; - NTSTATUS status; - int i; - bool ret = true; - printf("\nTesting QueryInfoPolicy2\n"); - for (i=1;i<13;i++) { - r.in.handle = handle; - r.in.level = i; - - printf("\ntrying QueryInfoPolicy2 level %d\n", i); - - status = dcerpc_lsa_QueryInfoPolicy2(p, mem_ctx, &r); - - switch (i) { - case LSA_POLICY_INFO_DB: - case LSA_POLICY_INFO_AUDIT_FULL_SET: - case LSA_POLICY_INFO_AUDIT_FULL_QUERY: - if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { - printf("server should have failed level %u: %s\n", i, nt_errstr(status)); - ret = false; - } - break; - case LSA_POLICY_INFO_DOMAIN: - case LSA_POLICY_INFO_ACCOUNT_DOMAIN: - case LSA_POLICY_INFO_DNS: - if (!NT_STATUS_IS_OK(status)) { - printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status)); - ret = false; - } - break; - default: - if (lp_parm_bool(global_loadparm, NULL, "torture", "samba4", false)) { - /* Other levels not implemented yet */ - if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) { - printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status)); - ret = false; - } - } else if (!NT_STATUS_IS_OK(status)) { - printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status)); - ret = false; - } - break; - } - } - - return ret; + return test_QueryInfoPolicyCalls(true, p, tctx, handle); } static bool test_GetUserName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) @@ -2105,7 +2471,7 @@ bool test_lsa_Close(struct dcerpc_pipe *p, struct lsa_Close r; struct policy_handle handle2; - printf("\ntesting Close\n"); + printf("\nTesting Close\n"); r.in.handle = handle; r.out.handle = &handle2; @@ -2128,99 +2494,103 @@ bool test_lsa_Close(struct dcerpc_pipe *p, return true; } -bool torture_rpc_lsa(struct torture_context *torture) +bool torture_rpc_lsa(struct torture_context *tctx) { NTSTATUS status; struct dcerpc_pipe *p; - TALLOC_CTX *mem_ctx; bool ret = true; struct policy_handle *handle; + struct test_join *join = NULL; + struct cli_credentials *machine_creds; - mem_ctx = talloc_init("torture_rpc_lsa"); - - status = torture_rpc_connection(torture, &p, &ndr_table_lsarpc); + status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc); if (!NT_STATUS_IS_OK(status)) { - talloc_free(mem_ctx); return false; } - if (!test_OpenPolicy(p, mem_ctx)) { + if (!test_OpenPolicy(p, tctx)) { ret = false; } - if (!test_lsa_OpenPolicy2(p, mem_ctx, &handle)) { + if (!test_lsa_OpenPolicy2(p, tctx, &handle)) { ret = false; } if (handle) { - if (!test_LookupNames_wellknown(p, mem_ctx, handle)) { + join = torture_join_domain(tctx, TEST_MACHINENAME, ACB_WSTRUST, &machine_creds); + if (!join) { + ret = false; + } + if (!test_LookupNames_wellknown(p, tctx, handle)) { ret = false; } - if (!test_LookupNames_bogus(p, mem_ctx, handle)) { + if (!test_LookupNames_bogus(p, tctx, handle)) { ret = false; } - if (!test_LookupSids_async(p, mem_ctx, handle)) { + if (!test_LookupSids_async(p, tctx, handle)) { ret = false; } - if (!test_QueryDomainInfoPolicy(p, mem_ctx, handle)) { + if (!test_QueryDomainInfoPolicy(p, tctx, handle)) { ret = false; } - if (!test_CreateAccount(p, mem_ctx, handle)) { + if (!test_CreateAccount(p, tctx, handle)) { ret = false; } - if (!test_CreateSecret(p, mem_ctx, handle)) { + if (!test_CreateSecret(p, tctx, handle)) { ret = false; } - - if (!test_CreateTrustedDomain(p, mem_ctx, handle)) { + if (!test_CreateTrustedDomain(p, tctx, handle)) { ret = false; } - - if (!test_EnumAccounts(p, mem_ctx, handle)) { + + if (!test_CreateTrustedDomainEx2(p, tctx, tctx, handle)) { + ret = false; + } + + if (!test_EnumAccounts(p, tctx, handle)) { ret = false; } - if (!test_EnumPrivs(p, mem_ctx, handle)) { + if (!test_EnumPrivs(p, tctx, handle)) { ret = false; } - if (!test_QueryInfoPolicy(p, mem_ctx, handle)) { + if (!test_QueryInfoPolicy(p, tctx, handle)) { ret = false; } - if (!test_QueryInfoPolicy2(p, mem_ctx, handle)) { + if (!test_QueryInfoPolicy2(p, tctx, handle)) { ret = false; } -#if 0 - if (!test_Delete(p, mem_ctx, handle)) { + if (!test_Delete(p, tctx, handle)) { ret = false; } -#endif - if (!test_many_LookupSids(p, mem_ctx, handle)) { + if (!test_many_LookupSids(p, tctx, handle)) { ret = false; } - if (!test_lsa_Close(p, mem_ctx, handle)) { + if (!test_lsa_Close(p, tctx, handle)) { ret = false; } + + torture_leave_domain(tctx, join); + } else { - if (!test_many_LookupSids(p, mem_ctx, handle)) { + if (!test_many_LookupSids(p, tctx, handle)) { ret = false; } } - if (!test_GetUserName(p, mem_ctx)) { + if (!test_GetUserName(p, tctx)) { ret = false; } - - talloc_free(mem_ctx); return ret; }