Signed-off-by: Hans Leidekker hans@codeweavers.com --- dlls/ntdll/tests/om.c | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+)
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index 43c5ee46d7..819abdb7cd 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,204 @@ 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 */ + ok( token_default_dacl != NULL, "NULL token_default_dacl\n" ); + ok( token_default_dacl->DefaultDacl != NULL, "NULL token_default_dacl->DefaultDacl\n" ); + 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 +2242,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 +2265,5 @@ START_TEST(om) test_mutant(); test_keyed_events(); test_null_device(); + test_token(); }