From 9ade3cce58a26560920535496832e796f2fc0d90 Mon Sep 17 00:00:00 2001 From: Qian Hong Date: Wed, 1 Apr 2015 18:05:42 +0800 Subject: [PATCH] advapi32: prepend a hidden Domain[-1] to prevent application crashing when access to Domain[-1] by accident. --- dlls/advapi32/lsa.c | 9 ++++++--- dlls/advapi32/tests/lsa.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/dlls/advapi32/lsa.c b/dlls/advapi32/lsa.c index 2a8b791..8320d58 100644 --- a/dlls/advapi32/lsa.c +++ b/dlls/advapi32/lsa.c @@ -488,14 +488,16 @@ NTSTATUS WINAPI LsaLookupSids( if (!(*Names = heap_alloc(name_fullsize))) return STATUS_NO_MEMORY; /* maximum count of stored domain infos is Count, allocate it like that cause really needed count could only be computed after sid data is retrieved */ - domain_fullsize = sizeof(LSA_REFERENCED_DOMAIN_LIST) + sizeof(LSA_TRUST_INFORMATION)*Count; + domain_fullsize = sizeof(LSA_REFERENCED_DOMAIN_LIST) + sizeof(LSA_TRUST_INFORMATION)*(Count+1); if (!(*ReferencedDomains = heap_alloc(domain_fullsize))) { heap_free(*Names); return STATUS_NO_MEMORY; } (*ReferencedDomains)->Entries = 0; - (*ReferencedDomains)->Domains = (LSA_TRUST_INFORMATION*)((char*)*ReferencedDomains + sizeof(LSA_REFERENCED_DOMAIN_LIST)); + (*ReferencedDomains)->Domains = (LSA_TRUST_INFORMATION*)((char*)*ReferencedDomains + sizeof(LSA_REFERENCED_DOMAIN_LIST) + sizeof(LSA_TRUST_INFORMATION)); + (*ReferencedDomains)->Domains[-1].Name.Buffer = NULL; + (*ReferencedDomains)->Domains[-1].Name.Length = 0; /* Get full names data length and full length needed to store domain name and SID */ for (i = 0; i < Count; i++) @@ -503,6 +505,7 @@ NTSTATUS WINAPI LsaLookupSids( (*Names)[i].Use = SidTypeUnknown; (*Names)[i].DomainIndex = -1; (*Names)[i].Name.Buffer = NULL; + (*Names)[i].Name.Length = 0; memset(&(*ReferencedDomains)->Domains[i], 0, sizeof(LSA_TRUST_INFORMATION)); @@ -555,7 +558,7 @@ NTSTATUS WINAPI LsaLookupSids( *ReferencedDomains = heap_realloc(*ReferencedDomains, domain_fullsize); /* fix pointer after reallocation */ - (*ReferencedDomains)->Domains = (LSA_TRUST_INFORMATION*)((char*)*ReferencedDomains + sizeof(LSA_REFERENCED_DOMAIN_LIST)); + (*ReferencedDomains)->Domains = (LSA_TRUST_INFORMATION*)((char*)*ReferencedDomains + sizeof(LSA_REFERENCED_DOMAIN_LIST) + sizeof(LSA_TRUST_INFORMATION)); domain_data = (char*)(*ReferencedDomains)->Domains + sizeof(LSA_TRUST_INFORMATION)*Count; mapped = 0; diff --git a/dlls/advapi32/tests/lsa.c b/dlls/advapi32/tests/lsa.c index 1a0d211..38fee45 100644 --- a/dlls/advapi32/tests/lsa.c +++ b/dlls/advapi32/tests/lsa.c @@ -361,7 +361,10 @@ static void test_LsaLookupSids(void) LSA_TRANSLATED_NAME *names; LSA_HANDLE policy; TOKEN_USER *user; + TOKEN_GROUPS *groups; + int group_id; NTSTATUS status; + PSID sids[257]; HANDLE token; DWORD size; BOOL ret; @@ -392,6 +395,7 @@ static void test_LsaLookupSids(void) ok((char*)list->Domains[0].Sid - (char*)list->Domains > 0, "%p, %p\n", list->Domains, list->Domains[0].Sid); ok(list->Domains[0].Name.MaximumLength > list->Domains[0].Name.Length, "got %d, %d\n", list->Domains[0].Name.MaximumLength, list->Domains[0].Name.Length); + trace("haha names[0].DomainIndex %d\n", names[0].DomainIndex); } pLsaFreeMemory(names); @@ -399,6 +403,39 @@ static void test_LsaLookupSids(void) HeapFree(GetProcessHeap(), 0, user); + /* Test Enum TokenGroups */ + ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size); + ok(!ret, "got %d\n", ret); + + groups = HeapAlloc(GetProcessHeap(), 0, size); + ret = GetTokenInformation(token, TokenGroups, groups, size, &size); + ok(ret, "got %d\n", ret); + + for (group_id = 0; group_id < groups->GroupCount; group_id++) + sids[group_id] = groups->Groups[group_id].Sid; + + status = pLsaLookupSids(policy, groups->GroupCount, sids, &list, &names); + ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); + + ok(list->Entries > 0, "got %d\n", list->Entries); + for (group_id = 0; group_id < groups->GroupCount; group_id++) + { + trace("entries %d\n", list->Entries); + if (list->Entries) + { + trace("names[%d].DomainIndex %d\n", group_id, names[group_id].DomainIndex); + trace("use %d\n", names[group_id].Use); + trace("name %s\n", wine_dbgstr_wn(names[group_id].Name.Buffer, names[group_id].Name.Length/sizeof(WCHAR))); + trace("domain name %s\n", wine_dbgstr_wn(list->Domains[names[group_id].DomainIndex].Name.Buffer, list->Domains[names[group_id].DomainIndex].Name.Length/sizeof(WCHAR))); + } + trace("domain sid %p\n", list->Domains[names[group_id].DomainIndex].Sid); + } + + pLsaFreeMemory(names); + pLsaFreeMemory(list); + + HeapFree(GetProcessHeap(), 0, groups); + CloseHandle(token); status = pLsaClose(policy); -- 2.1.0