Rob Shearman : advapi32: Add tests for token impersonation levels and what operations are allowed at each level .

Alexandre Julliard julliard at wine.codeweavers.com
Thu Feb 15 12:52:28 CST 2007


Module: wine
Branch: master
Commit: 795b40187e269f9858861be229da3af02e3dc799
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=795b40187e269f9858861be229da3af02e3dc799

Author: Rob Shearman <rob at codeweavers.com>
Date:   Thu Feb 15 16:25:58 2007 +0000

advapi32: Add tests for token impersonation levels and what operations are allowed at each level.

---

 dlls/advapi32/tests/security.c |  104 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 104 insertions(+), 0 deletions(-)

diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 58516d7..11863ed 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -1556,6 +1556,109 @@ static void test_process_security_child(void)
     CloseHandle( handle );
 }
 
+static void test_impersonation_level(void)
+{
+    HANDLE Token, ProcessToken;
+    HANDLE Token2;
+    DWORD Size;
+    TOKEN_PRIVILEGES *Privileges;
+    TOKEN_USER *User;
+    PRIVILEGE_SET *PrivilegeSet;
+    BOOL AccessGranted;
+    BOOL ret;
+    HKEY hkey;
+    DWORD error;
+
+    ret = ImpersonateSelf(SecurityAnonymous);
+    ok(ret, "ImpersonateSelf(SecurityAnonymous) failed with error %d\n", GetLastError());
+    ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token);
+    todo_wine {
+    ok(!ret, "OpenThreadToken should have failed\n");
+    error = GetLastError();
+    ok(error == ERROR_CANT_OPEN_ANONYMOUS, "OpenThreadToken on anonymous token should have returned ERROR_CANT_OPEN_ANONYMOUS instead of %d\n", error);
+    /* can't perform access check when opening object against an anonymous impersonation token */
+    error = RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
+    ok(error == ERROR_INVALID_HANDLE, "RegOpenKeyEx should have failed with ERROR_INVALID_HANDLE instead of %d\n", error);
+    }
+    RevertToSelf();
+
+    ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &ProcessToken);
+    ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
+
+    ret = DuplicateTokenEx(ProcessToken,
+        TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, NULL,
+        SecurityAnonymous, TokenImpersonation, &Token);
+    ok(ret, "DuplicateTokenEx failed with error %d\n", GetLastError());
+    /* can't increase the impersonation level */
+    ret = DuplicateToken(Token, SecurityIdentification, &Token2);
+    error = GetLastError();
+    todo_wine {
+    ok(!ret && error == ERROR_BAD_IMPERSONATION_LEVEL,
+        "Duplicating a token and increasing the impersonation level should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %d\n", error);
+    }
+    /* we can query anything from an anonymous token, including the user */
+    ret = GetTokenInformation(Token, TokenUser, NULL, 0, &Size);
+    error = GetLastError();
+    ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenUser) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d\n", error);
+    User = (TOKEN_USER *)HeapAlloc(GetProcessHeap(), 0, Size);
+    ret = GetTokenInformation(Token, TokenUser, User, Size, &Size);
+    ok(ret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
+    HeapFree(GetProcessHeap(), 0, User);
+
+    /* PrivilegeCheck fails with SecurityAnonymous level */
+    ret = GetTokenInformation(Token, TokenPrivileges, NULL, 0, &Size);
+    error = GetLastError();
+    ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenPrivileges) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d\n", error);
+    Privileges = (TOKEN_PRIVILEGES *)HeapAlloc(GetProcessHeap(), 0, Size);
+    ret = GetTokenInformation(Token, TokenPrivileges, Privileges, Size, &Size);
+    ok(ret, "GetTokenInformation(TokenPrivileges) failed with error %d\n", GetLastError());
+
+    PrivilegeSet = (PRIVILEGE_SET *)HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(PRIVILEGE_SET, Privilege[Privileges->PrivilegeCount]));
+    PrivilegeSet->PrivilegeCount = Privileges->PrivilegeCount;
+    memcpy(PrivilegeSet->Privilege, Privileges->Privileges, PrivilegeSet->PrivilegeCount * sizeof(PrivilegeSet->Privilege[0]));
+    PrivilegeSet->Control = PRIVILEGE_SET_ALL_NECESSARY;
+    HeapFree(GetProcessHeap(), 0, Privileges);
+
+    ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
+    error = GetLastError();
+    todo_wine {
+    ok(!ret && error == ERROR_BAD_IMPERSONATION_LEVEL, "PrivilegeCheck for SecurityAnonymous token should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %d\n", error);
+    }
+
+    CloseHandle(Token);
+
+    ret = ImpersonateSelf(SecurityIdentification);
+    ok(ret, "ImpersonateSelf(SecurityIdentification) failed with error %d\n", GetLastError());
+    ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token);
+    ok(ret, "OpenThreadToken failed with error %d\n", GetLastError());
+
+    /* can't perform access check when opening object against an identification impersonation token */
+    error = RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
+    todo_wine {
+    ok(error == ERROR_INVALID_HANDLE, "RegOpenKeyEx should have failed with ERROR_INVALID_HANDLE instead of %d\n", error);
+    }
+    ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
+    ok(ret, "PrivilegeCheck for SecurityIdentification failed with error %d\n", GetLastError());
+    CloseHandle(Token);
+    RevertToSelf();
+
+    ret = ImpersonateSelf(SecurityImpersonation);
+    ok(ret, "ImpersonateSelf(SecurityImpersonation) failed with error %d\n", GetLastError());
+    ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token);
+    ok(ret, "OpenThreadToken failed with error %d\n", GetLastError());
+    error = RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
+    ok(error == ERROR_SUCCESS, "RegOpenKeyEx should have succeeded instead of failing with %d\n", error);
+    RegCloseKey(hkey);
+    ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
+    ok(ret, "PrivilegeCheck for SecurityImpersonation failed with error %d\n", GetLastError());
+    RevertToSelf();
+
+    CloseHandle(Token);
+    CloseHandle(ProcessToken);
+
+    HeapFree(GetProcessHeap(), 0, PrivilegeSet);
+}
+
 START_TEST(security)
 {
     init();
@@ -1575,4 +1678,5 @@ START_TEST(security)
     test_LookupAccountSid();
     test_LookupAccountName();
     test_process_security();
+    test_impersonation_level();
 }




More information about the wine-cvs mailing list