[ADVAPI32_WINETEST] Sync with Wine Staging 1.7.43.

svn path=/trunk/; revision=67915
This commit is contained in:
Amine Khaldi 2015-05-25 18:46:12 +00:00
parent 3e2082bafa
commit a91416131e
3 changed files with 702 additions and 166 deletions

View file

@ -22,5 +22,5 @@ if(NOT MSVC)
endif()
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)

View file

@ -28,6 +28,7 @@
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wine/winternl.h"
#include "aclapi.h"
#include "winnt.h"
#include "sddl.h"
@ -62,29 +63,6 @@
#define THREAD_ALL_ACCESS_NT4 (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff)
#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_)); }
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);
static BOOL (WINAPI *pGetAclInformation)(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS);
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 int myARGC;
@ -176,6 +158,10 @@ static void init(void)
hntdll = GetModuleHandleA("ntdll.dll");
pNtQueryObject = (void *)GetProcAddress( hntdll, "NtQueryObject" );
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");
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)
{
BOOL res;
PTOKEN_USER user;
PTOKEN_OWNER owner;
PTOKEN_PRIMARY_GROUP group;
PSID AdminSid = NULL, UsersSid = NULL;
PSID AdminSid = NULL, UsersSid = NULL, UserSid = NULL;
PACL Acl = NULL, ThreadAcl = NULL;
SECURITY_DESCRIPTOR *SecurityDescriptor = NULL, *ThreadSecurityDescriptor = NULL;
char buffer[MAX_PATH];
char buffer[MAX_PATH], account[MAX_PATH], domain[MAX_PATH];
PROCESS_INFORMATION info;
STARTUPINFOA startup;
SECURITY_ATTRIBUTES psa, tsa;
HANDLE token, event;
DWORD size;
DWORD size, acc_size, dom_size, ret;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
PSID EveryoneSid = NULL;
SID_NAME_USE use;
Acl = HeapAlloc(GetProcessHeap(), 0, 256);
res = InitializeAcl(Acl, 256, ACL_REVISION);
@ -2575,7 +2563,8 @@ static void test_process_security(void)
owner = HeapAlloc(GetProcessHeap(), 0, size);
res = GetTokenInformation( token, TokenOwner, owner, size, &size );
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 );
ok(!res, "Expected failure, got %d\n", res);
@ -2585,13 +2574,34 @@ static void test_process_security(void)
group = HeapAlloc(GetProcessHeap(), 0, size);
res = GetTokenInformation( token, TokenPrimaryGroup, group, size, &size );
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 );
if (!res)
{
HeapFree(GetProcessHeap(), 0, group);
HeapFree(GetProcessHeap(), 0, owner);
HeapFree(GetProcessHeap(), 0, user);
HeapFree(GetProcessHeap(), 0, Acl);
return;
}
@ -2698,6 +2708,7 @@ static void test_process_security(void)
CloseHandle( event );
HeapFree(GetProcessHeap(), 0, group);
HeapFree(GetProcessHeap(), 0, owner);
HeapFree(GetProcessHeap(), 0, user);
HeapFree(GetProcessHeap(), 0, Acl);
HeapFree(GetProcessHeap(), 0, SecurityDescriptor);
HeapFree(GetProcessHeap(), 0, ThreadAcl);
@ -3142,6 +3153,98 @@ static void test_SetEntriesInAclA(void)
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)
{
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];
PSECURITY_DESCRIPTOR pSD = &sd;
ACL_SIZE_INFORMATION acl_size;
ACCESS_ALLOWED_ACE *ace;
UNICODE_STRING tmpfileW;
SECURITY_ATTRIBUTES sa;
OBJECT_ATTRIBUTES attr;
char tmpfile[MAX_PATH];
char tmpdir[MAX_PATH];
HANDLE token, hTemp;
IO_STATUS_BLOCK io;
struct _SID *owner;
BOOL bret = TRUE;
NTSTATUS status;
DWORD error;
PACL pDacl;
if (!pGetNamedSecurityInfoA || !pCreateWellKnownSid)
if (!pGetSecurityInfo || !pGetNamedSecurityInfoA || !pCreateWellKnownSid)
{
win_skip("Required functions are not available\n");
return;
@ -3218,72 +3324,288 @@ static void test_CreateDirectoryA(void)
goto done;
}
ok(!error, "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 == 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);
}
test_inherited_dacl(pDacl, admin_sid, user_sid, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
LocalFree(pSD);
/* Test inheritance of ACLs */
/* Test inheritance of ACLs in CreateFile without security descriptor */
strcpy(tmpfile, tmpdir);
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,
OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, (PSID*)&owner,
NULL, &pDacl, NULL, &pSD);
ok(error == ERROR_SUCCESS, "Failed to get permissions on file.\n");
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 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);
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);
if (acl_size.AceCount > 0)
{
bret = pGetAce(pDacl, 0, (VOID **)&ace);
ok(bret, "Inherited Failed to get Current User ACE.\n");
bret = EqualSid(&ace->SidStart, user_sid);
ok(bret, "Inherited Current User ACE != Current User SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == INHERITED_ACE,
"Inherited Current User ACE has unexpected flags (0x%x != 0x10)\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, "Inherited Failed to get Administators Group ACE.\n");
bret = EqualSid(&ace->SidStart, admin_sid);
ok(bret, "Inherited Administators Group ACE != Administators Group SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == INHERITED_ACE,
"Inherited Administators Group ACE has unexpected flags (0x%x != 0x10)\n", ((ACE_HEADER *)ace)->AceFlags);
ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
ace->Mask);
}
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");
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 NtCreateFile without security descriptor */
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 = 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);
done:
@ -3303,7 +3625,7 @@ static void test_GetNamedSecurityInfoA(void)
char invalid_path[] = "/an invalid file path";
int users_ace_id = -1, admins_ace_id = -1, i;
char software_key[] = "MACHINE\\Software";
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH+sizeof(void*)];
SECURITY_DESCRIPTOR_CONTROL control;
ACL_SIZE_INFORMATION acl_size;
CHAR windows_dir[MAX_PATH];
@ -3315,11 +3637,12 @@ static void test_GetNamedSecurityInfoA(void)
BOOL owner_defaulted;
BOOL group_defaulted;
BOOL dacl_defaulted;
HANDLE token, hTemp;
HANDLE token, hTemp, h;
PSID owner, group;
BOOL dacl_present;
PACL pDacl;
BYTE flags;
NTSTATUS status;
if (!pSetNamedSecurityInfoA || !pGetNamedSecurityInfoA || !pCreateWellKnownSid)
{
@ -3424,8 +3747,8 @@ static void test_GetNamedSecurityInfoA(void)
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);
hTemp = CreateFileA(tmpfile, WRITE_DAC|GENERIC_WRITE, FILE_SHARE_DELETE|FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
SetLastError(0xdeadbeef);
error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
NULL, pDacl, NULL);
@ -3460,8 +3783,8 @@ static void test_GetNamedSecurityInfoA(void)
ok(bret, "Current User ACE != Current User SID.\n");
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);
ok(ace->Mask == 0x1f01ff,
"Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
}
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);
}
LocalFree(pSD);
CloseHandle(hTemp);
/* Create security descriptor with no inheritance and test that it comes back the same */
pSD = &sd;
pDacl = HeapAlloc(GetProcessHeap(), 0, 100);
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
/* show that setting empty DACL is not removing all file permissions */
pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
bret = InitializeAcl(pDacl, sizeof(ACL), 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 = 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;
}
error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
NULL, NULL, pDacl, NULL);
ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error);
SetLastError(0xdeadbeef);
HeapFree(GetProcessHeap(), 0, pDacl);
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
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;
}
NULL, NULL, &pDacl, NULL, &pSD);
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
@ -3523,26 +3817,100 @@ static void test_GetNamedSecurityInfoA(void)
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 == 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);
ok(bret, "Failed to get ACE.\n");
ok(((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE,
"ACE has unexpected flags: 0x%x\n", ((ACE_HEADER *)ace)->AceFlags);
}
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);
CloseHandle(hTemp);
@ -3728,6 +4096,13 @@ static void test_ConvertStringSecurityDescriptor(void)
Blank, SDDL_REVISION_1, &pSD, NULL);
ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError());
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)
@ -4201,7 +4576,7 @@ static void test_GetSecurityInfo(void)
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);
ace->Mask);
}
if (acl_size.AceCount > 1)
{
@ -4211,8 +4586,8 @@ static void test_GetSecurityInfo(void)
ok(bret, "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, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
ace->Mask);
ok(ace->Mask == 0x1f01ff,
"Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
}
LocalFree(pSD);
CloseHandle(obj);
@ -5695,6 +6070,51 @@ static void test_AdjustTokenPrivileges(void)
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)
{
init();
@ -5736,4 +6156,5 @@ START_TEST(security)
test_TokenIntegrityLevel();
test_default_dacl_owner_sid();
test_AdjustTokenPrivileges();
test_AddAce();
}

View file

@ -53,6 +53,7 @@ static BOOL (WINAPI *pQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE,
DWORD, LPDWORD);
static BOOL (WINAPI *pQueryServiceObjectSecurity)(SC_HANDLE, SECURITY_INFORMATION,
PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
static DWORD (WINAPI *pNotifyServiceStatusChangeW)(SC_HANDLE,DWORD,SERVICE_NOTIFYW*);
static void init_function_pointers(void)
{
@ -66,6 +67,7 @@ static void init_function_pointers(void)
pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2W");
pQueryServiceStatusEx= (void*)GetProcAddress(hadvapi32, "QueryServiceStatusEx");
pQueryServiceObjectSecurity = (void*)GetProcAddress(hadvapi32, "QueryServiceObjectSecurity");
pNotifyServiceStatusChangeW = (void*)GetProcAddress(hadvapi32, "NotifyServiceStatusChangeW");
}
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;
}
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)
{
BOOL ret;
@ -2279,17 +2350,12 @@ static void test_start_stop(void)
le = try_start_stop(svc_handle, displayname, is_nt4);
ok(le == ERROR_SERVICE_REQUEST_TIMEOUT, "%d != ERROR_SERVICE_REQUEST_TIMEOUT\n", le);
/* And finally with a service that plays dead, forcing a timeout.
* This time we will put no quotes. That should work too, even if there are
* spaces in the path.
*/
sprintf(cmd, "%s service sleep", selfname);
displayname = "Winetest Sleep Service";
/* create a real service and test notifications */
sprintf(cmd, "%s service serve", selfname);
displayname = "Winetest Service";
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());
le = try_start_stop(svc_handle, displayname, is_nt4);
ok(le == ERROR_SERVICE_REQUEST_TIMEOUT, "%d != ERROR_SERVICE_REQUEST_TIMEOUT\n", le);
test_servicenotify(svc_handle);
cleanup:
if (svc_handle)
@ -2394,6 +2460,57 @@ static void test_refcount(void)
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)
{
SC_HANDLE scm_handle;
@ -2404,10 +2521,8 @@ START_TEST(service)
GetFullPathNameA(myARGV[0], sizeof(selfname), selfname, NULL);
if (myARGC >= 3)
{
if (strcmp(myARGV[2], "sleep") == 0)
/* Cause a service startup timeout */
Sleep(90000);
/* then, or if myARGV[2] == "exit", just exit */
if (strcmp(myARGV[2], "serve") == 0)
run_service();
return;
}