[PATCH v2 2/2] ntdll/tests: Add tests for NtCreateToken.

Hans Leidekker hans at codeweavers.com
Mon May 7 07:17:27 CDT 2018


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/ntdll/tests/om.c | 220 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 220 insertions(+)

diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c
index 43c5ee46d7..91007d4646 100644
--- a/dlls/ntdll/tests/om.c
+++ b/dlls/ntdll/tests/om.c
@@ -69,6 +69,19 @@ static NTSTATUS (WINAPI *pNtWaitForKeyedEvent)( HANDLE, const void *, BOOLEAN, c
 static NTSTATUS (WINAPI *pNtReleaseKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
 static NTSTATUS (WINAPI *pNtCreateIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG);
 static NTSTATUS (WINAPI *pNtOpenIoCompletion)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
+static NTSTATUS (WINAPI *pNtCreateToken)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, TOKEN_TYPE, PLUID, PLARGE_INTEGER,
+                                          PTOKEN_USER, PTOKEN_GROUPS, PTOKEN_PRIVILEGES, PTOKEN_OWNER,
+                                          PTOKEN_PRIMARY_GROUP, PTOKEN_DEFAULT_DACL, PTOKEN_SOURCE );
+static NTSTATUS (WINAPI *pNtOpenProcessToken)( HANDLE, DWORD, HANDLE * );
+static NTSTATUS (WINAPI *pNtQueryInformationToken)( HANDLE, TOKEN_INFORMATION_CLASS, PVOID, ULONG, PULONG );
+static NTSTATUS (WINAPI *pRtlAdjustPrivilege)( ULONG, BOOLEAN, BOOLEAN, PBOOLEAN );
+static NTSTATUS (WINAPI *pRtlAllocateAndInitializeSid)( PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD, DWORD, DWORD,
+                                                        DWORD, DWORD, DWORD, DWORD, PSID * );
+static NTSTATUS (WINAPI *pNtAllocateLocallyUniqueId)( PLUID );
+static PVOID    (WINAPI *pRtlAllocateHeap)( HANDLE, ULONG, SIZE_T );
+static BOOLEAN  (WINAPI *pRtlFreeHeap)( HANDLE, ULONG, PVOID );
+static BOOLEAN  (WINAPI *pRtlEqualSid)( PSID, PSID );
+static NTSTATUS (WINAPI *pRtlFreeSid)( PSID );
 
 #define KEYEDEVENT_WAIT       0x0001
 #define KEYEDEVENT_WAKE       0x0002
@@ -1979,6 +1992,202 @@ static void test_mutant(void)
     NtClose( mutant );
 }
 
+static void test_token(void)
+{
+    char buf[512];
+    NTSTATUS status;
+    HANDLE token;
+    OBJECT_ATTRIBUTES attrs;
+    LUID session;
+    LARGE_INTEGER expiration;
+    SID_IDENTIFIER_AUTHORITY authority = {{ 0, 1, 2, 3, 4, 5 }};
+    TOKEN_USER token_user, *token_user2;
+    TOKEN_GROUPS token_groups, *token_groups2;
+    TOKEN_PRIVILEGES token_privs, *token_privs2;
+    TOKEN_OWNER token_owner, *token_owner2;
+    TOKEN_PRIMARY_GROUP token_primary_group, *token_primary_group2;
+    TOKEN_SOURCE token_source, token_source2;
+    TOKEN_ORIGIN token_origin;
+    TOKEN_DEFAULT_DACL *token_default_dacl;
+    TOKEN_TYPE token_type;
+    BOOLEAN enabled;
+    ULONG len;
+
+    if (pRtlAdjustPrivilege( SE_CREATE_TOKEN_PRIVILEGE, TRUE, FALSE, &enabled ))
+    {
+        /* This privilege is not assigned by default. Use the policy editor to assign it
+           to the Administrators group and reboot. Then elevate and re-run the test. */
+        skip( "can't enable SeCreateTokenPrivilege\n" );
+        return;
+    }
+
+    status = pNtOpenProcessToken( NtCurrentProcess(), TOKEN_QUERY, &token );
+    ok( !status, "got %08x\n", status );
+    len = 0;
+    status = pNtQueryInformationToken( token, TokenDefaultDacl, NULL, 0, &len );
+    ok( status == STATUS_BUFFER_TOO_SMALL, "got %08x\n", status );
+    token_default_dacl = pRtlAllocateHeap( GetProcessHeap(), 0, len );
+    status = pNtQueryInformationToken( token, TokenDefaultDacl, token_default_dacl, len, &len );
+    ok( !status, "got %08x\n", status );
+    ok( token_default_dacl->DefaultDacl != NULL, "NULL DefaultDacl\n" );
+    status = pNtQueryInformationToken( token, TokenOrigin, &token_origin, sizeof(token_origin), &len );
+    todo_wine ok( !status, "got %08x\n", status );
+    pNtClose( token );
+
+    status = pRtlAllocateAndInitializeSid( &authority, 8, 1, 1, 1, 1, 1, 1, 1, 1, &token_user.User.Sid );
+    ok( !status, "got %08x\n", status );
+    status = pRtlAllocateAndInitializeSid( &authority, 8, 2, 2, 2, 2, 2, 2, 2, 2, &token_owner.Owner );
+    ok( !status, "got %08x\n", status );
+    status = pRtlAllocateAndInitializeSid( &authority, 8, 3, 3, 3, 3, 3, 3, 3, 3, &token_primary_group.PrimaryGroup );
+    ok( !status, "got %08x\n", status );
+    status = pRtlAllocateAndInitializeSid( &authority, 8, 3, 3, 3, 3, 3, 3, 3, 3, &token_groups.Groups[0].Sid );
+    ok( !status, "got %08x\n", status );
+
+    /* all arguments are required except default dacl */
+    status = pNtCreateToken( NULL, 0, NULL, 0, NULL, NULL, NULL,
+                             NULL, NULL, NULL, NULL, NULL, NULL );
+    ok( status == STATUS_ACCESS_VIOLATION, "got %08x\n", status );
+
+    status = pNtCreateToken( NULL, TOKEN_ALL_ACCESS, NULL, TokenPrimary, NULL, NULL, NULL,
+                             NULL, NULL, NULL, NULL, NULL, NULL );
+    ok( status == STATUS_ACCESS_VIOLATION, "got %08x\n", status );
+
+    status = pNtCreateToken( &token, TOKEN_ALL_ACCESS, NULL, TokenPrimary, NULL, NULL, NULL,
+                             NULL, NULL, NULL, NULL, NULL, NULL );
+    ok( status == STATUS_ACCESS_VIOLATION, "got %08x\n", status );
+
+    InitializeObjectAttributes( &attrs, NULL, 0, 0, NULL );
+    status = pNtCreateToken( &token, TOKEN_ALL_ACCESS, &attrs, TokenPrimary, NULL, NULL, NULL,
+                             NULL, NULL, NULL, NULL, NULL, NULL );
+    ok( status == STATUS_ACCESS_VIOLATION, "got %08x\n", status );
+
+    pNtAllocateLocallyUniqueId( &session );
+    status = pNtCreateToken( &token, TOKEN_ALL_ACCESS, &attrs, TokenPrimary, &session, NULL, NULL,
+                             NULL, NULL, NULL, NULL, NULL, NULL );
+    ok( status == STATUS_ACCESS_VIOLATION, "got %08x\n", status );
+
+    expiration.LowPart = 0;
+    expiration.HighPart = 0;
+    status = pNtCreateToken( &token, TOKEN_ALL_ACCESS, &attrs, TokenPrimary, &session, &expiration, NULL,
+                             NULL, NULL, NULL, NULL, NULL, NULL );
+    ok( status == STATUS_ACCESS_VIOLATION, "got %08x\n", status );
+
+    token_user.User.Attributes = 0;
+    status = pNtCreateToken( &token, TOKEN_ALL_ACCESS, &attrs, TokenPrimary, &session, &expiration, &token_user,
+                             NULL, NULL, NULL, NULL, NULL, NULL );
+    ok( status == STATUS_ACCESS_VIOLATION, "got %08x\n", status );
+
+    token_groups.GroupCount = 0;
+    status = pNtCreateToken( &token, TOKEN_ALL_ACCESS, &attrs, TokenPrimary, &session, &expiration, &token_user,
+                             &token_groups, NULL, NULL, NULL, NULL, NULL );
+    ok( status == STATUS_ACCESS_VIOLATION, "got %08x\n", status );
+
+    token_privs.PrivilegeCount = 1;
+    token_privs.Privileges[0].Luid.LowPart = SE_BACKUP_PRIVILEGE;
+    token_privs.Privileges[0].Luid.HighPart = 0;
+    token_privs.Privileges[0].Attributes = 0;
+    status = pNtCreateToken( &token, TOKEN_ALL_ACCESS, &attrs, TokenPrimary, &session, &expiration, &token_user,
+                             &token_groups, &token_privs, NULL, NULL, NULL, NULL );
+    ok( status == STATUS_ACCESS_VIOLATION, "got %08x\n", status );
+
+    status = pNtCreateToken( &token, TOKEN_ALL_ACCESS, &attrs, TokenPrimary, &session, &expiration, &token_user,
+                             &token_groups, &token_privs, &token_owner, NULL, NULL, NULL );
+    ok( status == STATUS_ACCESS_VIOLATION, "got %08x\n", status );
+
+    status = pNtCreateToken( &token, TOKEN_ALL_ACCESS, &attrs, TokenPrimary, &session, &expiration, &token_user,
+                             &token_groups, &token_privs, &token_owner, &token_primary_group, NULL, NULL );
+    ok( status == STATUS_ACCESS_VIOLATION, "got %08x\n", status );
+
+    memcpy( token_source.SourceName, "winetest", sizeof("winetest") - 1 );
+    token_source.SourceIdentifier.LowPart = 1;
+    token_source.SourceIdentifier.HighPart = 1;
+    status = pNtCreateToken( &token, TOKEN_ALL_ACCESS, &attrs, TokenPrimary, &session, &expiration, &token_user,
+                             &token_groups, &token_privs, &token_owner, &token_primary_group, NULL, &token_source );
+    ok( status == STATUS_INVALID_PRIMARY_GROUP, "got %08x\n", status );
+
+    token_groups.GroupCount = 1;
+    token_groups.Groups[0].Attributes = 0;
+    status = pNtCreateToken( &token, TOKEN_ALL_ACCESS, &attrs, TokenPrimary, &session, &expiration, &token_user,
+                             &token_groups, &token_privs, &token_owner, &token_primary_group, NULL, &token_source );
+    ok( status == STATUS_INVALID_OWNER, "got %08x\n", status );
+
+    pRtlFreeSid( token_owner.Owner );
+    /* same SID as user */
+    status = pRtlAllocateAndInitializeSid( &authority, 8, 1, 1, 1, 1, 1, 1, 1, 1, &token_owner.Owner );
+    ok( !status, "got %08x\n", status );
+    status = pNtCreateToken( &token, TOKEN_ALL_ACCESS, &attrs, TokenPrimary, &session, &expiration, &token_user,
+                             &token_groups, &token_privs, &token_owner, &token_primary_group, NULL, &token_source );
+    todo_wine ok( status == STATUS_NO_SUCH_LOGON_SESSION, "got %08x\n", status );
+    if (!status) pNtClose( token );
+
+    /* same logon session as current process token */
+    status = pNtCreateToken( &token, TOKEN_ALL_ACCESS, &attrs, TokenPrimary, &token_origin.OriginatingLogonSession,
+                             &expiration, &token_user, &token_groups, &token_privs, &token_owner, &token_primary_group,
+                             token_default_dacl, &token_source );
+    ok( !status, "got %08x\n", status );
+
+    /* check if token attributes were correctly set */
+    token_type = 0;
+    status = pNtQueryInformationToken( token, TokenType, &token_type, sizeof(token_type), &len );
+    ok( !status, "got %08x\n", status );
+    ok( token_type == TokenPrimary, "got %u\n", token_type );
+
+    memset( buf, 0, sizeof(buf) );
+    status = pNtQueryInformationToken( token, TokenUser, buf, sizeof(buf), &len );
+    ok( !status, "got %08x\n", status );
+    token_user2 = (TOKEN_USER *)buf;
+    ok( pRtlEqualSid( token_user.User.Sid, token_user2->User.Sid ), "user SIDs not equal\n" );
+    ok( token_user.User.Attributes == token_user2->User.Attributes, "user attributes not equal\n" );
+
+    memset( buf, 0, sizeof(buf) );
+    status = pNtQueryInformationToken( token, TokenGroups, buf, sizeof(buf), &len );
+    ok( !status, "got %08x\n", status );
+    token_groups2 = (TOKEN_GROUPS *)buf;
+    ok( token_groups.GroupCount == token_groups2->GroupCount, "group count not equal\n" );
+    ok( pRtlEqualSid( token_groups.Groups[0].Sid, token_groups2->Groups[0].Sid ), "group SIDs not equal\n" );
+    ok( token_groups.Groups[0].Attributes == token_groups2->Groups[0].Attributes,
+        "group attributes not equal\n" );
+
+    memset( buf, 0, sizeof(buf) );
+    status = pNtQueryInformationToken( token, TokenPrivileges, buf, sizeof(buf), &len );
+    ok( !status, "got %08x\n", status );
+    token_privs2 = (TOKEN_PRIVILEGES *)buf;
+    ok( token_privs.PrivilegeCount == token_privs2->PrivilegeCount, "privilege count not equal\n" );
+    ok( !memcmp( &token_privs.Privileges[0].Luid, &token_privs2->Privileges[0].Luid, sizeof(LUID) ),
+        "privilege LUIDS not equal\n" );
+    ok( token_privs.Privileges[0].Attributes == token_privs2->Privileges[0].Attributes,
+        "privilege attributes not equal\n" );
+
+    memset( buf, 0, sizeof(buf) );
+    status = pNtQueryInformationToken( token, TokenOwner, buf, sizeof(buf), &len );
+    ok( !status, "got %08x\n", status );
+    token_owner2 = (TOKEN_OWNER *)buf;
+    ok( pRtlEqualSid( token_owner.Owner, token_owner2->Owner ), "owner SIDs not equal\n" );
+
+    memset( buf, 0, sizeof(buf) );
+    status = pNtQueryInformationToken( token, TokenPrimaryGroup, buf, sizeof(buf), &len );
+    ok( !status, "got %08x\n", status );
+    token_primary_group2 = (TOKEN_PRIMARY_GROUP *)buf;
+    ok( pRtlEqualSid( token_primary_group.PrimaryGroup, token_primary_group2->PrimaryGroup ),
+        "primary group SIDs not equal\n" );
+
+    memset( &token_source2, 0, sizeof(token_source2) );
+    status = pNtQueryInformationToken( token, TokenSource, &token_source2, sizeof(token_source2), &len );
+    todo_wine ok( !status, "got %08x\n", status );
+    todo_wine ok( !memcmp( token_source.SourceName, token_source2.SourceName, sizeof(token_source.SourceName) ),
+        "source name not equal\n" );
+    todo_wine ok( !memcmp( &token_source.SourceIdentifier, &token_source2.SourceIdentifier,
+        sizeof(token_source.SourceIdentifier) ), "source identifier not equal\n" );
+
+    pRtlFreeSid( token_user.User.Sid );
+    pRtlFreeSid( token_owner.Owner );
+    pRtlFreeSid( token_primary_group.PrimaryGroup );
+    pRtlFreeSid( token_groups.Groups[0].Sid );
+    pNtClose( token );
+    pRtlAdjustPrivilege( SE_CREATE_TOKEN_PRIVILEGE, enabled, FALSE, &enabled );
+    pRtlFreeHeap( GetProcessHeap(), 0, token_default_dacl );
+}
+
 START_TEST(om)
 {
     HMODULE hntdll = GetModuleHandleA("ntdll.dll");
@@ -2031,6 +2240,16 @@ START_TEST(om)
     pNtReleaseKeyedEvent    =  (void *)GetProcAddress(hntdll, "NtReleaseKeyedEvent");
     pNtCreateIoCompletion   =  (void *)GetProcAddress(hntdll, "NtCreateIoCompletion");
     pNtOpenIoCompletion     =  (void *)GetProcAddress(hntdll, "NtOpenIoCompletion");
+    pNtCreateToken          =  (void *)GetProcAddress(hntdll, "NtCreateToken");
+    pNtOpenProcessToken     =  (void *)GetProcAddress(hntdll, "NtOpenProcessToken");
+    pNtQueryInformationToken = (void *)GetProcAddress(hntdll, "NtQueryInformationToken");
+    pRtlAdjustPrivilege     =  (void *)GetProcAddress(hntdll, "RtlAdjustPrivilege");
+    pRtlAllocateAndInitializeSid = (void *)GetProcAddress(hntdll, "RtlAllocateAndInitializeSid");
+    pNtAllocateLocallyUniqueId = (void *)GetProcAddress(hntdll, "NtAllocateLocallyUniqueId");
+    pRtlAllocateHeap        = (void *)GetProcAddress(hntdll, "RtlAllocateHeap");
+    pRtlFreeHeap            = (void *)GetProcAddress(hntdll, "RtlFreeHeap");
+    pRtlEqualSid            = (void *)GetProcAddress(hntdll, "RtlEqualSid");
+    pRtlFreeSid             = (void *)GetProcAddress(hntdll, "RtlFreeSid");
 
     test_case_sensitive();
     test_namespace_pipe();
@@ -2044,4 +2263,5 @@ START_TEST(om)
     test_mutant();
     test_keyed_events();
     test_null_device();
+    test_token();
 }
-- 
2.11.0




More information about the wine-devel mailing list