mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
[ADVAPI32_WINETEST] Sync with Wine Staging 1.7.43.
svn path=/trunk/; revision=67915
This commit is contained in:
parent
3e2082bafa
commit
a91416131e
3 changed files with 702 additions and 166 deletions
|
@ -22,5 +22,5 @@ if(NOT MSVC)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set_module_type(advapi32_winetest win32cui)
|
set_module_type(advapi32_winetest win32cui)
|
||||||
add_importlibs(advapi32_winetest advapi32 ole32 msvcrt kernel32)
|
add_importlibs(advapi32_winetest advapi32 ole32 msvcrt kernel32 ntdll)
|
||||||
add_cd_file(TARGET advapi32_winetest DESTINATION reactos/bin FOR all)
|
add_cd_file(TARGET advapi32_winetest DESTINATION reactos/bin FOR all)
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "winerror.h"
|
#include "winerror.h"
|
||||||
|
#include "wine/winternl.h"
|
||||||
#include "aclapi.h"
|
#include "aclapi.h"
|
||||||
#include "winnt.h"
|
#include "winnt.h"
|
||||||
#include "sddl.h"
|
#include "sddl.h"
|
||||||
|
@ -62,29 +63,6 @@
|
||||||
#define THREAD_ALL_ACCESS_NT4 (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff)
|
#define THREAD_ALL_ACCESS_NT4 (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff)
|
||||||
#define THREAD_ALL_ACCESS_VISTA (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xffff)
|
#define THREAD_ALL_ACCESS_VISTA (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xffff)
|
||||||
|
|
||||||
/* copied from Wine winternl.h - not included in the Windows SDK */
|
|
||||||
typedef enum _OBJECT_INFORMATION_CLASS {
|
|
||||||
ObjectBasicInformation,
|
|
||||||
ObjectNameInformation,
|
|
||||||
ObjectTypeInformation,
|
|
||||||
ObjectAllInformation,
|
|
||||||
ObjectDataInformation
|
|
||||||
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
|
|
||||||
|
|
||||||
typedef struct _OBJECT_BASIC_INFORMATION {
|
|
||||||
ULONG Attributes;
|
|
||||||
ACCESS_MASK GrantedAccess;
|
|
||||||
ULONG HandleCount;
|
|
||||||
ULONG PointerCount;
|
|
||||||
ULONG PagedPoolUsage;
|
|
||||||
ULONG NonPagedPoolUsage;
|
|
||||||
ULONG Reserved[3];
|
|
||||||
ULONG NameInformationLength;
|
|
||||||
ULONG TypeInformationLength;
|
|
||||||
ULONG SecurityDescriptorLength;
|
|
||||||
LARGE_INTEGER CreateTime;
|
|
||||||
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;
|
|
||||||
|
|
||||||
#define expect_eq(expr, value, type, format) { type ret_ = expr; ok((value) == ret_, #expr " expected " format " got " format "\n", (value), (ret_)); }
|
#define expect_eq(expr, value, type, format) { type ret_ = expr; ok((value) == ret_, #expr " expected " format " got " format "\n", (value), (ret_)); }
|
||||||
|
|
||||||
static BOOL (WINAPI *pAddAccessAllowedAceEx)(PACL, DWORD, DWORD, DWORD, PSID);
|
static BOOL (WINAPI *pAddAccessAllowedAceEx)(PACL, DWORD, DWORD, DWORD, PSID);
|
||||||
|
@ -150,6 +128,10 @@ static BOOL (WINAPI *pCreateRestrictedToken)(HANDLE, DWORD, DWORD, PSID_AND_ATTR
|
||||||
PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
|
PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
|
||||||
static BOOL (WINAPI *pGetAclInformation)(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS);
|
static BOOL (WINAPI *pGetAclInformation)(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS);
|
||||||
static BOOL (WINAPI *pGetAce)(PACL,DWORD,LPVOID*);
|
static BOOL (WINAPI *pGetAce)(PACL,DWORD,LPVOID*);
|
||||||
|
static NTSTATUS (WINAPI *pNtSetSecurityObject)(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
|
||||||
|
static NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,PLARGE_INTEGER,ULONG,ULONG,ULONG,ULONG,PVOID,ULONG);
|
||||||
|
static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(LPCWSTR,PUNICODE_STRING,PWSTR*,CURDIR*);
|
||||||
|
static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING,PCANSI_STRING,BOOLEAN);
|
||||||
|
|
||||||
static HMODULE hmod;
|
static HMODULE hmod;
|
||||||
static int myARGC;
|
static int myARGC;
|
||||||
|
@ -176,6 +158,10 @@ static void init(void)
|
||||||
hntdll = GetModuleHandleA("ntdll.dll");
|
hntdll = GetModuleHandleA("ntdll.dll");
|
||||||
pNtQueryObject = (void *)GetProcAddress( hntdll, "NtQueryObject" );
|
pNtQueryObject = (void *)GetProcAddress( hntdll, "NtQueryObject" );
|
||||||
pNtAccessCheck = (void *)GetProcAddress( hntdll, "NtAccessCheck" );
|
pNtAccessCheck = (void *)GetProcAddress( hntdll, "NtAccessCheck" );
|
||||||
|
pNtSetSecurityObject = (void *)GetProcAddress(hntdll, "NtSetSecurityObject");
|
||||||
|
pNtCreateFile = (void *)GetProcAddress(hntdll, "NtCreateFile");
|
||||||
|
pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U");
|
||||||
|
pRtlAnsiStringToUnicodeString = (void *)GetProcAddress(hntdll, "RtlAnsiStringToUnicodeString");
|
||||||
|
|
||||||
hmod = GetModuleHandleA("advapi32.dll");
|
hmod = GetModuleHandleA("advapi32.dll");
|
||||||
pAddAccessAllowedAceEx = (void *)GetProcAddress(hmod, "AddAccessAllowedAceEx");
|
pAddAccessAllowedAceEx = (void *)GetProcAddress(hmod, "AddAccessAllowedAceEx");
|
||||||
|
@ -2531,19 +2517,21 @@ static void test_granted_access(HANDLE handle, ACCESS_MASK access,
|
||||||
static void test_process_security(void)
|
static void test_process_security(void)
|
||||||
{
|
{
|
||||||
BOOL res;
|
BOOL res;
|
||||||
|
PTOKEN_USER user;
|
||||||
PTOKEN_OWNER owner;
|
PTOKEN_OWNER owner;
|
||||||
PTOKEN_PRIMARY_GROUP group;
|
PTOKEN_PRIMARY_GROUP group;
|
||||||
PSID AdminSid = NULL, UsersSid = NULL;
|
PSID AdminSid = NULL, UsersSid = NULL, UserSid = NULL;
|
||||||
PACL Acl = NULL, ThreadAcl = NULL;
|
PACL Acl = NULL, ThreadAcl = NULL;
|
||||||
SECURITY_DESCRIPTOR *SecurityDescriptor = NULL, *ThreadSecurityDescriptor = NULL;
|
SECURITY_DESCRIPTOR *SecurityDescriptor = NULL, *ThreadSecurityDescriptor = NULL;
|
||||||
char buffer[MAX_PATH];
|
char buffer[MAX_PATH], account[MAX_PATH], domain[MAX_PATH];
|
||||||
PROCESS_INFORMATION info;
|
PROCESS_INFORMATION info;
|
||||||
STARTUPINFOA startup;
|
STARTUPINFOA startup;
|
||||||
SECURITY_ATTRIBUTES psa, tsa;
|
SECURITY_ATTRIBUTES psa, tsa;
|
||||||
HANDLE token, event;
|
HANDLE token, event;
|
||||||
DWORD size;
|
DWORD size, acc_size, dom_size, ret;
|
||||||
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
|
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
|
||||||
PSID EveryoneSid = NULL;
|
PSID EveryoneSid = NULL;
|
||||||
|
SID_NAME_USE use;
|
||||||
|
|
||||||
Acl = HeapAlloc(GetProcessHeap(), 0, 256);
|
Acl = HeapAlloc(GetProcessHeap(), 0, 256);
|
||||||
res = InitializeAcl(Acl, 256, ACL_REVISION);
|
res = InitializeAcl(Acl, 256, ACL_REVISION);
|
||||||
|
@ -2575,7 +2563,8 @@ static void test_process_security(void)
|
||||||
owner = HeapAlloc(GetProcessHeap(), 0, size);
|
owner = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
res = GetTokenInformation( token, TokenOwner, owner, size, &size );
|
res = GetTokenInformation( token, TokenOwner, owner, size, &size );
|
||||||
ok(res, "GetTokenInformation failed with error %d\n", GetLastError());
|
ok(res, "GetTokenInformation failed with error %d\n", GetLastError());
|
||||||
AdminSid = ((TOKEN_OWNER*)owner)->Owner;
|
AdminSid = owner->Owner;
|
||||||
|
test_sid_str(AdminSid);
|
||||||
|
|
||||||
res = GetTokenInformation( token, TokenPrimaryGroup, NULL, 0, &size );
|
res = GetTokenInformation( token, TokenPrimaryGroup, NULL, 0, &size );
|
||||||
ok(!res, "Expected failure, got %d\n", res);
|
ok(!res, "Expected failure, got %d\n", res);
|
||||||
|
@ -2585,13 +2574,34 @@ static void test_process_security(void)
|
||||||
group = HeapAlloc(GetProcessHeap(), 0, size);
|
group = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
res = GetTokenInformation( token, TokenPrimaryGroup, group, size, &size );
|
res = GetTokenInformation( token, TokenPrimaryGroup, group, size, &size );
|
||||||
ok(res, "GetTokenInformation failed with error %d\n", GetLastError());
|
ok(res, "GetTokenInformation failed with error %d\n", GetLastError());
|
||||||
UsersSid = ((TOKEN_PRIMARY_GROUP*)group)->PrimaryGroup;
|
UsersSid = group->PrimaryGroup;
|
||||||
|
test_sid_str(UsersSid);
|
||||||
|
|
||||||
|
acc_size = sizeof(account);
|
||||||
|
dom_size = sizeof(domain);
|
||||||
|
ret = LookupAccountSidA( NULL, UsersSid, account, &acc_size, domain, &dom_size, &use );
|
||||||
|
ok(ret, "LookupAccountSid failed with %d\n", ret);
|
||||||
|
ok(use == SidTypeGroup, "expect SidTypeGroup, got %d\n", use);
|
||||||
|
ok(!strcmp(account, "None"), "expect None, got %s\n", account);
|
||||||
|
|
||||||
|
res = GetTokenInformation( token, TokenUser, NULL, 0, &size );
|
||||||
|
ok(!res, "Expected failure, got %d\n", res);
|
||||||
|
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
|
||||||
|
"Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
|
||||||
|
|
||||||
|
user = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
|
res = GetTokenInformation( token, TokenUser, user, size, &size );
|
||||||
|
ok(res, "GetTokenInformation failed with error %d\n", GetLastError());
|
||||||
|
UserSid = user->User.Sid;
|
||||||
|
test_sid_str(UserSid);
|
||||||
|
ok(EqualPrefixSid(UsersSid, UserSid), "TokenPrimaryGroup Sid and TokenUser Sid don't match.\n");
|
||||||
|
|
||||||
CloseHandle( token );
|
CloseHandle( token );
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, group);
|
HeapFree(GetProcessHeap(), 0, group);
|
||||||
HeapFree(GetProcessHeap(), 0, owner);
|
HeapFree(GetProcessHeap(), 0, owner);
|
||||||
|
HeapFree(GetProcessHeap(), 0, user);
|
||||||
HeapFree(GetProcessHeap(), 0, Acl);
|
HeapFree(GetProcessHeap(), 0, Acl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2698,6 +2708,7 @@ static void test_process_security(void)
|
||||||
CloseHandle( event );
|
CloseHandle( event );
|
||||||
HeapFree(GetProcessHeap(), 0, group);
|
HeapFree(GetProcessHeap(), 0, group);
|
||||||
HeapFree(GetProcessHeap(), 0, owner);
|
HeapFree(GetProcessHeap(), 0, owner);
|
||||||
|
HeapFree(GetProcessHeap(), 0, user);
|
||||||
HeapFree(GetProcessHeap(), 0, Acl);
|
HeapFree(GetProcessHeap(), 0, Acl);
|
||||||
HeapFree(GetProcessHeap(), 0, SecurityDescriptor);
|
HeapFree(GetProcessHeap(), 0, SecurityDescriptor);
|
||||||
HeapFree(GetProcessHeap(), 0, ThreadAcl);
|
HeapFree(GetProcessHeap(), 0, ThreadAcl);
|
||||||
|
@ -3142,6 +3153,98 @@ static void test_SetEntriesInAclA(void)
|
||||||
HeapFree(GetProcessHeap(), 0, OldAcl);
|
HeapFree(GetProcessHeap(), 0, OldAcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* helper function for test_CreateDirectoryA */
|
||||||
|
static void get_nt_pathW(const char *name, UNICODE_STRING *nameW)
|
||||||
|
{
|
||||||
|
UNICODE_STRING strW;
|
||||||
|
ANSI_STRING str;
|
||||||
|
NTSTATUS status;
|
||||||
|
BOOLEAN ret;
|
||||||
|
RtlInitAnsiString(&str, name);
|
||||||
|
|
||||||
|
status = pRtlAnsiStringToUnicodeString(&strW, &str, TRUE);
|
||||||
|
ok(!status, "RtlAnsiStringToUnicodeString failed with %08x\n", status);
|
||||||
|
|
||||||
|
ret = pRtlDosPathNameToNtPathName_U(strW.Buffer, nameW, NULL, NULL);
|
||||||
|
ok(ret, "RtlDosPathNameToNtPathName_U failed\n");
|
||||||
|
|
||||||
|
RtlFreeUnicodeString(&strW);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD flags, DWORD mask,
|
||||||
|
BOOL todo_count, BOOL todo_sid, BOOL todo_flags, int line)
|
||||||
|
{
|
||||||
|
ACL_SIZE_INFORMATION acl_size;
|
||||||
|
ACCESS_ALLOWED_ACE *ace;
|
||||||
|
BOOL bret;
|
||||||
|
|
||||||
|
bret = pGetAclInformation(dacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||||
|
ok_(__FILE__, line)(bret, "GetAclInformation failed\n");
|
||||||
|
|
||||||
|
if (todo_count)
|
||||||
|
todo_wine
|
||||||
|
ok_(__FILE__, line)(acl_size.AceCount == 2,
|
||||||
|
"GetAclInformation returned unexpected entry count (%d != 2)\n",
|
||||||
|
acl_size.AceCount);
|
||||||
|
else
|
||||||
|
ok_(__FILE__, line)(acl_size.AceCount == 2,
|
||||||
|
"GetAclInformation returned unexpected entry count (%d != 2)\n",
|
||||||
|
acl_size.AceCount);
|
||||||
|
|
||||||
|
if (acl_size.AceCount > 0)
|
||||||
|
{
|
||||||
|
bret = pGetAce(dacl, 0, (VOID **)&ace);
|
||||||
|
ok_(__FILE__, line)(bret, "Failed to get Current User ACE\n");
|
||||||
|
|
||||||
|
bret = EqualSid(&ace->SidStart, user_sid);
|
||||||
|
if (todo_sid)
|
||||||
|
todo_wine
|
||||||
|
ok_(__FILE__, line)(bret, "Current User ACE != Current User SID\n");
|
||||||
|
else
|
||||||
|
ok_(__FILE__, line)(bret, "Current User ACE != Current User SID\n");
|
||||||
|
|
||||||
|
if (todo_flags)
|
||||||
|
todo_wine
|
||||||
|
ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
|
||||||
|
"Current User ACE has unexpected flags (0x%x != 0x%x)\n",
|
||||||
|
((ACE_HEADER *)ace)->AceFlags, flags);
|
||||||
|
else
|
||||||
|
ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
|
||||||
|
"Current User ACE has unexpected flags (0x%x != 0x%x)\n",
|
||||||
|
((ACE_HEADER *)ace)->AceFlags, flags);
|
||||||
|
|
||||||
|
ok_(__FILE__, line)(ace->Mask == mask,
|
||||||
|
"Current User ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||||
|
ace->Mask, mask);
|
||||||
|
}
|
||||||
|
if (acl_size.AceCount > 1)
|
||||||
|
{
|
||||||
|
bret = pGetAce(dacl, 1, (VOID **)&ace);
|
||||||
|
ok_(__FILE__, line)(bret, "Failed to get Administators Group ACE\n");
|
||||||
|
|
||||||
|
bret = EqualSid(&ace->SidStart, admin_sid);
|
||||||
|
if (todo_sid)
|
||||||
|
todo_wine
|
||||||
|
ok_(__FILE__, line)(bret, "Administators Group ACE != Administators Group SID\n");
|
||||||
|
else
|
||||||
|
ok_(__FILE__, line)(bret, "Administators Group ACE != Administators Group SID\n");
|
||||||
|
|
||||||
|
if (todo_flags)
|
||||||
|
todo_wine
|
||||||
|
ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
|
||||||
|
"Administators Group ACE has unexpected flags (0x%x != 0x%x)\n",
|
||||||
|
((ACE_HEADER *)ace)->AceFlags, flags);
|
||||||
|
else
|
||||||
|
ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
|
||||||
|
"Administators Group ACE has unexpected flags (0x%x != 0x%x)\n",
|
||||||
|
((ACE_HEADER *)ace)->AceFlags, flags);
|
||||||
|
|
||||||
|
ok_(__FILE__, line)(ace->Mask == mask,
|
||||||
|
"Administators Group ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||||
|
ace->Mask, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void test_CreateDirectoryA(void)
|
static void test_CreateDirectoryA(void)
|
||||||
{
|
{
|
||||||
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], *user;
|
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], *user;
|
||||||
|
@ -3150,17 +3253,20 @@ static void test_CreateDirectoryA(void)
|
||||||
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
|
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
|
||||||
PSECURITY_DESCRIPTOR pSD = &sd;
|
PSECURITY_DESCRIPTOR pSD = &sd;
|
||||||
ACL_SIZE_INFORMATION acl_size;
|
ACL_SIZE_INFORMATION acl_size;
|
||||||
ACCESS_ALLOWED_ACE *ace;
|
UNICODE_STRING tmpfileW;
|
||||||
SECURITY_ATTRIBUTES sa;
|
SECURITY_ATTRIBUTES sa;
|
||||||
|
OBJECT_ATTRIBUTES attr;
|
||||||
char tmpfile[MAX_PATH];
|
char tmpfile[MAX_PATH];
|
||||||
char tmpdir[MAX_PATH];
|
char tmpdir[MAX_PATH];
|
||||||
HANDLE token, hTemp;
|
HANDLE token, hTemp;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
struct _SID *owner;
|
struct _SID *owner;
|
||||||
BOOL bret = TRUE;
|
BOOL bret = TRUE;
|
||||||
|
NTSTATUS status;
|
||||||
DWORD error;
|
DWORD error;
|
||||||
PACL pDacl;
|
PACL pDacl;
|
||||||
|
|
||||||
if (!pGetNamedSecurityInfoA || !pCreateWellKnownSid)
|
if (!pGetSecurityInfo || !pGetNamedSecurityInfoA || !pCreateWellKnownSid)
|
||||||
{
|
{
|
||||||
win_skip("Required functions are not available\n");
|
win_skip("Required functions are not available\n");
|
||||||
return;
|
return;
|
||||||
|
@ -3218,72 +3324,288 @@ static void test_CreateDirectoryA(void)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||||
|
test_inherited_dacl(pDacl, admin_sid, user_sid, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
|
||||||
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
|
||||||
ok(bret, "GetAclInformation failed\n");
|
|
||||||
ok(acl_size.AceCount == 2, "GetAclInformation returned unexpected entry count (%d != 2).\n",
|
|
||||||
acl_size.AceCount);
|
|
||||||
if (acl_size.AceCount > 0)
|
|
||||||
{
|
|
||||||
bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
|
||||||
ok(bret, "Failed to get Current User ACE.\n");
|
|
||||||
bret = EqualSid(&ace->SidStart, user_sid);
|
|
||||||
ok(bret, "Current User ACE != Current User SID.\n");
|
|
||||||
ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
|
|
||||||
"Current User ACE has unexpected flags (0x%x != 0x03)\n",
|
|
||||||
((ACE_HEADER *)ace)->AceFlags);
|
|
||||||
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
|
||||||
ace->Mask);
|
|
||||||
}
|
|
||||||
if (acl_size.AceCount > 1)
|
|
||||||
{
|
|
||||||
bret = pGetAce(pDacl, 1, (VOID **)&ace);
|
|
||||||
ok(bret, "Failed to get Administators Group ACE.\n");
|
|
||||||
bret = EqualSid(&ace->SidStart, admin_sid);
|
|
||||||
ok(bret, "Administators Group ACE != Administators Group SID.\n");
|
|
||||||
ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
|
|
||||||
"Administators Group ACE has unexpected flags (0x%x != 0x03)\n",
|
|
||||||
((ACE_HEADER *)ace)->AceFlags);
|
|
||||||
ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
|
||||||
ace->Mask);
|
|
||||||
}
|
|
||||||
LocalFree(pSD);
|
LocalFree(pSD);
|
||||||
|
|
||||||
/* Test inheritance of ACLs */
|
/* Test inheritance of ACLs in CreateFile without security descriptor */
|
||||||
strcpy(tmpfile, tmpdir);
|
strcpy(tmpfile, tmpdir);
|
||||||
lstrcatA(tmpfile, "/tmpfile");
|
lstrcatA(tmpfile, "/tmpfile");
|
||||||
hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW,
|
|
||||||
FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
|
||||||
|
CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
||||||
|
ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError());
|
||||||
|
|
||||||
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
|
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
|
||||||
OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, (PSID*)&owner,
|
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
NULL, &pDacl, NULL, &pSD);
|
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||||
ok(error == ERROR_SUCCESS, "Failed to get permissions on file.\n");
|
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
|
||||||
|
test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
|
||||||
|
0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
|
||||||
|
LocalFree(pSD);
|
||||||
|
CloseHandle(hTemp);
|
||||||
|
|
||||||
|
/* Test inheritance of ACLs in CreateFile with security descriptor -
|
||||||
|
* When a security descriptor is set, then inheritance doesn't take effect */
|
||||||
|
pSD = &sd;
|
||||||
|
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
||||||
|
pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
|
||||||
|
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
|
||||||
|
ok(bret, "Failed to initialize ACL\n");
|
||||||
|
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||||
|
ok(bret, "Failed to add ACL to security desciptor\n");
|
||||||
|
|
||||||
|
strcpy(tmpfile, tmpdir);
|
||||||
|
lstrcatA(tmpfile, "/tmpfile");
|
||||||
|
|
||||||
|
sa.nLength = sizeof(sa);
|
||||||
|
sa.lpSecurityDescriptor = pSD;
|
||||||
|
sa.bInheritHandle = TRUE;
|
||||||
|
hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, &sa,
|
||||||
|
CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
||||||
|
ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError());
|
||||||
|
HeapFree(GetProcessHeap(), 0, pDacl);
|
||||||
|
|
||||||
|
error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT,
|
||||||
|
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
|
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||||
|
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||||
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||||
ok(bret, "GetAclInformation failed\n");
|
ok(bret, "GetAclInformation failed\n");
|
||||||
ok(acl_size.AceCount == 2, "GetAclInformation returned unexpected entry count (%d != 2).\n",
|
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
|
||||||
acl_size.AceCount);
|
acl_size.AceCount);
|
||||||
if (acl_size.AceCount > 0)
|
LocalFree(pSD);
|
||||||
{
|
|
||||||
bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
|
||||||
ok(bret, "Inherited Failed to get Current User ACE.\n");
|
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
bret = EqualSid(&ace->SidStart, user_sid);
|
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||||
ok(bret, "Inherited Current User ACE != Current User SID.\n");
|
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||||
ok(((ACE_HEADER *)ace)->AceFlags == INHERITED_ACE,
|
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||||
"Inherited Current User ACE has unexpected flags (0x%x != 0x10)\n", ((ACE_HEADER *)ace)->AceFlags);
|
ok(bret, "GetAclInformation failed\n");
|
||||||
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
|
||||||
ace->Mask);
|
acl_size.AceCount);
|
||||||
}
|
LocalFree(pSD);
|
||||||
if (acl_size.AceCount > 1)
|
CloseHandle(hTemp);
|
||||||
{
|
|
||||||
bret = pGetAce(pDacl, 1, (VOID **)&ace);
|
/* Test inheritance of ACLs in NtCreateFile without security descriptor */
|
||||||
ok(bret, "Inherited Failed to get Administators Group ACE.\n");
|
strcpy(tmpfile, tmpdir);
|
||||||
bret = EqualSid(&ace->SidStart, admin_sid);
|
lstrcatA(tmpfile, "/tmpfile");
|
||||||
ok(bret, "Inherited Administators Group ACE != Administators Group SID.\n");
|
get_nt_pathW(tmpfile, &tmpfileW);
|
||||||
ok(((ACE_HEADER *)ace)->AceFlags == INHERITED_ACE,
|
|
||||||
"Inherited Administators Group ACE has unexpected flags (0x%x != 0x10)\n", ((ACE_HEADER *)ace)->AceFlags);
|
attr.Length = sizeof(attr);
|
||||||
ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
attr.RootDirectory = 0;
|
||||||
ace->Mask);
|
attr.ObjectName = &tmpfileW;
|
||||||
}
|
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||||
|
attr.SecurityDescriptor = NULL;
|
||||||
|
attr.SecurityQualityOfService = NULL;
|
||||||
|
|
||||||
|
status = pNtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL, 0,
|
||||||
|
FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0);
|
||||||
|
ok(!status, "NtCreateFile failed with %08x\n", status);
|
||||||
|
RtlFreeUnicodeString(&tmpfileW);
|
||||||
|
|
||||||
|
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
|
||||||
|
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
|
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||||
|
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
|
||||||
|
test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
|
||||||
|
0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
|
||||||
|
LocalFree(pSD);
|
||||||
|
CloseHandle(hTemp);
|
||||||
|
|
||||||
|
/* Test inheritance of ACLs in NtCreateFile with security descriptor -
|
||||||
|
* When a security descriptor is set, then inheritance doesn't take effect */
|
||||||
|
pSD = &sd;
|
||||||
|
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
||||||
|
pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
|
||||||
|
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
|
||||||
|
ok(bret, "Failed to initialize ACL\n");
|
||||||
|
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||||
|
ok(bret, "Failed to add ACL to security desciptor\n");
|
||||||
|
|
||||||
|
strcpy(tmpfile, tmpdir);
|
||||||
|
lstrcatA(tmpfile, "/tmpfile");
|
||||||
|
get_nt_pathW(tmpfile, &tmpfileW);
|
||||||
|
|
||||||
|
attr.Length = sizeof(attr);
|
||||||
|
attr.RootDirectory = 0;
|
||||||
|
attr.ObjectName = &tmpfileW;
|
||||||
|
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||||
|
attr.SecurityDescriptor = pSD;
|
||||||
|
attr.SecurityQualityOfService = NULL;
|
||||||
|
|
||||||
|
status = pNtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL, 0,
|
||||||
|
FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0);
|
||||||
|
ok(!status, "NtCreateFile failed with %08x\n", status);
|
||||||
|
RtlFreeUnicodeString(&tmpfileW);
|
||||||
|
HeapFree(GetProcessHeap(), 0, pDacl);
|
||||||
|
|
||||||
|
error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT,
|
||||||
|
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
|
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||||
|
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||||
|
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||||
|
ok(bret, "GetAclInformation failed\n");
|
||||||
|
todo_wine
|
||||||
|
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
|
||||||
|
acl_size.AceCount);
|
||||||
|
LocalFree(pSD);
|
||||||
|
|
||||||
|
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
|
||||||
|
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
|
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||||
|
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||||
|
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||||
|
ok(bret, "GetAclInformation failed\n");
|
||||||
|
todo_wine
|
||||||
|
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
|
||||||
|
acl_size.AceCount);
|
||||||
|
LocalFree(pSD);
|
||||||
|
CloseHandle(hTemp);
|
||||||
|
|
||||||
|
/* Test inheritance of ACLs in CreateDirectory without security descriptor */
|
||||||
|
strcpy(tmpfile, tmpdir);
|
||||||
|
lstrcatA(tmpfile, "/tmpdir");
|
||||||
|
bret = CreateDirectoryA(tmpfile, NULL);
|
||||||
|
ok(bret == TRUE, "CreateDirectoryA failed with error %u\n", GetLastError());
|
||||||
|
|
||||||
|
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
|
||||||
|
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
|
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||||
|
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
|
||||||
|
test_inherited_dacl(pDacl, admin_sid, user_sid,
|
||||||
|
OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE,
|
||||||
|
0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
|
||||||
|
LocalFree(pSD);
|
||||||
|
bret = RemoveDirectoryA(tmpfile);
|
||||||
|
ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n", GetLastError());
|
||||||
|
|
||||||
|
/* Test inheritance of ACLs in CreateDirectory with security descriptor */
|
||||||
|
pSD = &sd;
|
||||||
|
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
||||||
|
pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
|
||||||
|
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
|
||||||
|
ok(bret, "Failed to initialize ACL\n");
|
||||||
|
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||||
|
ok(bret, "Failed to add ACL to security desciptor\n");
|
||||||
|
|
||||||
|
strcpy(tmpfile, tmpdir);
|
||||||
|
lstrcatA(tmpfile, "/tmpdir1");
|
||||||
|
|
||||||
|
sa.nLength = sizeof(sa);
|
||||||
|
sa.lpSecurityDescriptor = pSD;
|
||||||
|
sa.bInheritHandle = TRUE;
|
||||||
|
bret = CreateDirectoryA(tmpfile, &sa);
|
||||||
|
ok(bret == TRUE, "CreateDirectoryA failed with error %u\n", GetLastError());
|
||||||
|
HeapFree(GetProcessHeap(), 0, pDacl);
|
||||||
|
|
||||||
|
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
|
||||||
|
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
|
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||||
|
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||||
|
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||||
|
ok(bret, "GetAclInformation failed\n");
|
||||||
|
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
|
||||||
|
acl_size.AceCount);
|
||||||
|
LocalFree(pSD);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
bret = RemoveDirectoryA(tmpfile);
|
||||||
|
error = GetLastError();
|
||||||
|
ok(bret == FALSE, "RemoveDirectoryA unexpected succeeded\n");
|
||||||
|
ok(error == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %u\n", error);
|
||||||
|
|
||||||
|
pSD = &sd;
|
||||||
|
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
||||||
|
pDacl = HeapAlloc(GetProcessHeap(), 0, 100);
|
||||||
|
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
|
||||||
|
ok(bret, "Failed to initialize ACL.\n");
|
||||||
|
bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
|
||||||
|
ok(bret, "Failed to add Current User to ACL.\n");
|
||||||
|
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||||
|
ok(bret, "Failed to add ACL to security desciptor.\n");
|
||||||
|
error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
|
||||||
|
NULL, pDacl, NULL);
|
||||||
|
ok(error == ERROR_SUCCESS, "SetNamedSecurityInfoA failed with error %u\n", error);
|
||||||
|
HeapFree(GetProcessHeap(), 0, pDacl);
|
||||||
|
|
||||||
|
bret = RemoveDirectoryA(tmpfile);
|
||||||
|
ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n", GetLastError());
|
||||||
|
|
||||||
|
/* Test inheritance of ACLs in NtCreateFile(..., FILE_DIRECTORY_FILE, ...) without security descriptor */
|
||||||
|
strcpy(tmpfile, tmpdir);
|
||||||
|
lstrcatA(tmpfile, "/tmpdir");
|
||||||
|
get_nt_pathW(tmpfile, &tmpfileW);
|
||||||
|
|
||||||
|
attr.Length = sizeof(attr);
|
||||||
|
attr.RootDirectory = 0;
|
||||||
|
attr.ObjectName = &tmpfileW;
|
||||||
|
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||||
|
attr.SecurityDescriptor = NULL;
|
||||||
|
attr.SecurityQualityOfService = NULL;
|
||||||
|
|
||||||
|
status = pNtCreateFile(&hTemp, GENERIC_READ | DELETE, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL,
|
||||||
|
FILE_SHARE_READ, FILE_CREATE, FILE_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, NULL, 0);
|
||||||
|
ok(!status, "NtCreateFile failed with %08x\n", status);
|
||||||
|
RtlFreeUnicodeString(&tmpfileW);
|
||||||
|
|
||||||
|
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
|
||||||
|
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
|
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||||
|
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
|
||||||
|
test_inherited_dacl(pDacl, admin_sid, user_sid,
|
||||||
|
OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE,
|
||||||
|
0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
|
||||||
|
LocalFree(pSD);
|
||||||
|
CloseHandle(hTemp);
|
||||||
|
|
||||||
|
/* Test inheritance of ACLs in NtCreateFile(..., FILE_DIRECTORY_FILE, ...) with security descriptor */
|
||||||
|
pSD = &sd;
|
||||||
|
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
||||||
|
pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
|
||||||
|
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
|
||||||
|
ok(bret, "Failed to initialize ACL\n");
|
||||||
|
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||||
|
ok(bret, "Failed to add ACL to security desciptor\n");
|
||||||
|
|
||||||
|
strcpy(tmpfile, tmpdir);
|
||||||
|
lstrcatA(tmpfile, "/tmpdir2");
|
||||||
|
get_nt_pathW(tmpfile, &tmpfileW);
|
||||||
|
|
||||||
|
attr.Length = sizeof(attr);
|
||||||
|
attr.RootDirectory = 0;
|
||||||
|
attr.ObjectName = &tmpfileW;
|
||||||
|
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||||
|
attr.SecurityDescriptor = pSD;
|
||||||
|
attr.SecurityQualityOfService = NULL;
|
||||||
|
|
||||||
|
status = pNtCreateFile(&hTemp, GENERIC_READ | DELETE, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL,
|
||||||
|
FILE_SHARE_READ, FILE_CREATE, FILE_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, NULL, 0);
|
||||||
|
ok(!status, "NtCreateFile failed with %08x\n", status);
|
||||||
|
RtlFreeUnicodeString(&tmpfileW);
|
||||||
|
HeapFree(GetProcessHeap(), 0, pDacl);
|
||||||
|
|
||||||
|
error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT,
|
||||||
|
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
|
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||||
|
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||||
|
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||||
|
ok(bret, "GetAclInformation failed\n");
|
||||||
|
todo_wine
|
||||||
|
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
|
||||||
|
acl_size.AceCount);
|
||||||
|
LocalFree(pSD);
|
||||||
|
|
||||||
|
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
|
||||||
|
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
|
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
|
||||||
|
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||||
|
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||||
|
ok(bret, "GetAclInformation failed\n");
|
||||||
|
todo_wine
|
||||||
|
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
|
||||||
|
acl_size.AceCount);
|
||||||
|
LocalFree(pSD);
|
||||||
CloseHandle(hTemp);
|
CloseHandle(hTemp);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -3303,7 +3625,7 @@ static void test_GetNamedSecurityInfoA(void)
|
||||||
char invalid_path[] = "/an invalid file path";
|
char invalid_path[] = "/an invalid file path";
|
||||||
int users_ace_id = -1, admins_ace_id = -1, i;
|
int users_ace_id = -1, admins_ace_id = -1, i;
|
||||||
char software_key[] = "MACHINE\\Software";
|
char software_key[] = "MACHINE\\Software";
|
||||||
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
|
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH+sizeof(void*)];
|
||||||
SECURITY_DESCRIPTOR_CONTROL control;
|
SECURITY_DESCRIPTOR_CONTROL control;
|
||||||
ACL_SIZE_INFORMATION acl_size;
|
ACL_SIZE_INFORMATION acl_size;
|
||||||
CHAR windows_dir[MAX_PATH];
|
CHAR windows_dir[MAX_PATH];
|
||||||
|
@ -3315,11 +3637,12 @@ static void test_GetNamedSecurityInfoA(void)
|
||||||
BOOL owner_defaulted;
|
BOOL owner_defaulted;
|
||||||
BOOL group_defaulted;
|
BOOL group_defaulted;
|
||||||
BOOL dacl_defaulted;
|
BOOL dacl_defaulted;
|
||||||
HANDLE token, hTemp;
|
HANDLE token, hTemp, h;
|
||||||
PSID owner, group;
|
PSID owner, group;
|
||||||
BOOL dacl_present;
|
BOOL dacl_present;
|
||||||
PACL pDacl;
|
PACL pDacl;
|
||||||
BYTE flags;
|
BYTE flags;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
if (!pSetNamedSecurityInfoA || !pGetNamedSecurityInfoA || !pCreateWellKnownSid)
|
if (!pSetNamedSecurityInfoA || !pGetNamedSecurityInfoA || !pCreateWellKnownSid)
|
||||||
{
|
{
|
||||||
|
@ -3424,8 +3747,8 @@ static void test_GetNamedSecurityInfoA(void)
|
||||||
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||||
ok(bret, "Failed to add ACL to security desciptor.\n");
|
ok(bret, "Failed to add ACL to security desciptor.\n");
|
||||||
GetTempFileNameA(".", "foo", 0, tmpfile);
|
GetTempFileNameA(".", "foo", 0, tmpfile);
|
||||||
hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
hTemp = CreateFileA(tmpfile, WRITE_DAC|GENERIC_WRITE, FILE_SHARE_DELETE|FILE_SHARE_READ,
|
||||||
FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
|
error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
|
||||||
NULL, pDacl, NULL);
|
NULL, pDacl, NULL);
|
||||||
|
@ -3460,8 +3783,8 @@ static void test_GetNamedSecurityInfoA(void)
|
||||||
ok(bret, "Current User ACE != Current User SID.\n");
|
ok(bret, "Current User ACE != Current User SID.\n");
|
||||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||||
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||||
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
ok(ace->Mask == 0x1f01ff,
|
||||||
ace->Mask);
|
"Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||||
}
|
}
|
||||||
if (acl_size.AceCount > 1)
|
if (acl_size.AceCount > 1)
|
||||||
{
|
{
|
||||||
|
@ -3475,47 +3798,18 @@ static void test_GetNamedSecurityInfoA(void)
|
||||||
"Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
"Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||||
}
|
}
|
||||||
LocalFree(pSD);
|
LocalFree(pSD);
|
||||||
CloseHandle(hTemp);
|
|
||||||
|
|
||||||
/* Create security descriptor with no inheritance and test that it comes back the same */
|
/* show that setting empty DACL is not removing all file permissions */
|
||||||
pSD = &sd;
|
pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
|
||||||
pDacl = HeapAlloc(GetProcessHeap(), 0, 100);
|
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
|
||||||
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
|
||||||
pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
|
|
||||||
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
|
|
||||||
ok(bret, "Failed to initialize ACL.\n");
|
ok(bret, "Failed to initialize ACL.\n");
|
||||||
bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
|
error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
||||||
ok(bret, "Failed to add Current User to ACL.\n");
|
NULL, NULL, pDacl, NULL);
|
||||||
bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid);
|
|
||||||
ok(bret, "Failed to add Administrator Group to ACL.\n");
|
|
||||||
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
|
||||||
ok(bret, "Failed to add ACL to security desciptor.\n");
|
|
||||||
GetTempFileNameA(".", "foo", 0, tmpfile);
|
|
||||||
hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
|
||||||
FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
|
||||||
SetLastError(0xdeadbeef);
|
|
||||||
error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
|
|
||||||
DACL_SECURITY_INFORMATION|PROTECTED_DACL_SECURITY_INFORMATION,
|
|
||||||
NULL, NULL, pDacl, NULL);
|
|
||||||
HeapFree(GetProcessHeap(), 0, pDacl);
|
|
||||||
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
|
|
||||||
{
|
|
||||||
win_skip("SetNamedSecurityInfoA is not implemented\n");
|
|
||||||
HeapFree(GetProcessHeap(), 0, user);
|
|
||||||
CloseHandle(hTemp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error);
|
ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error);
|
||||||
SetLastError(0xdeadbeef);
|
HeapFree(GetProcessHeap(), 0, pDacl);
|
||||||
|
|
||||||
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
||||||
NULL, NULL, &pDacl, NULL, &pSD);
|
NULL, NULL, &pDacl, NULL, &pSD);
|
||||||
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
|
|
||||||
{
|
|
||||||
win_skip("GetNamedSecurityInfoA is not implemented\n");
|
|
||||||
HeapFree(GetProcessHeap(), 0, user);
|
|
||||||
CloseHandle(hTemp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||||
|
|
||||||
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||||
|
@ -3523,26 +3817,100 @@ static void test_GetNamedSecurityInfoA(void)
|
||||||
if (acl_size.AceCount > 0)
|
if (acl_size.AceCount > 0)
|
||||||
{
|
{
|
||||||
bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
||||||
ok(bret, "Failed to get Current User ACE.\n");
|
ok(bret, "Failed to get ACE.\n");
|
||||||
bret = EqualSid(&ace->SidStart, user_sid);
|
ok(((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE,
|
||||||
ok(bret, "Current User ACE != Current User SID.\n");
|
"ACE has unexpected flags: 0x%x\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
|
||||||
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
|
||||||
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
|
||||||
ace->Mask);
|
|
||||||
}
|
|
||||||
if (acl_size.AceCount > 1)
|
|
||||||
{
|
|
||||||
bret = pGetAce(pDacl, 1, (VOID **)&ace);
|
|
||||||
ok(bret, "Failed to get Administators Group ACE.\n");
|
|
||||||
bret = EqualSid(&ace->SidStart, admin_sid);
|
|
||||||
ok(bret || broken(!bret) /* win2k */, "Administators Group ACE != Administators Group SID.\n");
|
|
||||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
|
||||||
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
|
||||||
ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
|
|
||||||
"Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
|
||||||
}
|
}
|
||||||
LocalFree(pSD);
|
LocalFree(pSD);
|
||||||
|
|
||||||
|
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||||
|
CloseHandle(h);
|
||||||
|
|
||||||
|
/* test setting NULL DACL */
|
||||||
|
error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
|
||||||
|
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL);
|
||||||
|
ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error);
|
||||||
|
|
||||||
|
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
||||||
|
NULL, NULL, &pDacl, NULL, &pSD);
|
||||||
|
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||||
|
todo_wine ok(!pDacl, "pDacl != NULL\n");
|
||||||
|
LocalFree(pSD);
|
||||||
|
|
||||||
|
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||||
|
CloseHandle(h);
|
||||||
|
|
||||||
|
/* NtSetSecurityObject doesn't inherit DACL entries */
|
||||||
|
pSD = sd+sizeof(void*)-((ULONG_PTR)sd)%sizeof(void*);
|
||||||
|
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
||||||
|
pDacl = HeapAlloc(GetProcessHeap(), 0, 100);
|
||||||
|
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
|
||||||
|
ok(bret, "Failed to initialize ACL.\n");
|
||||||
|
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||||
|
ok(bret, "Failed to add ACL to security desciptor.\n");
|
||||||
|
status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
|
||||||
|
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
|
||||||
|
|
||||||
|
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||||
|
CloseHandle(h);
|
||||||
|
|
||||||
|
pSetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ, SE_DACL_AUTO_INHERIT_REQ);
|
||||||
|
status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
|
||||||
|
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
|
||||||
|
|
||||||
|
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||||
|
CloseHandle(h);
|
||||||
|
|
||||||
|
pSetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED,
|
||||||
|
SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED);
|
||||||
|
status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
|
||||||
|
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
|
||||||
|
|
||||||
|
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||||
|
CloseHandle(h);
|
||||||
|
|
||||||
|
/* test if DACL is properly mapped to permission */
|
||||||
|
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
|
||||||
|
ok(bret, "Failed to initialize ACL.\n");
|
||||||
|
bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
|
||||||
|
ok(bret, "Failed to add Current User to ACL.\n");
|
||||||
|
bret = pAddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
|
||||||
|
ok(bret, "Failed to add Current User to ACL.\n");
|
||||||
|
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||||
|
ok(bret, "Failed to add ACL to security desciptor.\n");
|
||||||
|
status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
|
||||||
|
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
|
||||||
|
|
||||||
|
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||||
|
CloseHandle(h);
|
||||||
|
|
||||||
|
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
|
||||||
|
ok(bret, "Failed to initialize ACL.\n");
|
||||||
|
bret = pAddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
|
||||||
|
ok(bret, "Failed to add Current User to ACL.\n");
|
||||||
|
bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
|
||||||
|
ok(bret, "Failed to add Current User to ACL.\n");
|
||||||
|
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||||
|
ok(bret, "Failed to add ACL to security desciptor.\n");
|
||||||
|
status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
|
||||||
|
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
|
||||||
|
|
||||||
|
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||||
|
HeapFree(GetProcessHeap(), 0, pDacl);
|
||||||
HeapFree(GetProcessHeap(), 0, user);
|
HeapFree(GetProcessHeap(), 0, user);
|
||||||
CloseHandle(hTemp);
|
CloseHandle(hTemp);
|
||||||
|
|
||||||
|
@ -3728,6 +4096,13 @@ static void test_ConvertStringSecurityDescriptor(void)
|
||||||
Blank, SDDL_REVISION_1, &pSD, NULL);
|
Blank, SDDL_REVISION_1, &pSD, NULL);
|
||||||
ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError());
|
ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError());
|
||||||
LocalFree(pSD);
|
LocalFree(pSD);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
|
||||||
|
"D:P(A;;GRGW;;;BA)(A;;GRGW;;;S-1-5-21-0-0-0-1000)S:(ML;;NWNR;;;S-1-16-12288)", SDDL_REVISION_1, &pSD, NULL);
|
||||||
|
ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_DATATYPE) /* win2k */,
|
||||||
|
"ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %u\n", GetLastError());
|
||||||
|
if (ret) LocalFree(pSD);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_ConvertSecurityDescriptorToString(void)
|
static void test_ConvertSecurityDescriptorToString(void)
|
||||||
|
@ -4201,7 +4576,7 @@ static void test_GetSecurityInfo(void)
|
||||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||||
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||||
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
||||||
ace->Mask);
|
ace->Mask);
|
||||||
}
|
}
|
||||||
if (acl_size.AceCount > 1)
|
if (acl_size.AceCount > 1)
|
||||||
{
|
{
|
||||||
|
@ -4211,8 +4586,8 @@ static void test_GetSecurityInfo(void)
|
||||||
ok(bret, "Administators Group ACE != Administators Group SID.\n");
|
ok(bret, "Administators Group ACE != Administators Group SID.\n");
|
||||||
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
ok(((ACE_HEADER *)ace)->AceFlags == 0,
|
||||||
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
|
||||||
ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
|
ok(ace->Mask == 0x1f01ff,
|
||||||
ace->Mask);
|
"Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||||
}
|
}
|
||||||
LocalFree(pSD);
|
LocalFree(pSD);
|
||||||
CloseHandle(obj);
|
CloseHandle(obj);
|
||||||
|
@ -5695,6 +6070,51 @@ static void test_AdjustTokenPrivileges(void)
|
||||||
CloseHandle(token);
|
CloseHandle(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_AddAce(void)
|
||||||
|
{
|
||||||
|
static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
|
||||||
|
|
||||||
|
char acl_buf[1024], ace_buf[256];
|
||||||
|
ACCESS_ALLOWED_ACE *ace = (ACCESS_ALLOWED_ACE*)ace_buf;
|
||||||
|
PACL acl = (PACL)acl_buf;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
memset(ace, 0, sizeof(ace_buf));
|
||||||
|
ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
|
||||||
|
ace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD)+sizeof(SID);
|
||||||
|
memcpy(&ace->SidStart, &sidWorld, sizeof(sidWorld));
|
||||||
|
|
||||||
|
ret = InitializeAcl(acl, sizeof(acl_buf), ACL_REVISION2);
|
||||||
|
ok(ret, "InitializeAcl failed: %d\n", GetLastError());
|
||||||
|
|
||||||
|
ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
|
||||||
|
ok(ret, "AddAce failed: %d\n", GetLastError());
|
||||||
|
ret = AddAce(acl, ACL_REVISION2, MAXDWORD, ace, ace->Header.AceSize);
|
||||||
|
ok(ret, "AddAce failed: %d\n", GetLastError());
|
||||||
|
ret = AddAce(acl, ACL_REVISION3, MAXDWORD, ace, ace->Header.AceSize);
|
||||||
|
ok(ret, "AddAce failed: %d\n", GetLastError());
|
||||||
|
ok(acl->AclRevision == ACL_REVISION3, "acl->AclRevision = %d\n", acl->AclRevision);
|
||||||
|
ret = AddAce(acl, ACL_REVISION4, MAXDWORD, ace, ace->Header.AceSize);
|
||||||
|
ok(ret, "AddAce failed: %d\n", GetLastError());
|
||||||
|
ok(acl->AclRevision == ACL_REVISION4, "acl->AclRevision = %d\n", acl->AclRevision);
|
||||||
|
ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
|
||||||
|
ok(ret, "AddAce failed: %d\n", GetLastError());
|
||||||
|
ok(acl->AclRevision == ACL_REVISION4, "acl->AclRevision = %d\n", acl->AclRevision);
|
||||||
|
ret = AddAce(acl, ACL_REVISION2, MAXDWORD, ace, ace->Header.AceSize);
|
||||||
|
ok(ret, "AddAce failed: %d\n", GetLastError());
|
||||||
|
|
||||||
|
ret = AddAce(acl, MIN_ACL_REVISION-1, MAXDWORD, ace, ace->Header.AceSize);
|
||||||
|
ok(ret, "AddAce failed: %d\n", GetLastError());
|
||||||
|
/* next test succeededs but corrupts ACL */
|
||||||
|
ret = AddAce(acl, MAX_ACL_REVISION+1, MAXDWORD, ace, ace->Header.AceSize);
|
||||||
|
ok(ret, "AddAce failed: %d\n", GetLastError());
|
||||||
|
ok(acl->AclRevision == MAX_ACL_REVISION+1, "acl->AclRevision = %d\n", acl->AclRevision);
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
|
||||||
|
ok(!ret, "AddAce succeeded\n");
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError() = %d\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(security)
|
START_TEST(security)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
|
@ -5736,4 +6156,5 @@ START_TEST(security)
|
||||||
test_TokenIntegrityLevel();
|
test_TokenIntegrityLevel();
|
||||||
test_default_dacl_owner_sid();
|
test_default_dacl_owner_sid();
|
||||||
test_AdjustTokenPrivileges();
|
test_AdjustTokenPrivileges();
|
||||||
|
test_AddAce();
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ static BOOL (WINAPI *pQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE,
|
||||||
DWORD, LPDWORD);
|
DWORD, LPDWORD);
|
||||||
static BOOL (WINAPI *pQueryServiceObjectSecurity)(SC_HANDLE, SECURITY_INFORMATION,
|
static BOOL (WINAPI *pQueryServiceObjectSecurity)(SC_HANDLE, SECURITY_INFORMATION,
|
||||||
PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
|
PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
|
||||||
|
static DWORD (WINAPI *pNotifyServiceStatusChangeW)(SC_HANDLE,DWORD,SERVICE_NOTIFYW*);
|
||||||
|
|
||||||
static void init_function_pointers(void)
|
static void init_function_pointers(void)
|
||||||
{
|
{
|
||||||
|
@ -66,6 +67,7 @@ static void init_function_pointers(void)
|
||||||
pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2W");
|
pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2W");
|
||||||
pQueryServiceStatusEx= (void*)GetProcAddress(hadvapi32, "QueryServiceStatusEx");
|
pQueryServiceStatusEx= (void*)GetProcAddress(hadvapi32, "QueryServiceStatusEx");
|
||||||
pQueryServiceObjectSecurity = (void*)GetProcAddress(hadvapi32, "QueryServiceObjectSecurity");
|
pQueryServiceObjectSecurity = (void*)GetProcAddress(hadvapi32, "QueryServiceObjectSecurity");
|
||||||
|
pNotifyServiceStatusChangeW = (void*)GetProcAddress(hadvapi32, "NotifyServiceStatusChangeW");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_open_scm(void)
|
static void test_open_scm(void)
|
||||||
|
@ -2201,6 +2203,75 @@ static DWORD try_start_stop(SC_HANDLE svc_handle, const char* name, DWORD is_nt4
|
||||||
return le1;
|
return le1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct notify_data {
|
||||||
|
SERVICE_NOTIFYW notify;
|
||||||
|
SC_HANDLE svc;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void CALLBACK cb_stopped(void *user)
|
||||||
|
{
|
||||||
|
struct notify_data *data = user;
|
||||||
|
BOOL br;
|
||||||
|
|
||||||
|
ok(data->notify.dwNotificationStatus == ERROR_SUCCESS,
|
||||||
|
"Got wrong notification status: %u\n", data->notify.dwNotificationStatus);
|
||||||
|
ok(data->notify.ServiceStatus.dwCurrentState == SERVICE_STOPPED,
|
||||||
|
"Got wrong service state: 0x%x\n", data->notify.ServiceStatus.dwCurrentState);
|
||||||
|
ok(data->notify.dwNotificationTriggered == SERVICE_NOTIFY_STOPPED,
|
||||||
|
"Got wrong notification triggered: 0x%x\n", data->notify.dwNotificationTriggered);
|
||||||
|
|
||||||
|
br = StartServiceA(data->svc, 0, NULL);
|
||||||
|
ok(br, "StartService failed: %u\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CALLBACK cb_running(void *user)
|
||||||
|
{
|
||||||
|
struct notify_data *data = user;
|
||||||
|
BOOL br;
|
||||||
|
SERVICE_STATUS status;
|
||||||
|
|
||||||
|
ok(data->notify.dwNotificationStatus == ERROR_SUCCESS,
|
||||||
|
"Got wrong notification status: %u\n", data->notify.dwNotificationStatus);
|
||||||
|
ok(data->notify.ServiceStatus.dwCurrentState == SERVICE_RUNNING,
|
||||||
|
"Got wrong service state: 0x%x\n", data->notify.ServiceStatus.dwCurrentState);
|
||||||
|
ok(data->notify.dwNotificationTriggered == SERVICE_NOTIFY_RUNNING,
|
||||||
|
"Got wrong notification triggered: 0x%x\n", data->notify.dwNotificationTriggered);
|
||||||
|
|
||||||
|
br = ControlService(data->svc, SERVICE_CONTROL_STOP, &status);
|
||||||
|
ok(br, "ControlService failed: %u\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_servicenotify(SC_HANDLE svc)
|
||||||
|
{
|
||||||
|
DWORD dr;
|
||||||
|
struct notify_data data;
|
||||||
|
|
||||||
|
if(!pNotifyServiceStatusChangeW){
|
||||||
|
win_skip("No NotifyServiceStatusChangeW\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&data.notify, 0, sizeof(data.notify));
|
||||||
|
data.notify.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE;
|
||||||
|
data.notify.pfnNotifyCallback = &cb_stopped;
|
||||||
|
data.notify.pContext = &data;
|
||||||
|
data.svc = svc;
|
||||||
|
|
||||||
|
dr = pNotifyServiceStatusChangeW(svc, SERVICE_NOTIFY_STOPPED | SERVICE_NOTIFY_RUNNING, &data.notify);
|
||||||
|
ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %u\n", dr);
|
||||||
|
|
||||||
|
dr = SleepEx(100, TRUE);
|
||||||
|
ok(dr == WAIT_IO_COMPLETION, "APC wasn't called\n");
|
||||||
|
|
||||||
|
data.notify.pfnNotifyCallback = &cb_running;
|
||||||
|
|
||||||
|
dr = pNotifyServiceStatusChangeW(svc, SERVICE_NOTIFY_STOPPED | SERVICE_NOTIFY_RUNNING, &data.notify);
|
||||||
|
ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %u\n", dr);
|
||||||
|
|
||||||
|
dr = SleepEx(100, TRUE);
|
||||||
|
ok(dr == WAIT_IO_COMPLETION, "APC wasn't called\n");
|
||||||
|
}
|
||||||
|
|
||||||
static void test_start_stop(void)
|
static void test_start_stop(void)
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
@ -2279,17 +2350,12 @@ static void test_start_stop(void)
|
||||||
le = try_start_stop(svc_handle, displayname, is_nt4);
|
le = try_start_stop(svc_handle, displayname, is_nt4);
|
||||||
ok(le == ERROR_SERVICE_REQUEST_TIMEOUT, "%d != ERROR_SERVICE_REQUEST_TIMEOUT\n", le);
|
ok(le == ERROR_SERVICE_REQUEST_TIMEOUT, "%d != ERROR_SERVICE_REQUEST_TIMEOUT\n", le);
|
||||||
|
|
||||||
/* And finally with a service that plays dead, forcing a timeout.
|
/* create a real service and test notifications */
|
||||||
* This time we will put no quotes. That should work too, even if there are
|
sprintf(cmd, "%s service serve", selfname);
|
||||||
* spaces in the path.
|
displayname = "Winetest Service";
|
||||||
*/
|
|
||||||
sprintf(cmd, "%s service sleep", selfname);
|
|
||||||
displayname = "Winetest Sleep Service";
|
|
||||||
ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, cmd, NULL, NULL, NULL, NULL, NULL, displayname);
|
ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, cmd, NULL, NULL, NULL, NULL, NULL, displayname);
|
||||||
ok(ret, "ChangeServiceConfig() failed le=%u\n", GetLastError());
|
ok(ret, "ChangeServiceConfig() failed le=%u\n", GetLastError());
|
||||||
|
test_servicenotify(svc_handle);
|
||||||
le = try_start_stop(svc_handle, displayname, is_nt4);
|
|
||||||
ok(le == ERROR_SERVICE_REQUEST_TIMEOUT, "%d != ERROR_SERVICE_REQUEST_TIMEOUT\n", le);
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (svc_handle)
|
if (svc_handle)
|
||||||
|
@ -2394,6 +2460,57 @@ static void test_refcount(void)
|
||||||
CloseServiceHandle(scm_handle);
|
CloseServiceHandle(scm_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD WINAPI ctrl_handler(DWORD ctl, DWORD type, void *data, void *user)
|
||||||
|
{
|
||||||
|
HANDLE evt = user;
|
||||||
|
|
||||||
|
switch(ctl){
|
||||||
|
case SERVICE_CONTROL_STOP:
|
||||||
|
SetEvent(evt);
|
||||||
|
break;
|
||||||
|
case SERVICE_CONTROL_INTERROGATE:
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WINAPI service_main(DWORD argc, char **argv)
|
||||||
|
{
|
||||||
|
SERVICE_STATUS_HANDLE st_handle;
|
||||||
|
SERVICE_STATUS st;
|
||||||
|
HANDLE evt = CreateEventW(0, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
st_handle = RegisterServiceCtrlHandlerExA("", &ctrl_handler, evt);
|
||||||
|
|
||||||
|
st.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
||||||
|
st.dwServiceSpecificExitCode = 0;
|
||||||
|
st.dwCurrentState = SERVICE_RUNNING;
|
||||||
|
st.dwWin32ExitCode = NO_ERROR;
|
||||||
|
st.dwWaitHint = 0;
|
||||||
|
st.dwControlsAccepted = SERVICE_ACCEPT_STOP;
|
||||||
|
st.dwCheckPoint = 0;
|
||||||
|
|
||||||
|
SetServiceStatus(st_handle, &st);
|
||||||
|
|
||||||
|
WaitForSingleObject(evt, 5000);
|
||||||
|
|
||||||
|
st.dwCurrentState = SERVICE_STOPPED;
|
||||||
|
|
||||||
|
SetServiceStatus(st_handle, &st);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void run_service(void)
|
||||||
|
{
|
||||||
|
char empty[] = {0};
|
||||||
|
SERVICE_TABLE_ENTRYA table[] = {
|
||||||
|
{empty, &service_main },
|
||||||
|
{0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
StartServiceCtrlDispatcherA(table);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(service)
|
START_TEST(service)
|
||||||
{
|
{
|
||||||
SC_HANDLE scm_handle;
|
SC_HANDLE scm_handle;
|
||||||
|
@ -2404,10 +2521,8 @@ START_TEST(service)
|
||||||
GetFullPathNameA(myARGV[0], sizeof(selfname), selfname, NULL);
|
GetFullPathNameA(myARGV[0], sizeof(selfname), selfname, NULL);
|
||||||
if (myARGC >= 3)
|
if (myARGC >= 3)
|
||||||
{
|
{
|
||||||
if (strcmp(myARGV[2], "sleep") == 0)
|
if (strcmp(myARGV[2], "serve") == 0)
|
||||||
/* Cause a service startup timeout */
|
run_service();
|
||||||
Sleep(90000);
|
|
||||||
/* then, or if myARGV[2] == "exit", just exit */
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue