From 23fa5c43fa5fde7b65ad3867126035c79fc1b038 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Thu, 15 Mar 2012 16:10:42 +0800 Subject: [PATCH] advapi32: Add some mutex security tests. --- dlls/advapi32/tests/security.c | 176 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index c8db437fdac..c3de8e4dbd7 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -3983,6 +3983,181 @@ static void test_CreateRestrictedToken(void) CloseHandle(process_token); } +static void validate_default_security_descriptor(SECURITY_DESCRIPTOR *sd) +{ + BOOL ret, present, defaulted; + ACL *acl; + void *sid; + + present = -1; + defaulted = -1; + acl = (void *)0xdeadbeef; + SetLastError(0xdeadbeef); + ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted); + ok(ret, "GetSecurityDescriptorDacl error %d\n", GetLastError()); +todo_wine + ok(present == 1, "acl is not present\n"); +todo_wine + ok(acl != (void *)0xdeadbeef && acl != NULL, "acl pointer is not set\n"); + ok(defaulted == 0, "defaulted is set to TRUE\n"); + + defaulted = -1; + sid = (void *)0xdeadbeef; + SetLastError(0xdeadbeef); + ret = GetSecurityDescriptorOwner(sd, &sid, &defaulted); + ok(ret, "GetSecurityDescriptorOwner error %d\n", GetLastError()); +todo_wine + ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n"); + ok(defaulted == 0, "defaulted is set to TRUE\n"); + + defaulted = -1; + sid = (void *)0xdeadbeef; + SetLastError(0xdeadbeef); + ret = GetSecurityDescriptorGroup(sd, &sid, &defaulted); + ok(ret, "GetSecurityDescriptorGroup error %d\n", GetLastError()); +todo_wine + ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n"); + ok(defaulted == 0, "defaulted is set to TRUE\n"); +} + +static void test_default_handle_security(HANDLE token, HANDLE handle, GENERIC_MAPPING *mapping) +{ + DWORD ret, length, needed, granted, priv_set_len; + BOOL status; + PRIVILEGE_SET priv_set; + SECURITY_DESCRIPTOR *sd; + + needed = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, + NULL, 0, &needed); + ok(!ret, "GetKernelObjectSecurity should fail\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + ok(needed != 0xdeadbeef, "GetKernelObjectSecurity should return required buffer length\n"); + + length = needed; + sd = HeapAlloc(GetProcessHeap(), 0, length); + + needed = 0; + SetLastError(0xdeadbeef); + ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, + sd, length, &needed); + ok(ret, "GetKernelObjectSecurity error %d\n", GetLastError()); + ok(needed == length, "GetKernelObjectSecurity should return required buffer length\n"); + + validate_default_security_descriptor(sd); + + priv_set_len = sizeof(priv_set); + granted = 0xdeadbeef; + status = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = AccessCheck(sd, token, MAXIMUM_ALLOWED, mapping, &priv_set, &priv_set_len, &granted, &status); +todo_wine { + ok(ret, "AccessCheck error %d\n", GetLastError()); + ok(status == 1, "expected 1, got %d\n", status); + ok(granted == mapping->GenericAll, "expected %#x, got %#x\n", mapping->GenericAll, granted); +} + HeapFree(GetProcessHeap(), 0, sd); +} + +static void test_mutex_security(HANDLE token) +{ + HANDLE mutex; + GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ, STANDARD_RIGHTS_WRITE, + STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, + STANDARD_RIGHTS_ALL | MUTEX_ALL_ACCESS }; + + SetLastError(0xdeadbeef); + mutex = OpenMutex(0, FALSE, "WineTestMutex"); + ok(!mutex, "mutex should not exist\n"); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + mutex = CreateMutex(NULL, FALSE, "WineTestMutex"); + ok(mutex != 0, "CreateMutex error %d\n", GetLastError()); + + test_default_handle_security(token, mutex, &mapping); + + CloseHandle (mutex); +} + +static BOOL validate_impersonation_token(HANDLE token, DWORD *token_type) +{ + DWORD ret, needed; + TOKEN_TYPE type; + SECURITY_IMPERSONATION_LEVEL sil; + + type = 0xdeadbeef; + needed = 0; + SetLastError(0xdeadbeef); + ret = GetTokenInformation(token, TokenType, &type, sizeof(type), &needed); + ok(ret, "GetTokenInformation error %d\n", GetLastError()); + ok(needed == sizeof(type), "GetTokenInformation should return required buffer length\n"); + ok(type == TokenPrimary || type == TokenImpersonation, "expected TokenPrimary or TokenImpersonation, got %d\n", type); + + *token_type = type; + if (type != TokenImpersonation) return FALSE; + + needed = 0; + SetLastError(0xdeadbeef); + ret = GetTokenInformation(token, TokenImpersonationLevel, &sil, sizeof(sil), &needed); + ok(ret, "GetTokenInformation error %d\n", GetLastError()); + ok(needed == sizeof(sil), "GetTokenInformation should return required buffer length\n"); + ok(sil == SecurityImpersonation, "expected SecurityImpersonation, got %d\n", sil); + + needed = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = GetTokenInformation(token, TokenDefaultDacl, NULL, 0, &needed); + ok(!ret, "GetTokenInformation should fail\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n"); + ok(needed > sizeof(TOKEN_DEFAULT_DACL), "GetTokenInformation returned empty default DACL\n"); + + needed = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = GetTokenInformation(token, TokenOwner, NULL, 0, &needed); + ok(!ret, "GetTokenInformation should fail\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n"); + ok(needed > sizeof(TOKEN_OWNER), "GetTokenInformation returned empty token owner\n"); + + needed = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &needed); + ok(!ret, "GetTokenInformation should fail\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n"); + ok(needed > sizeof(TOKEN_PRIMARY_GROUP), "GetTokenInformation returned empty token primary group\n"); + + return TRUE; +} + +static void test_kernel_objects_security(void) +{ + HANDLE token, process_token; + DWORD ret, token_type; + + ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &process_token); + ok(ret, "OpenProcessToken error %d\n", GetLastError()); + + ret = validate_impersonation_token(process_token, &token_type); + ok(token_type == TokenPrimary, "expected TokenPrimary, got %d\n", token_type); + ok(!ret, "access token should not be an impersonation token\n"); + + ret = DuplicateToken(process_token, SecurityImpersonation, &token); + ok(ret, "DuplicateToken error %d\n", GetLastError()); + + ret = validate_impersonation_token(token, &token_type); + ok(ret, "access token should be a valid impersonation token\n"); + ok(token_type == TokenImpersonation, "expected TokenImpersonation, got %d\n", token_type); + + test_mutex_security(token); + /* FIXME: test other kernel object types */ + + CloseHandle(process_token); + CloseHandle(token); +} + START_TEST(security) { init(); @@ -3993,6 +4168,7 @@ START_TEST(security) test_process_security_child(); return; } + test_kernel_objects_security(); test_sid(); test_trustee(); test_luid(); -- 2.11.4.GIT