Signed-off-by: Hans Leidekker <hans(a)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