2007-03-06 11:59:18 +00:00
/*
* Unit tests for security functions
*
* Copyright ( c ) 2004 Mike McCormack
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
2008-05-09 17:35:45 +00:00
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2007-03-06 11:59:18 +00:00
*/
2008-05-09 17:35:45 +00:00
# include <stdarg.h>
2007-03-06 11:59:18 +00:00
# include <stdio.h>
2008-05-09 17:35:45 +00:00
# include "ntstatus.h"
# define WIN32_NO_STATUS
2007-03-06 11:59:18 +00:00
# include "windef.h"
# include "winbase.h"
# include "winerror.h"
# include "aclapi.h"
# include "winnt.h"
2008-05-09 17:35:45 +00:00
# include "sddl.h"
# include "ntsecapi.h"
# include "lmcons.h"
# include "wine/test.h"
/* 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)); }
2007-03-06 11:59:18 +00:00
2008-05-09 17:35:45 +00:00
static BOOL ( WINAPI * pAddAccessAllowedAceEx ) ( PACL , DWORD , DWORD , DWORD , PSID ) ;
static BOOL ( WINAPI * pAddAccessDeniedAceEx ) ( PACL , DWORD , DWORD , DWORD , PSID ) ;
static BOOL ( WINAPI * pAddAuditAccessAceEx ) ( PACL , DWORD , DWORD , DWORD , PSID , BOOL , BOOL ) ;
typedef VOID ( WINAPI * fnBuildTrusteeWithSidA ) ( PTRUSTEEA pTrustee , PSID pSid ) ;
typedef VOID ( WINAPI * fnBuildTrusteeWithNameA ) ( PTRUSTEEA pTrustee , LPSTR pName ) ;
typedef VOID ( WINAPI * fnBuildTrusteeWithObjectsAndNameA ) ( PTRUSTEEA pTrustee ,
POBJECTS_AND_NAME_A pObjName ,
SE_OBJECT_TYPE ObjectType ,
LPSTR ObjectTypeName ,
LPSTR InheritedObjectTypeName ,
LPSTR Name ) ;
typedef VOID ( WINAPI * fnBuildTrusteeWithObjectsAndSidA ) ( PTRUSTEEA pTrustee ,
POBJECTS_AND_SID pObjSid ,
GUID * pObjectGuid ,
GUID * pInheritedObjectGuid ,
PSID pSid ) ;
typedef LPSTR ( WINAPI * fnGetTrusteeNameA ) ( PTRUSTEEA pTrustee ) ;
typedef BOOL ( WINAPI * fnMakeSelfRelativeSD ) ( PSECURITY_DESCRIPTOR , PSECURITY_DESCRIPTOR , LPDWORD ) ;
2007-03-06 11:59:18 +00:00
typedef BOOL ( WINAPI * fnConvertSidToStringSidA ) ( PSID pSid , LPSTR * str ) ;
typedef BOOL ( WINAPI * fnConvertStringSidToSidA ) ( LPCSTR str , PSID pSid ) ;
2008-05-09 17:35:45 +00:00
static BOOL ( WINAPI * pConvertStringSecurityDescriptorToSecurityDescriptorA ) ( LPCSTR , DWORD ,
PSECURITY_DESCRIPTOR * , PULONG ) ;
2008-12-09 19:26:45 +00:00
static BOOL ( WINAPI * pConvertStringSecurityDescriptorToSecurityDescriptorW ) ( LPCWSTR , DWORD ,
PSECURITY_DESCRIPTOR * , PULONG ) ;
2008-05-09 17:35:45 +00:00
static BOOL ( WINAPI * pConvertSecurityDescriptorToStringSecurityDescriptorA ) ( PSECURITY_DESCRIPTOR , DWORD ,
SECURITY_INFORMATION , LPSTR * , PULONG ) ;
2007-03-06 11:59:18 +00:00
typedef BOOL ( WINAPI * fnGetFileSecurityA ) ( LPCSTR , SECURITY_INFORMATION ,
PSECURITY_DESCRIPTOR , DWORD , LPDWORD ) ;
2008-12-09 19:26:45 +00:00
typedef BOOL ( WINAPI * fnSetFileSecurityA ) ( LPCSTR , SECURITY_INFORMATION ,
PSECURITY_DESCRIPTOR ) ;
2008-05-09 17:35:45 +00:00
static DWORD ( WINAPI * pGetNamedSecurityInfoA ) ( LPSTR , SE_OBJECT_TYPE , SECURITY_INFORMATION ,
PSID * , PSID * , PACL * , PACL * ,
PSECURITY_DESCRIPTOR * ) ;
2009-10-18 14:57:22 +00:00
static PDWORD ( WINAPI * pGetSidSubAuthority ) ( PSID , DWORD ) ;
static PUCHAR ( WINAPI * pGetSidSubAuthorityCount ) ( PSID ) ;
static BOOL ( WINAPI * pIsValidSid ) ( PSID ) ;
2008-05-09 17:35:45 +00:00
typedef DWORD ( WINAPI * fnRtlAdjustPrivilege ) ( ULONG , BOOLEAN , BOOLEAN , PBOOLEAN ) ;
typedef BOOL ( WINAPI * fnCreateWellKnownSid ) ( WELL_KNOWN_SID_TYPE , PSID , PSID , DWORD * ) ;
typedef BOOL ( WINAPI * fnDuplicateTokenEx ) ( HANDLE , DWORD , LPSECURITY_ATTRIBUTES ,
SECURITY_IMPERSONATION_LEVEL , TOKEN_TYPE , PHANDLE ) ;
typedef NTSTATUS ( WINAPI * fnLsaQueryInformationPolicy ) ( LSA_HANDLE , POLICY_INFORMATION_CLASS , PVOID * ) ;
typedef NTSTATUS ( WINAPI * fnLsaClose ) ( LSA_HANDLE ) ;
typedef NTSTATUS ( WINAPI * fnLsaFreeMemory ) ( PVOID ) ;
typedef NTSTATUS ( WINAPI * fnLsaOpenPolicy ) ( PLSA_UNICODE_STRING , PLSA_OBJECT_ATTRIBUTES , ACCESS_MASK , PLSA_HANDLE ) ;
static NTSTATUS ( WINAPI * pNtQueryObject ) ( HANDLE , OBJECT_INFORMATION_CLASS , PVOID , ULONG , PULONG ) ;
static DWORD ( WINAPI * pSetEntriesInAclW ) ( ULONG , PEXPLICIT_ACCESSW , PACL , PACL * ) ;
static BOOL ( WINAPI * pSetSecurityDescriptorControl ) ( PSECURITY_DESCRIPTOR , SECURITY_DESCRIPTOR_CONTROL ,
SECURITY_DESCRIPTOR_CONTROL ) ;
2008-09-14 18:24:25 +00:00
static DWORD ( WINAPI * pGetSecurityInfo ) ( HANDLE , SE_OBJECT_TYPE , SECURITY_INFORMATION ,
PSID * , PSID * , PACL * , PACL * , PSECURITY_DESCRIPTOR * ) ;
2009-02-08 09:32:24 +00:00
static NTSTATUS ( WINAPI * pNtAccessCheck ) ( PSECURITY_DESCRIPTOR , HANDLE , ACCESS_MASK , PGENERIC_MAPPING ,
PPRIVILEGE_SET , PULONG , PULONG , NTSTATUS * ) ;
2007-03-06 11:59:18 +00:00
static HMODULE hmod ;
2008-05-09 17:35:45 +00:00
static int myARGC ;
static char * * myARGV ;
2007-03-06 11:59:18 +00:00
fnBuildTrusteeWithSidA pBuildTrusteeWithSidA ;
fnBuildTrusteeWithNameA pBuildTrusteeWithNameA ;
2008-05-09 17:35:45 +00:00
fnBuildTrusteeWithObjectsAndNameA pBuildTrusteeWithObjectsAndNameA ;
fnBuildTrusteeWithObjectsAndSidA pBuildTrusteeWithObjectsAndSidA ;
fnGetTrusteeNameA pGetTrusteeNameA ;
fnMakeSelfRelativeSD pMakeSelfRelativeSD ;
2007-03-06 11:59:18 +00:00
fnConvertSidToStringSidA pConvertSidToStringSidA ;
fnConvertStringSidToSidA pConvertStringSidToSidA ;
fnGetFileSecurityA pGetFileSecurityA ;
2008-12-09 19:26:45 +00:00
fnSetFileSecurityA pSetFileSecurityA ;
2008-05-09 17:35:45 +00:00
fnRtlAdjustPrivilege pRtlAdjustPrivilege ;
fnCreateWellKnownSid pCreateWellKnownSid ;
fnDuplicateTokenEx pDuplicateTokenEx ;
fnLsaQueryInformationPolicy pLsaQueryInformationPolicy ;
fnLsaClose pLsaClose ;
fnLsaFreeMemory pLsaFreeMemory ;
fnLsaOpenPolicy pLsaOpenPolicy ;
2007-03-06 11:59:18 +00:00
struct sidRef
{
SID_IDENTIFIER_AUTHORITY auth ;
const char * refStr ;
} ;
static void init ( void )
{
2008-05-09 17:35:45 +00:00
HMODULE hntdll ;
hntdll = GetModuleHandleA ( " ntdll.dll " ) ;
pNtQueryObject = ( void * ) GetProcAddress ( hntdll , " NtQueryObject " ) ;
2009-02-08 09:32:24 +00:00
pNtAccessCheck = ( void * ) GetProcAddress ( hntdll , " NtAccessCheck " ) ;
2008-05-09 17:35:45 +00:00
2007-03-06 11:59:18 +00:00
hmod = GetModuleHandle ( " advapi32.dll " ) ;
2008-05-09 17:35:45 +00:00
pAddAccessAllowedAceEx = ( void * ) GetProcAddress ( hmod , " AddAccessAllowedAceEx " ) ;
pAddAccessDeniedAceEx = ( void * ) GetProcAddress ( hmod , " AddAccessDeniedAceEx " ) ;
pAddAuditAccessAceEx = ( void * ) GetProcAddress ( hmod , " AddAuditAccessAceEx " ) ;
pConvertStringSecurityDescriptorToSecurityDescriptorA =
( void * ) GetProcAddress ( hmod , " ConvertStringSecurityDescriptorToSecurityDescriptorA " ) ;
2008-12-09 19:26:45 +00:00
pConvertStringSecurityDescriptorToSecurityDescriptorW =
( void * ) GetProcAddress ( hmod , " ConvertStringSecurityDescriptorToSecurityDescriptorW " ) ;
2008-05-09 17:35:45 +00:00
pConvertSecurityDescriptorToStringSecurityDescriptorA =
( void * ) GetProcAddress ( hmod , " ConvertSecurityDescriptorToStringSecurityDescriptorA " ) ;
2008-12-09 19:26:45 +00:00
pGetFileSecurityA = ( fnGetFileSecurityA ) GetProcAddress ( hmod , " GetFileSecurityA " ) ;
pSetFileSecurityA = ( fnSetFileSecurityA ) GetProcAddress ( hmod , " SetFileSecurityA " ) ;
2008-05-09 17:35:45 +00:00
pCreateWellKnownSid = ( fnCreateWellKnownSid ) GetProcAddress ( hmod , " CreateWellKnownSid " ) ;
pGetNamedSecurityInfoA = ( void * ) GetProcAddress ( hmod , " GetNamedSecurityInfoA " ) ;
2009-10-18 14:57:22 +00:00
pGetSidSubAuthority = ( void * ) GetProcAddress ( hmod , " GetSidSubAuthority " ) ;
pGetSidSubAuthorityCount = ( void * ) GetProcAddress ( hmod , " GetSidSubAuthorityCount " ) ;
pIsValidSid = ( void * ) GetProcAddress ( hmod , " IsValidSid " ) ;
2008-05-09 17:35:45 +00:00
pMakeSelfRelativeSD = ( void * ) GetProcAddress ( hmod , " MakeSelfRelativeSD " ) ;
pSetEntriesInAclW = ( void * ) GetProcAddress ( hmod , " SetEntriesInAclW " ) ;
pSetSecurityDescriptorControl = ( void * ) GetProcAddress ( hmod , " SetSecurityDescriptorControl " ) ;
2008-09-14 18:24:25 +00:00
pGetSecurityInfo = ( void * ) GetProcAddress ( hmod , " GetSecurityInfo " ) ;
2008-05-09 17:35:45 +00:00
myARGC = winetest_get_mainargs ( & myARGV ) ;
}
static void test_str_sid ( const char * str_sid )
{
PSID psid ;
char * temp ;
if ( pConvertStringSidToSidA ( str_sid , & psid ) )
{
if ( pConvertSidToStringSidA ( psid , & temp ) )
{
trace ( " %s: %s \n " , str_sid , temp ) ;
LocalFree ( temp ) ;
}
LocalFree ( psid ) ;
}
else
{
if ( GetLastError ( ) ! = ERROR_INVALID_SID )
trace ( " %s: couldn't be converted, returned %d \n " , str_sid , GetLastError ( ) ) ;
else
trace ( " %s: couldn't be converted \n " , str_sid ) ;
}
2007-03-06 11:59:18 +00:00
}
2008-05-09 17:35:45 +00:00
static void test_sid ( void )
2007-03-06 11:59:18 +00:00
{
struct sidRef refs [ ] = {
{ { { 0x00 , 0x00 , 0x33 , 0x44 , 0x55 , 0x66 } } , " S-1-860116326-1 " } ,
{ { { 0x00 , 0x00 , 0x01 , 0x02 , 0x03 , 0x04 } } , " S-1-16909060-1 " } ,
{ { { 0x00 , 0x00 , 0x00 , 0x01 , 0x02 , 0x03 } } , " S-1-66051-1 " } ,
{ { { 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x02 } } , " S-1-258-1 " } ,
{ { { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 } } , " S-1-2-1 " } ,
{ { { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x0c } } , " S-1-12-1 " } ,
} ;
const char noSubAuthStr [ ] = " S-1-5 " ;
unsigned int i ;
PSID psid = NULL ;
2008-05-09 17:35:45 +00:00
SID * pisid ;
2007-03-06 11:59:18 +00:00
BOOL r ;
LPSTR str = NULL ;
pConvertSidToStringSidA = ( fnConvertSidToStringSidA )
GetProcAddress ( hmod , " ConvertSidToStringSidA " ) ;
if ( ! pConvertSidToStringSidA )
return ;
pConvertStringSidToSidA = ( fnConvertStringSidToSidA )
GetProcAddress ( hmod , " ConvertStringSidToSidA " ) ;
if ( ! pConvertStringSidToSidA )
return ;
r = pConvertStringSidToSidA ( NULL , NULL ) ;
ok ( ! r , " expected failure with NULL parameters \n " ) ;
if ( GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
return ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
2008-05-09 17:35:45 +00:00
" expected GetLastError() is ERROR_INVALID_PARAMETER, got %d \n " ,
2007-03-06 11:59:18 +00:00
GetLastError ( ) ) ;
r = pConvertStringSidToSidA ( refs [ 0 ] . refStr , NULL ) ;
ok ( ! r & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
2008-05-09 17:35:45 +00:00
" expected GetLastError() is ERROR_INVALID_PARAMETER, got %d \n " ,
2007-03-06 11:59:18 +00:00
GetLastError ( ) ) ;
r = pConvertStringSidToSidA ( NULL , & str ) ;
ok ( ! r & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
2008-05-09 17:35:45 +00:00
" expected GetLastError() is ERROR_INVALID_PARAMETER, got %d \n " ,
2007-03-06 11:59:18 +00:00
GetLastError ( ) ) ;
r = pConvertStringSidToSidA ( noSubAuthStr , & psid ) ;
ok ( ! r ,
" expected failure with no sub authorities \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_SID ,
2008-05-09 17:35:45 +00:00
" expected GetLastError() is ERROR_INVALID_SID, got %d \n " ,
2007-03-06 11:59:18 +00:00
GetLastError ( ) ) ;
2008-05-09 17:35:45 +00:00
ok ( pConvertStringSidToSidA ( " S-1-5-21-93476-23408-4576 " , & psid ) , " ConvertStringSidToSidA failed \n " ) ;
2009-02-08 09:32:24 +00:00
pisid = psid ;
2008-05-09 17:35:45 +00:00
ok ( pisid - > SubAuthorityCount = = 4 , " Invalid sub authority count - expected 4, got %d \n " , pisid - > SubAuthorityCount ) ;
ok ( pisid - > SubAuthority [ 0 ] = = 21 , " Invalid subauthority 0 - expceted 21, got %d \n " , pisid - > SubAuthority [ 0 ] ) ;
ok ( pisid - > SubAuthority [ 3 ] = = 4576 , " Invalid subauthority 0 - expceted 4576, got %d \n " , pisid - > SubAuthority [ 3 ] ) ;
LocalFree ( str ) ;
2007-03-06 11:59:18 +00:00
for ( i = 0 ; i < sizeof ( refs ) / sizeof ( refs [ 0 ] ) ; i + + )
{
PISID pisid ;
r = AllocateAndInitializeSid ( & refs [ i ] . auth , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& psid ) ;
ok ( r , " failed to allocate sid \n " ) ;
r = pConvertSidToStringSidA ( psid , & str ) ;
ok ( r , " failed to convert sid \n " ) ;
if ( r )
{
ok ( ! strcmp ( str , refs [ i ] . refStr ) ,
" incorrect sid, expected %s, got %s \n " , refs [ i ] . refStr , str ) ;
LocalFree ( str ) ;
}
if ( psid )
FreeSid ( psid ) ;
r = pConvertStringSidToSidA ( refs [ i ] . refStr , & psid ) ;
ok ( r , " failed to parse sid string \n " ) ;
2009-02-08 09:32:24 +00:00
pisid = psid ;
2007-03-06 11:59:18 +00:00
ok ( pisid & &
! memcmp ( pisid - > IdentifierAuthority . Value , refs [ i ] . auth . Value ,
sizeof ( refs [ i ] . auth ) ) ,
" string sid %s didn't parse to expected value \n "
2008-05-09 17:35:45 +00:00
" (got 0x%04x%08x, expected 0x%04x%08x) \n " ,
2007-03-06 11:59:18 +00:00
refs [ i ] . refStr ,
MAKEWORD ( pisid - > IdentifierAuthority . Value [ 1 ] ,
pisid - > IdentifierAuthority . Value [ 0 ] ) ,
MAKELONG ( MAKEWORD ( pisid - > IdentifierAuthority . Value [ 5 ] ,
pisid - > IdentifierAuthority . Value [ 4 ] ) ,
MAKEWORD ( pisid - > IdentifierAuthority . Value [ 3 ] ,
pisid - > IdentifierAuthority . Value [ 2 ] ) ) ,
MAKEWORD ( refs [ i ] . auth . Value [ 1 ] , refs [ i ] . auth . Value [ 0 ] ) ,
MAKELONG ( MAKEWORD ( refs [ i ] . auth . Value [ 5 ] , refs [ i ] . auth . Value [ 4 ] ) ,
MAKEWORD ( refs [ i ] . auth . Value [ 3 ] , refs [ i ] . auth . Value [ 2 ] ) ) ) ;
if ( psid )
LocalFree ( psid ) ;
}
2008-05-09 17:35:45 +00:00
trace ( " String SIDs: \n " ) ;
test_str_sid ( " AO " ) ;
test_str_sid ( " RU " ) ;
test_str_sid ( " AN " ) ;
test_str_sid ( " AU " ) ;
test_str_sid ( " BA " ) ;
test_str_sid ( " BG " ) ;
test_str_sid ( " BO " ) ;
test_str_sid ( " BU " ) ;
test_str_sid ( " CA " ) ;
test_str_sid ( " CG " ) ;
test_str_sid ( " CO " ) ;
test_str_sid ( " DA " ) ;
test_str_sid ( " DC " ) ;
test_str_sid ( " DD " ) ;
test_str_sid ( " DG " ) ;
test_str_sid ( " DU " ) ;
test_str_sid ( " EA " ) ;
test_str_sid ( " ED " ) ;
test_str_sid ( " WD " ) ;
test_str_sid ( " PA " ) ;
test_str_sid ( " IU " ) ;
test_str_sid ( " LA " ) ;
test_str_sid ( " LG " ) ;
test_str_sid ( " LS " ) ;
test_str_sid ( " SY " ) ;
test_str_sid ( " NU " ) ;
test_str_sid ( " NO " ) ;
test_str_sid ( " NS " ) ;
test_str_sid ( " PO " ) ;
test_str_sid ( " PS " ) ;
test_str_sid ( " PU " ) ;
test_str_sid ( " RS " ) ;
test_str_sid ( " RD " ) ;
test_str_sid ( " RE " ) ;
test_str_sid ( " RC " ) ;
test_str_sid ( " SA " ) ;
test_str_sid ( " SO " ) ;
test_str_sid ( " SU " ) ;
2007-03-06 11:59:18 +00:00
}
2008-05-09 17:35:45 +00:00
static void test_trustee ( void )
2007-03-06 11:59:18 +00:00
{
2008-05-09 17:35:45 +00:00
GUID ObjectType = { 0x12345678 , 0x1234 , 0x5678 , { 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 } } ;
GUID InheritedObjectType = { 0x23456789 , 0x2345 , 0x6786 , { 0x2 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 } } ;
GUID ZeroGuid ;
OBJECTS_AND_NAME_ oan ;
OBJECTS_AND_SID oas ;
2007-03-06 11:59:18 +00:00
TRUSTEE trustee ;
PSID psid ;
2008-05-09 17:35:45 +00:00
char szObjectTypeName [ ] = " ObjectTypeName " ;
char szInheritedObjectTypeName [ ] = " InheritedObjectTypeName " ;
char szTrusteeName [ ] = " szTrusteeName " ;
2007-03-06 11:59:18 +00:00
SID_IDENTIFIER_AUTHORITY auth = { { 0x11 , 0x22 , 0 , 0 , 0 , 0 } } ;
2008-05-09 17:35:45 +00:00
memset ( & ZeroGuid , 0x00 , sizeof ( ZeroGuid ) ) ;
2007-03-06 11:59:18 +00:00
pBuildTrusteeWithSidA = ( fnBuildTrusteeWithSidA )
GetProcAddress ( hmod , " BuildTrusteeWithSidA " ) ;
pBuildTrusteeWithNameA = ( fnBuildTrusteeWithNameA )
GetProcAddress ( hmod , " BuildTrusteeWithNameA " ) ;
2008-05-09 17:35:45 +00:00
pBuildTrusteeWithObjectsAndNameA = ( fnBuildTrusteeWithObjectsAndNameA )
GetProcAddress ( hmod , " BuildTrusteeWithObjectsAndNameA " ) ;
pBuildTrusteeWithObjectsAndSidA = ( fnBuildTrusteeWithObjectsAndSidA )
GetProcAddress ( hmod , " BuildTrusteeWithObjectsAndSidA " ) ;
pGetTrusteeNameA = ( fnGetTrusteeNameA )
GetProcAddress ( hmod , " GetTrusteeNameA " ) ;
if ( ! pBuildTrusteeWithSidA | | ! pBuildTrusteeWithNameA | |
! pBuildTrusteeWithObjectsAndNameA | | ! pBuildTrusteeWithObjectsAndSidA | |
! pGetTrusteeNameA )
2007-03-06 11:59:18 +00:00
return ;
if ( ! AllocateAndInitializeSid ( & auth , 1 , 42 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , & psid ) )
{
trace ( " failed to init SID \n " ) ;
return ;
}
2008-05-09 17:35:45 +00:00
/* test BuildTrusteeWithSidA */
2007-03-06 11:59:18 +00:00
memset ( & trustee , 0xff , sizeof trustee ) ;
pBuildTrusteeWithSidA ( & trustee , psid ) ;
ok ( trustee . pMultipleTrustee = = NULL , " pMultipleTrustee wrong \n " ) ;
2008-05-09 17:35:45 +00:00
ok ( trustee . MultipleTrusteeOperation = = NO_MULTIPLE_TRUSTEE ,
2007-03-06 11:59:18 +00:00
" MultipleTrusteeOperation wrong \n " ) ;
ok ( trustee . TrusteeForm = = TRUSTEE_IS_SID , " TrusteeForm wrong \n " ) ;
ok ( trustee . TrusteeType = = TRUSTEE_IS_UNKNOWN , " TrusteeType wrong \n " ) ;
2009-02-08 09:32:24 +00:00
ok ( trustee . ptstrName = = psid , " ptstrName wrong \n " ) ;
2008-05-09 17:35:45 +00:00
/* test BuildTrusteeWithObjectsAndSidA (test 1) */
memset ( & trustee , 0xff , sizeof trustee ) ;
memset ( & oas , 0xff , sizeof ( oas ) ) ;
pBuildTrusteeWithObjectsAndSidA ( & trustee , & oas , & ObjectType ,
& InheritedObjectType , psid ) ;
ok ( trustee . pMultipleTrustee = = NULL , " pMultipleTrustee wrong \n " ) ;
ok ( trustee . MultipleTrusteeOperation = = NO_MULTIPLE_TRUSTEE , " MultipleTrusteeOperation wrong \n " ) ;
ok ( trustee . TrusteeForm = = TRUSTEE_IS_OBJECTS_AND_SID , " TrusteeForm wrong \n " ) ;
ok ( trustee . TrusteeType = = TRUSTEE_IS_UNKNOWN , " TrusteeType wrong \n " ) ;
ok ( trustee . ptstrName = = ( LPSTR ) & oas , " ptstrName wrong \n " ) ;
ok ( oas . ObjectsPresent = = ( ACE_OBJECT_TYPE_PRESENT | ACE_INHERITED_OBJECT_TYPE_PRESENT ) , " ObjectsPresent wrong \n " ) ;
ok ( ! memcmp ( & oas . ObjectTypeGuid , & ObjectType , sizeof ( GUID ) ) , " ObjectTypeGuid wrong \n " ) ;
ok ( ! memcmp ( & oas . InheritedObjectTypeGuid , & InheritedObjectType , sizeof ( GUID ) ) , " InheritedObjectTypeGuid wrong \n " ) ;
ok ( oas . pSid = = psid , " pSid wrong \n " ) ;
/* test GetTrusteeNameA */
ok ( pGetTrusteeNameA ( & trustee ) = = ( LPSTR ) & oas , " GetTrusteeName returned wrong value \n " ) ;
/* test BuildTrusteeWithObjectsAndSidA (test 2) */
memset ( & trustee , 0xff , sizeof trustee ) ;
memset ( & oas , 0xff , sizeof ( oas ) ) ;
pBuildTrusteeWithObjectsAndSidA ( & trustee , & oas , NULL ,
& InheritedObjectType , psid ) ;
ok ( trustee . pMultipleTrustee = = NULL , " pMultipleTrustee wrong \n " ) ;
ok ( trustee . MultipleTrusteeOperation = = NO_MULTIPLE_TRUSTEE , " MultipleTrusteeOperation wrong \n " ) ;
ok ( trustee . TrusteeForm = = TRUSTEE_IS_OBJECTS_AND_SID , " TrusteeForm wrong \n " ) ;
ok ( trustee . TrusteeType = = TRUSTEE_IS_UNKNOWN , " TrusteeType wrong \n " ) ;
ok ( trustee . ptstrName = = ( LPSTR ) & oas , " ptstrName wrong \n " ) ;
ok ( oas . ObjectsPresent = = ACE_INHERITED_OBJECT_TYPE_PRESENT , " ObjectsPresent wrong \n " ) ;
ok ( ! memcmp ( & oas . ObjectTypeGuid , & ZeroGuid , sizeof ( GUID ) ) , " ObjectTypeGuid wrong \n " ) ;
ok ( ! memcmp ( & oas . InheritedObjectTypeGuid , & InheritedObjectType , sizeof ( GUID ) ) , " InheritedObjectTypeGuid wrong \n " ) ;
ok ( oas . pSid = = psid , " pSid wrong \n " ) ;
2007-03-06 11:59:18 +00:00
FreeSid ( psid ) ;
/* test BuildTrusteeWithNameA */
memset ( & trustee , 0xff , sizeof trustee ) ;
2008-05-09 17:35:45 +00:00
pBuildTrusteeWithNameA ( & trustee , szTrusteeName ) ;
2007-03-06 11:59:18 +00:00
ok ( trustee . pMultipleTrustee = = NULL , " pMultipleTrustee wrong \n " ) ;
2008-05-09 17:35:45 +00:00
ok ( trustee . MultipleTrusteeOperation = = NO_MULTIPLE_TRUSTEE ,
2007-03-06 11:59:18 +00:00
" MultipleTrusteeOperation wrong \n " ) ;
ok ( trustee . TrusteeForm = = TRUSTEE_IS_NAME , " TrusteeForm wrong \n " ) ;
ok ( trustee . TrusteeType = = TRUSTEE_IS_UNKNOWN , " TrusteeType wrong \n " ) ;
2008-05-09 17:35:45 +00:00
ok ( trustee . ptstrName = = szTrusteeName , " ptstrName wrong \n " ) ;
/* test BuildTrusteeWithObjectsAndNameA (test 1) */
memset ( & trustee , 0xff , sizeof trustee ) ;
memset ( & oan , 0xff , sizeof ( oan ) ) ;
pBuildTrusteeWithObjectsAndNameA ( & trustee , & oan , SE_KERNEL_OBJECT , szObjectTypeName ,
szInheritedObjectTypeName , szTrusteeName ) ;
ok ( trustee . pMultipleTrustee = = NULL , " pMultipleTrustee wrong \n " ) ;
ok ( trustee . MultipleTrusteeOperation = = NO_MULTIPLE_TRUSTEE , " MultipleTrusteeOperation wrong \n " ) ;
ok ( trustee . TrusteeForm = = TRUSTEE_IS_OBJECTS_AND_NAME , " TrusteeForm wrong \n " ) ;
ok ( trustee . TrusteeType = = TRUSTEE_IS_UNKNOWN , " TrusteeType wrong \n " ) ;
ok ( trustee . ptstrName = = ( LPTSTR ) & oan , " ptstrName wrong \n " ) ;
ok ( oan . ObjectsPresent = = ( ACE_OBJECT_TYPE_PRESENT | ACE_INHERITED_OBJECT_TYPE_PRESENT ) , " ObjectsPresent wrong \n " ) ;
ok ( oan . ObjectType = = SE_KERNEL_OBJECT , " ObjectType wrong \n " ) ;
ok ( oan . InheritedObjectTypeName = = szInheritedObjectTypeName , " InheritedObjectTypeName wrong \n " ) ;
ok ( oan . ptstrName = = szTrusteeName , " szTrusteeName wrong \n " ) ;
/* test GetTrusteeNameA */
ok ( pGetTrusteeNameA ( & trustee ) = = ( LPSTR ) & oan , " GetTrusteeName returned wrong value \n " ) ;
/* test BuildTrusteeWithObjectsAndNameA (test 2) */
memset ( & trustee , 0xff , sizeof trustee ) ;
memset ( & oan , 0xff , sizeof ( oan ) ) ;
pBuildTrusteeWithObjectsAndNameA ( & trustee , & oan , SE_KERNEL_OBJECT , NULL ,
szInheritedObjectTypeName , szTrusteeName ) ;
ok ( trustee . pMultipleTrustee = = NULL , " pMultipleTrustee wrong \n " ) ;
ok ( trustee . MultipleTrusteeOperation = = NO_MULTIPLE_TRUSTEE , " MultipleTrusteeOperation wrong \n " ) ;
ok ( trustee . TrusteeForm = = TRUSTEE_IS_OBJECTS_AND_NAME , " TrusteeForm wrong \n " ) ;
ok ( trustee . TrusteeType = = TRUSTEE_IS_UNKNOWN , " TrusteeType wrong \n " ) ;
ok ( trustee . ptstrName = = ( LPSTR ) & oan , " ptstrName wrong \n " ) ;
ok ( oan . ObjectsPresent = = ACE_INHERITED_OBJECT_TYPE_PRESENT , " ObjectsPresent wrong \n " ) ;
ok ( oan . ObjectType = = SE_KERNEL_OBJECT , " ObjectType wrong \n " ) ;
ok ( oan . InheritedObjectTypeName = = szInheritedObjectTypeName , " InheritedObjectTypeName wrong \n " ) ;
ok ( oan . ptstrName = = szTrusteeName , " szTrusteeName wrong \n " ) ;
2007-03-06 11:59:18 +00:00
2008-05-09 17:35:45 +00:00
/* test BuildTrusteeWithObjectsAndNameA (test 3) */
memset ( & trustee , 0xff , sizeof trustee ) ;
memset ( & oan , 0xff , sizeof ( oan ) ) ;
pBuildTrusteeWithObjectsAndNameA ( & trustee , & oan , SE_KERNEL_OBJECT , szObjectTypeName ,
NULL , szTrusteeName ) ;
ok ( trustee . pMultipleTrustee = = NULL , " pMultipleTrustee wrong \n " ) ;
ok ( trustee . MultipleTrusteeOperation = = NO_MULTIPLE_TRUSTEE , " MultipleTrusteeOperation wrong \n " ) ;
ok ( trustee . TrusteeForm = = TRUSTEE_IS_OBJECTS_AND_NAME , " TrusteeForm wrong \n " ) ;
ok ( trustee . TrusteeType = = TRUSTEE_IS_UNKNOWN , " TrusteeType wrong \n " ) ;
ok ( trustee . ptstrName = = ( LPTSTR ) & oan , " ptstrName wrong \n " ) ;
ok ( oan . ObjectsPresent = = ACE_OBJECT_TYPE_PRESENT , " ObjectsPresent wrong \n " ) ;
ok ( oan . ObjectType = = SE_KERNEL_OBJECT , " ObjectType wrong \n " ) ;
ok ( oan . InheritedObjectTypeName = = NULL , " InheritedObjectTypeName wrong \n " ) ;
ok ( oan . ptstrName = = szTrusteeName , " szTrusteeName wrong \n " ) ;
}
2007-03-06 11:59:18 +00:00
/* If the first isn't defined, assume none is */
# ifndef SE_MIN_WELL_KNOWN_PRIVILEGE
# define SE_MIN_WELL_KNOWN_PRIVILEGE 2L
# define SE_CREATE_TOKEN_PRIVILEGE 2L
# define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE 3L
# define SE_LOCK_MEMORY_PRIVILEGE 4L
# define SE_INCREASE_QUOTA_PRIVILEGE 5L
# define SE_MACHINE_ACCOUNT_PRIVILEGE 6L
# define SE_TCB_PRIVILEGE 7L
# define SE_SECURITY_PRIVILEGE 8L
# define SE_TAKE_OWNERSHIP_PRIVILEGE 9L
# define SE_LOAD_DRIVER_PRIVILEGE 10L
# define SE_SYSTEM_PROFILE_PRIVILEGE 11L
# define SE_SYSTEMTIME_PRIVILEGE 12L
# define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13L
# define SE_INC_BASE_PRIORITY_PRIVILEGE 14L
# define SE_CREATE_PAGEFILE_PRIVILEGE 15L
# define SE_CREATE_PERMANENT_PRIVILEGE 16L
# define SE_BACKUP_PRIVILEGE 17L
# define SE_RESTORE_PRIVILEGE 18L
# define SE_SHUTDOWN_PRIVILEGE 19L
# define SE_DEBUG_PRIVILEGE 20L
# define SE_AUDIT_PRIVILEGE 21L
# define SE_SYSTEM_ENVIRONMENT_PRIVILEGE 22L
2008-12-09 19:26:45 +00:00
# define SE_CHANGE_NOTIFY_PRIVILEGE 23L
2007-03-06 11:59:18 +00:00
# define SE_REMOTE_SHUTDOWN_PRIVILEGE 24L
# define SE_UNDOCK_PRIVILEGE 25L
# define SE_SYNC_AGENT_PRIVILEGE 26L
# define SE_ENABLE_DELEGATION_PRIVILEGE 27L
# define SE_MANAGE_VOLUME_PRIVILEGE 28L
# define SE_IMPERSONATE_PRIVILEGE 29L
# define SE_CREATE_GLOBAL_PRIVILEGE 30L
# define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_GLOBAL_PRIVILEGE
# endif /* ndef SE_MIN_WELL_KNOWN_PRIVILEGE */
static void test_allocateLuid ( void )
{
BOOL ( WINAPI * pAllocateLocallyUniqueId ) ( PLUID ) ;
LUID luid1 , luid2 ;
BOOL ret ;
pAllocateLocallyUniqueId = ( void * ) GetProcAddress ( hmod , " AllocateLocallyUniqueId " ) ;
if ( ! pAllocateLocallyUniqueId ) return ;
ret = pAllocateLocallyUniqueId ( & luid1 ) ;
if ( ! ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
return ;
ok ( ret ,
2008-05-09 17:35:45 +00:00
" AllocateLocallyUniqueId failed: %d \n " , GetLastError ( ) ) ;
2007-03-06 11:59:18 +00:00
ret = pAllocateLocallyUniqueId ( & luid2 ) ;
ok ( ret ,
2008-05-09 17:35:45 +00:00
" AllocateLocallyUniqueId failed: %d \n " , GetLastError ( ) ) ;
2007-03-06 11:59:18 +00:00
ok ( luid1 . LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE | | luid1 . HighPart ! = 0 ,
" AllocateLocallyUniqueId returned a well-known LUID \n " ) ;
ok ( luid1 . LowPart ! = luid2 . LowPart | | luid1 . HighPart ! = luid2 . HighPart ,
" AllocateLocallyUniqueId returned non-unique LUIDs \n " ) ;
ret = pAllocateLocallyUniqueId ( NULL ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_NOACCESS ,
2008-05-09 17:35:45 +00:00
" AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %d \n " ,
2007-03-06 11:59:18 +00:00
GetLastError ( ) ) ;
}
static void test_lookupPrivilegeName ( void )
{
2008-05-09 17:35:45 +00:00
BOOL ( WINAPI * pLookupPrivilegeNameA ) ( LPCSTR , PLUID , LPSTR , LPDWORD ) ;
2007-03-06 11:59:18 +00:00
char buf [ MAX_PATH ] ; /* arbitrary, seems long enough */
DWORD cchName = sizeof ( buf ) ;
LUID luid = { 0 , 0 } ;
LONG i ;
BOOL ret ;
/* check whether it's available first */
pLookupPrivilegeNameA = ( void * ) GetProcAddress ( hmod , " LookupPrivilegeNameA " ) ;
if ( ! pLookupPrivilegeNameA ) return ;
luid . LowPart = SE_CREATE_TOKEN_PRIVILEGE ;
ret = pLookupPrivilegeNameA ( NULL , & luid , buf , & cchName ) ;
if ( ! ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
return ;
/* check with a short buffer */
cchName = 0 ;
luid . LowPart = SE_CREATE_TOKEN_PRIVILEGE ;
ret = pLookupPrivilegeNameA ( NULL , & luid , NULL , & cchName ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
2008-05-09 17:35:45 +00:00
" LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %d \n " ,
2007-03-06 11:59:18 +00:00
GetLastError ( ) ) ;
ok ( cchName = = strlen ( " SeCreateTokenPrivilege " ) + 1 ,
" LookupPrivilegeNameA returned an incorrect required length for \n "
2008-05-09 17:35:45 +00:00
" SeCreateTokenPrivilege (got %d, expected %d) \n " , cchName ,
lstrlenA ( " SeCreateTokenPrivilege " ) + 1 ) ;
2007-03-06 11:59:18 +00:00
/* check a known value and its returned length on success */
cchName = sizeof ( buf ) ;
ok ( pLookupPrivilegeNameA ( NULL , & luid , buf , & cchName ) & &
cchName = = strlen ( " SeCreateTokenPrivilege " ) ,
" LookupPrivilegeNameA returned an incorrect output length for \n "
2008-05-09 17:35:45 +00:00
" SeCreateTokenPrivilege (got %d, expected %d) \n " , cchName ,
2007-03-06 11:59:18 +00:00
( int ) strlen ( " SeCreateTokenPrivilege " ) ) ;
/* check known values */
2008-12-09 19:26:45 +00:00
for ( i = SE_MIN_WELL_KNOWN_PRIVILEGE ; i < = SE_MAX_WELL_KNOWN_PRIVILEGE ; i + + )
2007-03-06 11:59:18 +00:00
{
luid . LowPart = i ;
cchName = sizeof ( buf ) ;
ret = pLookupPrivilegeNameA ( NULL , & luid , buf , & cchName ) ;
ok ( ret | | GetLastError ( ) = = ERROR_NO_SUCH_PRIVILEGE ,
2008-05-09 17:35:45 +00:00
" LookupPrivilegeNameA(0.%d) failed: %d \n " , i , GetLastError ( ) ) ;
2007-03-06 11:59:18 +00:00
}
/* check a bogus LUID */
luid . LowPart = 0xdeadbeef ;
cchName = sizeof ( buf ) ;
ret = pLookupPrivilegeNameA ( NULL , & luid , buf , & cchName ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_NO_SUCH_PRIVILEGE ,
2008-05-09 17:35:45 +00:00
" LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d \n " ,
2007-03-06 11:59:18 +00:00
GetLastError ( ) ) ;
/* check on a bogus system */
luid . LowPart = SE_CREATE_TOKEN_PRIVILEGE ;
cchName = sizeof ( buf ) ;
ret = pLookupPrivilegeNameA ( " b0gu5.Nam3 " , & luid , buf , & cchName ) ;
2008-09-14 18:24:25 +00:00
ok ( ! ret & & ( GetLastError ( ) = = RPC_S_SERVER_UNAVAILABLE | |
GetLastError ( ) = = RPC_S_INVALID_NET_ADDR ) /* w2k8 */ ,
" LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR: %d \n " ,
2007-03-06 11:59:18 +00:00
GetLastError ( ) ) ;
}
struct NameToLUID
{
const char * name ;
DWORD lowPart ;
} ;
static void test_lookupPrivilegeValue ( void )
{
static const struct NameToLUID privs [ ] = {
{ " SeCreateTokenPrivilege " , SE_CREATE_TOKEN_PRIVILEGE } ,
{ " SeAssignPrimaryTokenPrivilege " , SE_ASSIGNPRIMARYTOKEN_PRIVILEGE } ,
{ " SeLockMemoryPrivilege " , SE_LOCK_MEMORY_PRIVILEGE } ,
{ " SeIncreaseQuotaPrivilege " , SE_INCREASE_QUOTA_PRIVILEGE } ,
{ " SeMachineAccountPrivilege " , SE_MACHINE_ACCOUNT_PRIVILEGE } ,
{ " SeTcbPrivilege " , SE_TCB_PRIVILEGE } ,
{ " SeSecurityPrivilege " , SE_SECURITY_PRIVILEGE } ,
{ " SeTakeOwnershipPrivilege " , SE_TAKE_OWNERSHIP_PRIVILEGE } ,
{ " SeLoadDriverPrivilege " , SE_LOAD_DRIVER_PRIVILEGE } ,
{ " SeSystemProfilePrivilege " , SE_SYSTEM_PROFILE_PRIVILEGE } ,
{ " SeSystemtimePrivilege " , SE_SYSTEMTIME_PRIVILEGE } ,
{ " SeProfileSingleProcessPrivilege " , SE_PROF_SINGLE_PROCESS_PRIVILEGE } ,
{ " SeIncreaseBasePriorityPrivilege " , SE_INC_BASE_PRIORITY_PRIVILEGE } ,
{ " SeCreatePagefilePrivilege " , SE_CREATE_PAGEFILE_PRIVILEGE } ,
{ " SeCreatePermanentPrivilege " , SE_CREATE_PERMANENT_PRIVILEGE } ,
{ " SeBackupPrivilege " , SE_BACKUP_PRIVILEGE } ,
{ " SeRestorePrivilege " , SE_RESTORE_PRIVILEGE } ,
{ " SeShutdownPrivilege " , SE_SHUTDOWN_PRIVILEGE } ,
{ " SeDebugPrivilege " , SE_DEBUG_PRIVILEGE } ,
{ " SeAuditPrivilege " , SE_AUDIT_PRIVILEGE } ,
{ " SeSystemEnvironmentPrivilege " , SE_SYSTEM_ENVIRONMENT_PRIVILEGE } ,
2008-12-09 19:26:45 +00:00
{ " SeChangeNotifyPrivilege " , SE_CHANGE_NOTIFY_PRIVILEGE } ,
2007-03-06 11:59:18 +00:00
{ " SeRemoteShutdownPrivilege " , SE_REMOTE_SHUTDOWN_PRIVILEGE } ,
{ " SeUndockPrivilege " , SE_UNDOCK_PRIVILEGE } ,
{ " SeSyncAgentPrivilege " , SE_SYNC_AGENT_PRIVILEGE } ,
{ " SeEnableDelegationPrivilege " , SE_ENABLE_DELEGATION_PRIVILEGE } ,
{ " SeManageVolumePrivilege " , SE_MANAGE_VOLUME_PRIVILEGE } ,
{ " SeImpersonatePrivilege " , SE_IMPERSONATE_PRIVILEGE } ,
{ " SeCreateGlobalPrivilege " , SE_CREATE_GLOBAL_PRIVILEGE } ,
} ;
BOOL ( WINAPI * pLookupPrivilegeValueA ) ( LPCSTR , LPCSTR , PLUID ) ;
int i ;
LUID luid ;
BOOL ret ;
/* check whether it's available first */
pLookupPrivilegeValueA = ( void * ) GetProcAddress ( hmod , " LookupPrivilegeValueA " ) ;
if ( ! pLookupPrivilegeValueA ) return ;
ret = pLookupPrivilegeValueA ( NULL , " SeCreateTokenPrivilege " , & luid ) ;
if ( ! ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
return ;
/* check a bogus system name */
ret = pLookupPrivilegeValueA ( " b0gu5.Nam3 " , " SeCreateTokenPrivilege " , & luid ) ;
2008-09-14 18:24:25 +00:00
ok ( ! ret & & ( GetLastError ( ) = = RPC_S_SERVER_UNAVAILABLE | |
GetLastError ( ) = = RPC_S_INVALID_NET_ADDR ) /* w2k8 */ ,
" LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR: %d \n " ,
2007-03-06 11:59:18 +00:00
GetLastError ( ) ) ;
/* check a NULL string */
ret = pLookupPrivilegeValueA ( NULL , 0 , & luid ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_NO_SUCH_PRIVILEGE ,
2008-05-09 17:35:45 +00:00
" LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d \n " ,
2007-03-06 11:59:18 +00:00
GetLastError ( ) ) ;
/* check a bogus privilege name */
ret = pLookupPrivilegeValueA ( NULL , " SeBogusPrivilege " , & luid ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_NO_SUCH_PRIVILEGE ,
2008-05-09 17:35:45 +00:00
" LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d \n " ,
2007-03-06 11:59:18 +00:00
GetLastError ( ) ) ;
/* check case insensitive */
ret = pLookupPrivilegeValueA ( NULL , " sEcREATEtOKENpRIVILEGE " , & luid ) ;
ok ( ret ,
2008-05-09 17:35:45 +00:00
" LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %d \n " ,
2007-03-06 11:59:18 +00:00
GetLastError ( ) ) ;
for ( i = 0 ; i < sizeof ( privs ) / sizeof ( privs [ 0 ] ) ; i + + )
{
/* Not all privileges are implemented on all Windows versions, so
* don ' t worry if the call fails
*/
if ( pLookupPrivilegeValueA ( NULL , privs [ i ] . name , & luid ) )
{
ok ( luid . LowPart = = privs [ i ] . lowPart ,
" LookupPrivilegeValueA returned an invalid LUID for %s \n " ,
privs [ i ] . name ) ;
}
}
}
static void test_luid ( void )
{
test_allocateLuid ( ) ;
test_lookupPrivilegeName ( ) ;
test_lookupPrivilegeValue ( ) ;
}
static void test_FileSecurity ( void )
{
2008-12-09 19:26:45 +00:00
char wintmpdir [ MAX_PATH ] ;
char path [ MAX_PATH ] ;
char file [ MAX_PATH ] ;
BOOL rc ;
HANDLE fh ;
DWORD sdSize ;
DWORD retSize ;
BYTE * sd ;
SECURITY_INFORMATION const request = OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION ;
if ( ! pGetFileSecurityA ) {
win_skip ( " GetFileSecurity is not available \n " ) ;
return ;
}
if ( ! pSetFileSecurityA ) {
win_skip ( " SetFileSecurity is not available \n " ) ;
2007-03-06 11:59:18 +00:00
return ;
2008-12-09 19:26:45 +00:00
}
2007-03-06 11:59:18 +00:00
2008-12-09 19:26:45 +00:00
if ( ! GetTempPathA ( sizeof ( wintmpdir ) , wintmpdir ) ) {
win_skip ( " GetTempPathA failed \n " ) ;
2007-03-06 11:59:18 +00:00
return ;
}
2008-12-09 19:26:45 +00:00
/* Create a temporary directory and in it a temporary file */
strcat ( strcpy ( path , wintmpdir ) , " rary " ) ;
SetLastError ( 0xdeadbeef ) ;
rc = CreateDirectoryA ( path , NULL ) ;
ok ( rc | | GetLastError ( ) = = ERROR_ALREADY_EXISTS , " CreateDirectoryA "
" failed for '%s' with %d \n " , path , GetLastError ( ) ) ;
strcat ( strcpy ( file , path ) , " \\ ess " ) ;
SetLastError ( 0xdeadbeef ) ;
fh = CreateFileA ( file , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS , 0 , NULL ) ;
ok ( fh ! = INVALID_HANDLE_VALUE , " CreateFileA "
" failed for '%s' with %d \n " , file , GetLastError ( ) ) ;
CloseHandle ( fh ) ;
/* For the temporary file ... */
/* Get size needed */
retSize = 0 ;
SetLastError ( 0xdeadbeef ) ;
rc = pGetFileSecurityA ( file , request , NULL , 0 , & retSize ) ;
if ( ! rc & & ( GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED ) ) {
win_skip ( " GetFileSecurityA is not implemented \n " ) ;
goto cleanup ;
}
ok ( ! rc , " GetFileSecurityA "
" was expected to fail for '%s' \n " , file ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER , " GetFileSecurityA "
" returned %d; expected ERROR_INSUFFICIENT_BUFFER \n " , GetLastError ( ) ) ;
ok ( retSize > sizeof ( SECURITY_DESCRIPTOR ) , " GetFileSecurityA returned size %d \n " , retSize ) ;
sdSize = retSize ;
sd = HeapAlloc ( GetProcessHeap ( ) , 0 , sdSize ) ;
/* Get security descriptor for real */
retSize = - 1 ;
SetLastError ( 0xdeadbeef ) ;
rc = pGetFileSecurityA ( file , request , sd , sdSize , & retSize ) ;
ok ( rc , " GetFileSecurityA "
" was not expected to fail '%s': %d \n " , file , GetLastError ( ) ) ;
ok ( retSize = = sdSize | |
broken ( retSize = = 0 ) , /* NT4 */
" GetFileSecurityA returned size %d; expected %d \n " , retSize , sdSize ) ;
/* Use it to set security descriptor */
SetLastError ( 0xdeadbeef ) ;
rc = pSetFileSecurityA ( file , request , sd ) ;
ok ( rc , " SetFileSecurityA "
" was not expected to fail '%s': %d \n " , file , GetLastError ( ) ) ;
HeapFree ( GetProcessHeap ( ) , 0 , sd ) ;
/* Repeat for the temporary directory ... */
/* Get size needed */
retSize = 0 ;
SetLastError ( 0xdeadbeef ) ;
rc = pGetFileSecurityA ( path , request , NULL , 0 , & retSize ) ;
ok ( ! rc , " GetFileSecurityA "
" was expected to fail for '%s' \n " , path ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER , " GetFileSecurityA "
" returned %d; expected ERROR_INSUFFICIENT_BUFFER \n " , GetLastError ( ) ) ;
ok ( retSize > sizeof ( SECURITY_DESCRIPTOR ) , " GetFileSecurityA returned size %d \n " , retSize ) ;
sdSize = retSize ;
sd = HeapAlloc ( GetProcessHeap ( ) , 0 , sdSize ) ;
/* Get security descriptor for real */
retSize = - 1 ;
SetLastError ( 0xdeadbeef ) ;
rc = pGetFileSecurityA ( path , request , sd , sdSize , & retSize ) ;
ok ( rc , " GetFileSecurityA "
" was not expected to fail '%s': %d \n " , path , GetLastError ( ) ) ;
ok ( retSize = = sdSize | |
broken ( retSize = = 0 ) , /* NT4 */
" GetFileSecurityA returned size %d; expected %d \n " , retSize , sdSize ) ;
/* Use it to set security descriptor */
SetLastError ( 0xdeadbeef ) ;
rc = pSetFileSecurityA ( path , request , sd ) ;
ok ( rc , " SetFileSecurityA "
" was not expected to fail '%s': %d \n " , path , GetLastError ( ) ) ;
HeapFree ( GetProcessHeap ( ) , 0 , sd ) ;
2007-03-06 11:59:18 +00:00
2008-12-09 19:26:45 +00:00
/* Old test */
strcpy ( wintmpdir , " \\ Should not exist " ) ;
SetLastError ( 0xdeadbeef ) ;
rc = pGetFileSecurityA ( wintmpdir , OWNER_SECURITY_INFORMATION , NULL , 0 , & sdSize ) ;
ok ( ! rc , " GetFileSecurityA should fail for not existing directories/files \n " ) ;
ok ( GetLastError ( ) = = ERROR_FILE_NOT_FOUND ,
" last error ERROR_FILE_NOT_FOUND expected, got %d \n " , GetLastError ( ) ) ;
cleanup :
/* Remove temporary file and directory */
DeleteFileA ( file ) ;
RemoveDirectoryA ( path ) ;
2008-05-09 17:35:45 +00:00
}
static void test_AccessCheck ( void )
{
PSID EveryoneSid = NULL , AdminSid = NULL , UsersSid = NULL ;
PACL Acl = NULL ;
SECURITY_DESCRIPTOR * SecurityDescriptor = NULL ;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY } ;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY } ;
GENERIC_MAPPING Mapping = { KEY_READ , KEY_WRITE , KEY_EXECUTE , KEY_ALL_ACCESS } ;
ACCESS_MASK Access ;
BOOL AccessStatus ;
HANDLE Token ;
HANDLE ProcessToken ;
BOOL ret ;
DWORD PrivSetLen ;
PRIVILEGE_SET * PrivSet ;
BOOL res ;
HMODULE NtDllModule ;
BOOLEAN Enabled ;
DWORD err ;
2009-02-08 09:32:24 +00:00
NTSTATUS ntret , ntAccessStatus ;
2008-05-09 17:35:45 +00:00
NtDllModule = GetModuleHandle ( " ntdll.dll " ) ;
if ( ! NtDllModule )
{
skip ( " not running on NT, skipping test \n " ) ;
return ;
}
pRtlAdjustPrivilege = ( fnRtlAdjustPrivilege )
GetProcAddress ( NtDllModule , " RtlAdjustPrivilege " ) ;
if ( ! pRtlAdjustPrivilege )
{
2009-05-17 07:05:22 +00:00
win_skip ( " missing RtlAdjustPrivilege, skipping test \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
Acl = HeapAlloc ( GetProcessHeap ( ) , 0 , 256 ) ;
res = InitializeAcl ( Acl , 256 , ACL_REVISION ) ;
if ( ! res & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
{
skip ( " ACLs not implemented - skipping tests \n " ) ;
HeapFree ( GetProcessHeap ( ) , 0 , Acl ) ;
return ;
}
ok ( res , " InitializeAcl failed with error %d \n " , GetLastError ( ) ) ;
res = AllocateAndInitializeSid ( & SIDAuthWorld , 1 , SECURITY_WORLD_RID , 0 , 0 , 0 , 0 , 0 , 0 , 0 , & EveryoneSid ) ;
ok ( res , " AllocateAndInitializeSid failed with error %d \n " , GetLastError ( ) ) ;
res = AllocateAndInitializeSid ( & SIDAuthNT , 2 , SECURITY_BUILTIN_DOMAIN_RID ,
DOMAIN_ALIAS_RID_ADMINS , 0 , 0 , 0 , 0 , 0 , 0 , & AdminSid ) ;
ok ( res , " AllocateAndInitializeSid failed with error %d \n " , GetLastError ( ) ) ;
res = AllocateAndInitializeSid ( & SIDAuthNT , 2 , SECURITY_BUILTIN_DOMAIN_RID ,
DOMAIN_ALIAS_RID_USERS , 0 , 0 , 0 , 0 , 0 , 0 , & UsersSid ) ;
ok ( res , " AllocateAndInitializeSid failed with error %d \n " , GetLastError ( ) ) ;
SecurityDescriptor = HeapAlloc ( GetProcessHeap ( ) , 0 , SECURITY_DESCRIPTOR_MIN_LENGTH ) ;
res = InitializeSecurityDescriptor ( SecurityDescriptor , SECURITY_DESCRIPTOR_REVISION ) ;
ok ( res , " InitializeSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
res = SetSecurityDescriptorDacl ( SecurityDescriptor , TRUE , Acl , FALSE ) ;
ok ( res , " SetSecurityDescriptorDacl failed with error %d \n " , GetLastError ( ) ) ;
PrivSetLen = FIELD_OFFSET ( PRIVILEGE_SET , Privilege [ 16 ] ) ;
PrivSet = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , PrivSetLen ) ;
PrivSet - > PrivilegeCount = 16 ;
res = OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_DUPLICATE | TOKEN_QUERY , & ProcessToken ) ;
ok ( res , " OpenProcessToken failed with error %d \n " , GetLastError ( ) ) ;
pRtlAdjustPrivilege ( SE_SECURITY_PRIVILEGE , FALSE , TRUE , & Enabled ) ;
res = DuplicateToken ( ProcessToken , SecurityImpersonation , & Token ) ;
ok ( res , " DuplicateToken failed with error %d \n " , GetLastError ( ) ) ;
/* SD without owner/group */
SetLastError ( 0xdeadbeef ) ;
Access = AccessStatus = 0xdeadbeef ;
ret = AccessCheck ( SecurityDescriptor , Token , KEY_QUERY_VALUE , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
err = GetLastError ( ) ;
ok ( ! ret & & err = = ERROR_INVALID_SECURITY_DESCR , " AccessCheck should have "
" failed with ERROR_INVALID_SECURITY_DESCR, instead of %d \n " , err ) ;
ok ( Access = = 0xdeadbeef & & AccessStatus = = 0xdeadbeef ,
" Access and/or AccessStatus were changed! \n " ) ;
/* Set owner and group */
res = SetSecurityDescriptorOwner ( SecurityDescriptor , AdminSid , FALSE ) ;
ok ( res , " SetSecurityDescriptorOwner failed with error %d \n " , GetLastError ( ) ) ;
res = SetSecurityDescriptorGroup ( SecurityDescriptor , UsersSid , TRUE ) ;
ok ( res , " SetSecurityDescriptorGroup failed with error %d \n " , GetLastError ( ) ) ;
/* Generic access mask */
SetLastError ( 0xdeadbeef ) ;
2009-02-08 09:32:24 +00:00
Access = AccessStatus = 0xdeadbeef ;
2008-05-09 17:35:45 +00:00
ret = AccessCheck ( SecurityDescriptor , Token , GENERIC_READ , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
err = GetLastError ( ) ;
ok ( ! ret & & err = = ERROR_GENERIC_NOT_MAPPED , " AccessCheck should have failed "
" with ERROR_GENERIC_NOT_MAPPED, instead of %d \n " , err ) ;
ok ( Access = = 0xdeadbeef & & AccessStatus = = 0xdeadbeef ,
" Access and/or AccessStatus were changed! \n " ) ;
2009-02-08 09:32:24 +00:00
/* Generic access mask - no privilegeset buffer */
SetLastError ( 0xdeadbeef ) ;
Access = AccessStatus = 0xdeadbeef ;
ret = AccessCheck ( SecurityDescriptor , Token , GENERIC_READ , & Mapping ,
NULL , & PrivSetLen , & Access , & AccessStatus ) ;
err = GetLastError ( ) ;
ok ( ! ret & & err = = ERROR_NOACCESS , " AccessCheck should have failed "
" with ERROR_NOACCESS, instead of %d \n " , err ) ;
ok ( Access = = 0xdeadbeef & & AccessStatus = = 0xdeadbeef ,
" Access and/or AccessStatus were changed! \n " ) ;
/* Generic access mask - no returnlength */
SetLastError ( 0xdeadbeef ) ;
Access = AccessStatus = 0xdeadbeef ;
ret = AccessCheck ( SecurityDescriptor , Token , GENERIC_READ , & Mapping ,
PrivSet , NULL , & Access , & AccessStatus ) ;
err = GetLastError ( ) ;
ok ( ! ret & & err = = ERROR_NOACCESS , " AccessCheck should have failed "
" with ERROR_NOACCESS, instead of %d \n " , err ) ;
ok ( Access = = 0xdeadbeef & & AccessStatus = = 0xdeadbeef ,
" Access and/or AccessStatus were changed! \n " ) ;
/* Generic access mask - no privilegeset buffer, no returnlength */
SetLastError ( 0xdeadbeef ) ;
Access = AccessStatus = 0xdeadbeef ;
ret = AccessCheck ( SecurityDescriptor , Token , GENERIC_READ , & Mapping ,
NULL , NULL , & Access , & AccessStatus ) ;
err = GetLastError ( ) ;
ok ( ! ret & & err = = ERROR_NOACCESS , " AccessCheck should have failed "
" with ERROR_NOACCESS, instead of %d \n " , err ) ;
ok ( Access = = 0xdeadbeef & & AccessStatus = = 0xdeadbeef ,
" Access and/or AccessStatus were changed! \n " ) ;
2008-05-09 17:35:45 +00:00
/* sd with no dacl present */
2009-02-08 09:32:24 +00:00
Access = AccessStatus = 0xdeadbeef ;
2008-05-09 17:35:45 +00:00
ret = SetSecurityDescriptorDacl ( SecurityDescriptor , FALSE , NULL , FALSE ) ;
ok ( ret , " SetSecurityDescriptorDacl failed with error %d \n " , GetLastError ( ) ) ;
ret = AccessCheck ( SecurityDescriptor , Token , KEY_READ , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
ok ( ret , " AccessCheck failed with error %d \n " , GetLastError ( ) ) ;
ok ( AccessStatus & & ( Access = = KEY_READ ) ,
" AccessCheck failed to grant access with error %d \n " ,
GetLastError ( ) ) ;
2009-02-08 09:32:24 +00:00
/* sd with no dacl present - no privilegeset buffer */
SetLastError ( 0xdeadbeef ) ;
Access = AccessStatus = 0xdeadbeef ;
ret = AccessCheck ( SecurityDescriptor , Token , GENERIC_READ , & Mapping ,
NULL , & PrivSetLen , & Access , & AccessStatus ) ;
err = GetLastError ( ) ;
ok ( ! ret & & err = = ERROR_NOACCESS , " AccessCheck should have failed "
" with ERROR_NOACCESS, instead of %d \n " , err ) ;
ok ( Access = = 0xdeadbeef & & AccessStatus = = 0xdeadbeef ,
" Access and/or AccessStatus were changed! \n " ) ;
if ( pNtAccessCheck )
{
/* Generic access mask - no privilegeset buffer */
SetLastError ( 0xdeadbeef ) ;
Access = ntAccessStatus = 0xdeadbeef ;
ntret = pNtAccessCheck ( SecurityDescriptor , Token , GENERIC_READ , & Mapping ,
NULL , & PrivSetLen , & Access , & ntAccessStatus ) ;
err = GetLastError ( ) ;
ok ( ntret = = STATUS_ACCESS_VIOLATION ,
" NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x \n " , ntret ) ;
ok ( err = = 0xdeadbeef ,
" NtAccessCheck shouldn't set last error, got %d \n " , err ) ;
ok ( Access = = 0xdeadbeef & & ntAccessStatus = = 0xdeadbeef ,
" Access and/or AccessStatus were changed! \n " ) ;
/* Generic access mask - no returnlength */
SetLastError ( 0xdeadbeef ) ;
Access = ntAccessStatus = 0xdeadbeef ;
ntret = pNtAccessCheck ( SecurityDescriptor , Token , GENERIC_READ , & Mapping ,
PrivSet , NULL , & Access , & ntAccessStatus ) ;
err = GetLastError ( ) ;
ok ( ntret = = STATUS_ACCESS_VIOLATION ,
" NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x \n " , ntret ) ;
ok ( err = = 0xdeadbeef ,
" NtAccessCheck shouldn't set last error, got %d \n " , err ) ;
ok ( Access = = 0xdeadbeef & & ntAccessStatus = = 0xdeadbeef ,
" Access and/or AccessStatus were changed! \n " ) ;
/* Generic access mask - no privilegeset buffer, no returnlength */
SetLastError ( 0xdeadbeef ) ;
Access = ntAccessStatus = 0xdeadbeef ;
ntret = pNtAccessCheck ( SecurityDescriptor , Token , GENERIC_READ , & Mapping ,
NULL , NULL , & Access , & ntAccessStatus ) ;
err = GetLastError ( ) ;
ok ( ntret = = STATUS_ACCESS_VIOLATION ,
" NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x \n " , ntret ) ;
ok ( err = = 0xdeadbeef ,
" NtAccessCheck shouldn't set last error, got %d \n " , err ) ;
ok ( Access = = 0xdeadbeef & & ntAccessStatus = = 0xdeadbeef ,
" Access and/or AccessStatus were changed! \n " ) ;
}
else
win_skip ( " NtAccessCheck unavailable. Skipping. \n " ) ;
2008-05-09 17:35:45 +00:00
/* sd with NULL dacl */
2009-02-08 09:32:24 +00:00
Access = AccessStatus = 0xdeadbeef ;
2008-05-09 17:35:45 +00:00
ret = SetSecurityDescriptorDacl ( SecurityDescriptor , TRUE , NULL , FALSE ) ;
ok ( ret , " SetSecurityDescriptorDacl failed with error %d \n " , GetLastError ( ) ) ;
ret = AccessCheck ( SecurityDescriptor , Token , KEY_READ , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
ok ( ret , " AccessCheck failed with error %d \n " , GetLastError ( ) ) ;
ok ( AccessStatus & & ( Access = = KEY_READ ) ,
" AccessCheck failed to grant access with error %d \n " ,
GetLastError ( ) ) ;
/* sd with blank dacl */
ret = SetSecurityDescriptorDacl ( SecurityDescriptor , TRUE , Acl , FALSE ) ;
ok ( ret , " SetSecurityDescriptorDacl failed with error %d \n " , GetLastError ( ) ) ;
ret = AccessCheck ( SecurityDescriptor , Token , KEY_READ , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
ok ( ret , " AccessCheck failed with error %d \n " , GetLastError ( ) ) ;
err = GetLastError ( ) ;
ok ( ! AccessStatus & & err = = ERROR_ACCESS_DENIED , " AccessCheck should have failed "
" with ERROR_ACCESS_DENIED, instead of %d \n " , err ) ;
ok ( ! Access , " Should have failed to grant any access, got 0x%08x \n " , Access ) ;
res = AddAccessAllowedAce ( Acl , ACL_REVISION , KEY_READ , EveryoneSid ) ;
ok ( res , " AddAccessAllowedAce failed with error %d \n " , GetLastError ( ) ) ;
res = AddAccessDeniedAce ( Acl , ACL_REVISION , KEY_SET_VALUE , AdminSid ) ;
ok ( res , " AddAccessDeniedAce failed with error %d \n " , GetLastError ( ) ) ;
/* sd with dacl */
2009-02-08 09:32:24 +00:00
Access = AccessStatus = 0xdeadbeef ;
2008-05-09 17:35:45 +00:00
ret = AccessCheck ( SecurityDescriptor , Token , KEY_READ , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
ok ( ret , " AccessCheck failed with error %d \n " , GetLastError ( ) ) ;
ok ( AccessStatus & & ( Access = = KEY_READ ) ,
" AccessCheck failed to grant access with error %d \n " ,
GetLastError ( ) ) ;
ret = AccessCheck ( SecurityDescriptor , Token , MAXIMUM_ALLOWED , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
ok ( ret , " AccessCheck failed with error %d \n " , GetLastError ( ) ) ;
ok ( AccessStatus ,
" AccessCheck failed to grant any access with error %d \n " ,
GetLastError ( ) ) ;
trace ( " AccessCheck with MAXIMUM_ALLOWED got Access 0x%08x \n " , Access ) ;
/* Access denied by SD */
SetLastError ( 0xdeadbeef ) ;
2009-02-08 09:32:24 +00:00
Access = AccessStatus = 0xdeadbeef ;
2008-05-09 17:35:45 +00:00
ret = AccessCheck ( SecurityDescriptor , Token , KEY_WRITE , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
ok ( ret , " AccessCheck failed with error %d \n " , GetLastError ( ) ) ;
err = GetLastError ( ) ;
ok ( ! AccessStatus & & err = = ERROR_ACCESS_DENIED , " AccessCheck should have failed "
" with ERROR_ACCESS_DENIED, instead of %d \n " , err ) ;
ok ( ! Access , " Should have failed to grant any access, got 0x%08x \n " , Access ) ;
SetLastError ( 0 ) ;
PrivSet - > PrivilegeCount = 16 ;
ret = AccessCheck ( SecurityDescriptor , Token , ACCESS_SYSTEM_SECURITY , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
ok ( ret & & ! AccessStatus & & GetLastError ( ) = = ERROR_PRIVILEGE_NOT_HELD ,
" AccessCheck should have failed with ERROR_PRIVILEGE_NOT_HELD, instead of %d \n " ,
GetLastError ( ) ) ;
ret = ImpersonateLoggedOnUser ( Token ) ;
ok ( ret , " ImpersonateLoggedOnUser failed with error %d \n " , GetLastError ( ) ) ;
ret = pRtlAdjustPrivilege ( SE_SECURITY_PRIVILEGE , TRUE , TRUE , & Enabled ) ;
if ( ! ret )
{
SetLastError ( 0 ) ;
PrivSet - > PrivilegeCount = 16 ;
ret = AccessCheck ( SecurityDescriptor , Token , ACCESS_SYSTEM_SECURITY , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
ok ( ret & & AccessStatus & & GetLastError ( ) = = 0 ,
" AccessCheck should have succeeded, error %d \n " ,
GetLastError ( ) ) ;
ok ( Access = = ACCESS_SYSTEM_SECURITY ,
" Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08x \n " ,
Access ) ;
}
else
trace ( " Couldn't get SE_SECURITY_PRIVILEGE (0x%08x), skipping ACCESS_SYSTEM_SECURITY test \n " ,
ret ) ;
ret = RevertToSelf ( ) ;
ok ( ret , " RevertToSelf failed with error %d \n " , GetLastError ( ) ) ;
/* test INHERIT_ONLY_ACE */
ret = InitializeAcl ( Acl , 256 , ACL_REVISION ) ;
ok ( ret , " InitializeAcl failed with error %d \n " , GetLastError ( ) ) ;
/* NT doesn't have AddAccessAllowedAceEx. Skipping this call/test doesn't influence
* the next ones .
*/
if ( pAddAccessAllowedAceEx )
{
ret = pAddAccessAllowedAceEx ( Acl , ACL_REVISION , INHERIT_ONLY_ACE , KEY_READ , EveryoneSid ) ;
ok ( ret , " AddAccessAllowedAceEx failed with error %d \n " , GetLastError ( ) ) ;
}
else
2009-05-17 07:05:22 +00:00
win_skip ( " AddAccessAllowedAceEx is not available \n " ) ;
2008-05-09 17:35:45 +00:00
ret = AccessCheck ( SecurityDescriptor , Token , KEY_READ , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
ok ( ret , " AccessCheck failed with error %d \n " , GetLastError ( ) ) ;
err = GetLastError ( ) ;
ok ( ! AccessStatus & & err = = ERROR_ACCESS_DENIED , " AccessCheck should have failed "
" with ERROR_ACCESS_DENIED, instead of %d \n " , err ) ;
ok ( ! Access , " Should have failed to grant any access, got 0x%08x \n " , Access ) ;
CloseHandle ( Token ) ;
res = DuplicateToken ( ProcessToken , SecurityAnonymous , & Token ) ;
ok ( res , " DuplicateToken failed with error %d \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = AccessCheck ( SecurityDescriptor , Token , MAXIMUM_ALLOWED , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
err = GetLastError ( ) ;
ok ( ! ret & & err = = ERROR_BAD_IMPERSONATION_LEVEL , " AccessCheck should have failed "
" with ERROR_BAD_IMPERSONATION_LEVEL, instead of %d \n " , err ) ;
CloseHandle ( Token ) ;
SetLastError ( 0xdeadbeef ) ;
ret = AccessCheck ( SecurityDescriptor , ProcessToken , KEY_READ , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
err = GetLastError ( ) ;
ok ( ! ret & & err = = ERROR_NO_IMPERSONATION_TOKEN , " AccessCheck should have failed "
" with ERROR_NO_IMPERSONATION_TOKEN, instead of %d \n " , err ) ;
CloseHandle ( ProcessToken ) ;
if ( EveryoneSid )
FreeSid ( EveryoneSid ) ;
if ( AdminSid )
FreeSid ( AdminSid ) ;
if ( UsersSid )
FreeSid ( UsersSid ) ;
HeapFree ( GetProcessHeap ( ) , 0 , Acl ) ;
HeapFree ( GetProcessHeap ( ) , 0 , SecurityDescriptor ) ;
HeapFree ( GetProcessHeap ( ) , 0 , PrivSet ) ;
}
/* test GetTokenInformation for the various attributes */
static void test_token_attr ( void )
{
HANDLE Token , ImpersonationToken ;
2009-05-17 07:05:22 +00:00
DWORD Size , Size2 ;
2008-05-09 17:35:45 +00:00
TOKEN_PRIVILEGES * Privileges ;
TOKEN_GROUPS * Groups ;
TOKEN_USER * User ;
2009-05-17 07:05:22 +00:00
TOKEN_DEFAULT_DACL * Dacl ;
2008-05-09 17:35:45 +00:00
BOOL ret ;
DWORD i , GLE ;
LPSTR SidString ;
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel ;
2009-05-17 07:05:22 +00:00
ACL * acl ;
2008-05-09 17:35:45 +00:00
/* cygwin-like use case */
SetLastError ( 0xdeadbeef ) ;
ret = OpenProcessToken ( GetCurrentProcess ( ) , MAXIMUM_ALLOWED , & Token ) ;
if ( ! ret & & ( GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED ) )
{
2009-05-17 07:05:22 +00:00
win_skip ( " OpenProcessToken is not implemented \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
ok ( ret , " OpenProcessToken failed with error %d \n " , GetLastError ( ) ) ;
if ( ret )
{
2009-05-17 07:05:22 +00:00
DWORD buf [ 256 ] ; /* GetTokenInformation wants a dword-aligned buffer */
2008-05-09 17:35:45 +00:00
Size = sizeof ( buf ) ;
ret = GetTokenInformation ( Token , TokenUser , ( void * ) buf , Size , & Size ) ;
ok ( ret , " GetTokenInformation failed with error %d \n " , GetLastError ( ) ) ;
Size = sizeof ( ImpersonationLevel ) ;
ret = GetTokenInformation ( Token , TokenImpersonationLevel , & ImpersonationLevel , Size , & Size ) ;
GLE = GetLastError ( ) ;
ok ( ! ret & & ( GLE = = ERROR_INVALID_PARAMETER ) , " GetTokenInformation(TokenImpersonationLevel) on primary token should have failed with ERROR_INVALID_PARAMETER instead of %d \n " , GLE ) ;
CloseHandle ( Token ) ;
}
if ( ! pConvertSidToStringSidA )
{
2009-05-17 07:05:22 +00:00
win_skip ( " ConvertSidToStringSidA is not available \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
SetLastError ( 0xdeadbeef ) ;
2009-05-17 07:05:22 +00:00
ret = OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_ALL_ACCESS , & Token ) ;
2008-05-09 17:35:45 +00:00
ok ( ret , " OpenProcessToken failed with error %d \n " , GetLastError ( ) ) ;
/* groups */
ret = GetTokenInformation ( Token , TokenGroups , NULL , 0 , & Size ) ;
Groups = HeapAlloc ( GetProcessHeap ( ) , 0 , Size ) ;
ret = GetTokenInformation ( Token , TokenGroups , Groups , Size , & Size ) ;
ok ( ret , " GetTokenInformation(TokenGroups) failed with error %d \n " , GetLastError ( ) ) ;
trace ( " TokenGroups: \n " ) ;
for ( i = 0 ; i < Groups - > GroupCount ; i + + )
{
DWORD NameLength = 255 ;
TCHAR Name [ 255 ] ;
DWORD DomainLength = 255 ;
TCHAR Domain [ 255 ] ;
SID_NAME_USE SidNameUse ;
pConvertSidToStringSidA ( Groups - > Groups [ i ] . Sid , & SidString ) ;
Name [ 0 ] = ' \0 ' ;
Domain [ 0 ] = ' \0 ' ;
ret = LookupAccountSid ( NULL , Groups - > Groups [ i ] . Sid , Name , & NameLength , Domain , & DomainLength , & SidNameUse ) ;
if ( ret )
2009-06-22 20:07:32 +00:00
{
trace ( " %s, %s \\ %s use: %d attr: 0x%08x \n " , SidString , Domain , Name , SidNameUse , Groups - > Groups [ i ] . Attributes ) ;
LocalFree ( SidString ) ;
}
else trace ( " attr: 0x%08x LookupAccountSid failed with error %d \n " , Groups - > Groups [ i ] . Attributes , GetLastError ( ) ) ;
2008-05-09 17:35:45 +00:00
}
HeapFree ( GetProcessHeap ( ) , 0 , Groups ) ;
/* user */
ret = GetTokenInformation ( Token , TokenUser , NULL , 0 , & Size ) ;
ok ( ! ret & & ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ) ,
" GetTokenInformation(TokenUser) failed with error %d \n " , GetLastError ( ) ) ;
User = HeapAlloc ( GetProcessHeap ( ) , 0 , Size ) ;
ret = GetTokenInformation ( Token , TokenUser , User , Size , & Size ) ;
ok ( ret ,
" GetTokenInformation(TokenUser) failed with error %d \n " , GetLastError ( ) ) ;
pConvertSidToStringSidA ( User - > User . Sid , & SidString ) ;
trace ( " TokenUser: %s attr: 0x%08x \n " , SidString , User - > User . Attributes ) ;
LocalFree ( SidString ) ;
HeapFree ( GetProcessHeap ( ) , 0 , User ) ;
/* privileges */
ret = GetTokenInformation ( Token , TokenPrivileges , NULL , 0 , & Size ) ;
ok ( ! ret & & ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ) ,
" GetTokenInformation(TokenPrivileges) failed with error %d \n " , GetLastError ( ) ) ;
Privileges = HeapAlloc ( GetProcessHeap ( ) , 0 , Size ) ;
ret = GetTokenInformation ( Token , TokenPrivileges , Privileges , Size , & Size ) ;
ok ( ret ,
" GetTokenInformation(TokenPrivileges) failed with error %d \n " , GetLastError ( ) ) ;
trace ( " TokenPrivileges: \n " ) ;
for ( i = 0 ; i < Privileges - > PrivilegeCount ; i + + )
{
TCHAR Name [ 256 ] ;
DWORD NameLen = sizeof ( Name ) / sizeof ( Name [ 0 ] ) ;
LookupPrivilegeName ( NULL , & Privileges - > Privileges [ i ] . Luid , Name , & NameLen ) ;
trace ( " \t %s, 0x%x \n " , Name , Privileges - > Privileges [ i ] . Attributes ) ;
}
HeapFree ( GetProcessHeap ( ) , 0 , Privileges ) ;
ret = DuplicateToken ( Token , SecurityAnonymous , & ImpersonationToken ) ;
ok ( ret , " DuplicateToken failed with error %d \n " , GetLastError ( ) ) ;
Size = sizeof ( ImpersonationLevel ) ;
ret = GetTokenInformation ( ImpersonationToken , TokenImpersonationLevel , & ImpersonationLevel , Size , & Size ) ;
ok ( ret , " GetTokenInformation(TokenImpersonationLevel) failed with error %d \n " , GetLastError ( ) ) ;
ok ( ImpersonationLevel = = SecurityAnonymous , " ImpersonationLevel should have been SecurityAnonymous instead of %d \n " , ImpersonationLevel ) ;
CloseHandle ( ImpersonationToken ) ;
2009-05-17 07:05:22 +00:00
/* default dacl */
ret = GetTokenInformation ( Token , TokenDefaultDacl , NULL , 0 , & Size ) ;
ok ( ! ret & & ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ) ,
" GetTokenInformation(TokenDefaultDacl) failed with error %u \n " , GetLastError ( ) ) ;
Dacl = HeapAlloc ( GetProcessHeap ( ) , 0 , Size ) ;
ret = GetTokenInformation ( Token , TokenDefaultDacl , Dacl , Size , & Size ) ;
ok ( ret , " GetTokenInformation(TokenDefaultDacl) failed with error %u \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = SetTokenInformation ( Token , TokenDefaultDacl , NULL , 0 ) ;
GLE = GetLastError ( ) ;
ok ( ! ret , " SetTokenInformation(TokenDefaultDacl) succeeded \n " ) ;
ok ( GLE = = ERROR_BAD_LENGTH , " expected ERROR_BAD_LENGTH got %u \n " , GLE ) ;
SetLastError ( 0xdeadbeef ) ;
ret = SetTokenInformation ( Token , TokenDefaultDacl , NULL , Size ) ;
GLE = GetLastError ( ) ;
ok ( ! ret , " SetTokenInformation(TokenDefaultDacl) succeeded \n " ) ;
ok ( GLE = = ERROR_NOACCESS , " expected ERROR_NOACCESS got %u \n " , GLE ) ;
acl = Dacl - > DefaultDacl ;
Dacl - > DefaultDacl = NULL ;
ret = SetTokenInformation ( Token , TokenDefaultDacl , Dacl , Size ) ;
ok ( ret , " SetTokenInformation(TokenDefaultDacl) succeeded \n " ) ;
Size2 = 0 ;
Dacl - > DefaultDacl = ( ACL * ) 0xdeadbeef ;
ret = GetTokenInformation ( Token , TokenDefaultDacl , Dacl , Size , & Size2 ) ;
ok ( ret , " GetTokenInformation(TokenDefaultDacl) failed with error %u \n " , GetLastError ( ) ) ;
ok ( Dacl - > DefaultDacl = = NULL , " expected NULL, got %p \n " , Dacl - > DefaultDacl ) ;
ok ( Size2 = = sizeof ( TOKEN_DEFAULT_DACL ) , " got %u expected sizeof(TOKEN_DEFAULT_DACL) \n " , Size2 ) ;
Dacl - > DefaultDacl = acl ;
ret = SetTokenInformation ( Token , TokenDefaultDacl , Dacl , Size ) ;
ok ( ret , " SetTokenInformation(TokenDefaultDacl) failed with error %u \n " , GetLastError ( ) ) ;
ret = GetTokenInformation ( Token , TokenDefaultDacl , Dacl , Size , & Size2 ) ;
ok ( ret , " GetTokenInformation(TokenDefaultDacl) failed with error %u \n " , GetLastError ( ) ) ;
HeapFree ( GetProcessHeap ( ) , 0 , Dacl ) ;
2008-05-09 17:35:45 +00:00
CloseHandle ( Token ) ;
}
typedef union _MAX_SID
{
SID sid ;
char max [ SECURITY_MAX_SID_SIZE ] ;
} MAX_SID ;
static void test_sid_str ( PSID * sid )
{
char * str_sid ;
BOOL ret = pConvertSidToStringSidA ( sid , & str_sid ) ;
ok ( ret , " ConvertSidToStringSidA() failed: %d \n " , GetLastError ( ) ) ;
if ( ret )
{
char account [ MAX_PATH ] , domain [ MAX_PATH ] ;
SID_NAME_USE use ;
DWORD acc_size = MAX_PATH ;
DWORD dom_size = MAX_PATH ;
ret = LookupAccountSid ( NULL , sid , account , & acc_size , domain , & dom_size , & use ) ;
ok ( ret | | ( ! ret & & ( GetLastError ( ) = = ERROR_NONE_MAPPED ) ) ,
" LookupAccountSid(%s) failed: %d \n " , str_sid , GetLastError ( ) ) ;
if ( ret )
trace ( " %s %s \\ %s %d \n " , str_sid , domain , account , use ) ;
else if ( GetLastError ( ) = = ERROR_NONE_MAPPED )
trace ( " %s couldn't be mapped \n " , str_sid ) ;
LocalFree ( str_sid ) ;
}
}
struct well_known_sid_value
{
BOOL without_domain ;
const char * sid_string ;
} well_known_sid_values [ ] = {
/* 0 */ { TRUE , " S-1-0-0 " } , { TRUE , " S-1-1-0 " } , { TRUE , " S-1-2-0 " } , { TRUE , " S-1-3-0 " } ,
/* 4 */ { TRUE , " S-1-3-1 " } , { TRUE , " S-1-3-2 " } , { TRUE , " S-1-3-3 " } , { TRUE , " S-1-5 " } ,
/* 8 */ { FALSE , " S-1-5-1 " } , { TRUE , " S-1-5-2 " } , { TRUE , " S-1-5-3 " } , { TRUE , " S-1-5-4 " } ,
/* 12 */ { TRUE , " S-1-5-6 " } , { TRUE , " S-1-5-7 " } , { TRUE , " S-1-5-8 " } , { TRUE , " S-1-5-9 " } ,
/* 16 */ { TRUE , " S-1-5-10 " } , { TRUE , " S-1-5-11 " } , { TRUE , " S-1-5-12 " } , { TRUE , " S-1-5-13 " } ,
/* 20 */ { TRUE , " S-1-5-14 " } , { FALSE , NULL } , { TRUE , " S-1-5-18 " } , { TRUE , " S-1-5-19 " } ,
/* 24 */ { TRUE , " S-1-5-20 " } , { TRUE , " S-1-5-32 " } ,
/* 26 */ { FALSE , " S-1-5-32-544 " } , { TRUE , " S-1-5-32-545 " } , { TRUE , " S-1-5-32-546 " } ,
/* 29 */ { TRUE , " S-1-5-32-547 " } , { TRUE , " S-1-5-32-548 " } , { TRUE , " S-1-5-32-549 " } ,
/* 32 */ { TRUE , " S-1-5-32-550 " } , { TRUE , " S-1-5-32-551 " } , { TRUE , " S-1-5-32-552 " } ,
/* 35 */ { TRUE , " S-1-5-32-554 " } , { TRUE , " S-1-5-32-555 " } , { TRUE , " S-1-5-32-556 " } ,
/* 38 */ { FALSE , " S-1-5-21-12-23-34-45-56-500 " } , { FALSE , " S-1-5-21-12-23-34-45-56-501 " } ,
/* 40 */ { FALSE , " S-1-5-21-12-23-34-45-56-502 " } , { FALSE , " S-1-5-21-12-23-34-45-56-512 " } ,
/* 42 */ { FALSE , " S-1-5-21-12-23-34-45-56-513 " } , { FALSE , " S-1-5-21-12-23-34-45-56-514 " } ,
/* 44 */ { FALSE , " S-1-5-21-12-23-34-45-56-515 " } , { FALSE , " S-1-5-21-12-23-34-45-56-516 " } ,
/* 46 */ { FALSE , " S-1-5-21-12-23-34-45-56-517 " } , { FALSE , " S-1-5-21-12-23-34-45-56-518 " } ,
/* 48 */ { FALSE , " S-1-5-21-12-23-34-45-56-519 " } , { FALSE , " S-1-5-21-12-23-34-45-56-520 " } ,
/* 50 */ { FALSE , " S-1-5-21-12-23-34-45-56-553 " } ,
/* Added in Windows Server 2003 */
/* 51 */ { TRUE , " S-1-5-64-10 " } , { TRUE , " S-1-5-64-21 " } , { TRUE , " S-1-5-64-14 " } ,
/* 54 */ { TRUE , " S-1-5-15 " } , { TRUE , " S-1-5-1000 " } , { FALSE , " S-1-5-32-557 " } ,
/* 57 */ { TRUE , " S-1-5-32-558 " } , { TRUE , " S-1-5-32-559 " } , { TRUE , " S-1-5-32-560 " } ,
/* 60 */ { TRUE , " S-1-5-32-561 " } , { TRUE , " S-1-5-32-562 " } ,
/* Added in Windows Vista: */
/* 62 */ { TRUE , " S-1-5-32-568 " } ,
/* 63 */ { TRUE , " S-1-5-17 " } , { FALSE , " S-1-5-32-569 " } , { TRUE , " S-1-16-0 " } ,
/* 66 */ { TRUE , " S-1-16-4096 " } , { TRUE , " S-1-16-8192 " } , { TRUE , " S-1-16-12288 " } ,
/* 69 */ { TRUE , " S-1-16-16384 " } , { TRUE , " S-1-5-33 " } , { TRUE , " S-1-3-4 " } ,
/* 72 */ { FALSE , " S-1-5-21-12-23-34-45-56-571 " } , { FALSE , " S-1-5-21-12-23-34-45-56-572 " } ,
/* 74 */ { TRUE , " S-1-5-22 " } , { FALSE , " S-1-5-21-12-23-34-45-56-521 " } , { TRUE , " S-1-5-32-573 " }
} ;
2009-02-08 09:32:24 +00:00
static void test_CreateWellKnownSid ( void )
2008-05-09 17:35:45 +00:00
{
SID_IDENTIFIER_AUTHORITY ident = { SECURITY_NT_AUTHORITY } ;
2009-05-17 07:05:22 +00:00
PSID domainsid , sid ;
DWORD size , error ;
BOOL ret ;
2008-05-09 17:35:45 +00:00
int i ;
if ( ! pCreateWellKnownSid )
{
2009-05-17 07:05:22 +00:00
win_skip ( " CreateWellKnownSid not available \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
2009-05-17 07:05:22 +00:00
size = 0 ;
SetLastError ( 0xdeadbeef ) ;
ret = pCreateWellKnownSid ( WinInteractiveSid , NULL , NULL , & size ) ;
error = GetLastError ( ) ;
ok ( ! ret , " CreateWellKnownSid succeeded \n " ) ;
ok ( error = = ERROR_INSUFFICIENT_BUFFER , " expected ERROR_INSUFFICIENT_BUFFER, got %u \n " , error ) ;
ok ( size , " expected size > 0 \n " ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pCreateWellKnownSid ( WinInteractiveSid , NULL , NULL , & size ) ;
error = GetLastError ( ) ;
ok ( ! ret , " CreateWellKnownSid succeeded \n " ) ;
ok ( error = = ERROR_INVALID_PARAMETER , " expected ERROR_INVALID_PARAMETER, got %u \n " , error ) ;
sid = HeapAlloc ( GetProcessHeap ( ) , 0 , size ) ;
ret = pCreateWellKnownSid ( WinInteractiveSid , NULL , sid , & size ) ;
ok ( ret , " CreateWellKnownSid failed %u \n " , GetLastError ( ) ) ;
HeapFree ( GetProcessHeap ( ) , 0 , sid ) ;
2008-05-09 17:35:45 +00:00
/* a domain sid usually have three subauthorities but we test that CreateWellKnownSid doesn't check it */
AllocateAndInitializeSid ( & ident , 6 , SECURITY_NT_NON_UNIQUE , 12 , 23 , 34 , 45 , 56 , 0 , 0 , & domainsid ) ;
for ( i = 0 ; i < sizeof ( well_known_sid_values ) / sizeof ( well_known_sid_values [ 0 ] ) ; i + + )
{
struct well_known_sid_value * value = & well_known_sid_values [ i ] ;
char sid_buffer [ SECURITY_MAX_SID_SIZE ] ;
LPSTR str ;
DWORD cb ;
if ( value - > sid_string = = NULL )
continue ;
if ( i > WinAccountRasAndIasServersSid )
{
/* These SIDs aren't implemented by all Windows versions - detect it and break the loop */
cb = sizeof ( sid_buffer ) ;
if ( ! pCreateWellKnownSid ( i , domainsid , sid_buffer , & cb ) )
{
skip ( " Well known SIDs starting from %d are not implemented \n " , i ) ;
break ;
}
}
cb = sizeof ( sid_buffer ) ;
ok ( pCreateWellKnownSid ( i , value - > without_domain ? NULL : domainsid , sid_buffer , & cb ) , " Couldn't create well known sid %d \n " , i ) ;
expect_eq ( GetSidLengthRequired ( * GetSidSubAuthorityCount ( sid_buffer ) ) , cb , DWORD , " %d " ) ;
ok ( IsValidSid ( sid_buffer ) , " The sid is not valid \n " ) ;
ok ( pConvertSidToStringSidA ( sid_buffer , & str ) , " Couldn't convert SID to string \n " ) ;
ok ( strcmp ( str , value - > sid_string ) = = 0 , " SID mismatch - expected %s, got %s \n " ,
value - > sid_string , str ) ;
LocalFree ( str ) ;
if ( value - > without_domain )
{
char buf2 [ SECURITY_MAX_SID_SIZE ] ;
cb = sizeof ( buf2 ) ;
ok ( pCreateWellKnownSid ( i , domainsid , buf2 , & cb ) , " Couldn't create well known sid %d with optional domain \n " , i ) ;
expect_eq ( GetSidLengthRequired ( * GetSidSubAuthorityCount ( sid_buffer ) ) , cb , DWORD , " %d " ) ;
ok ( memcmp ( buf2 , sid_buffer , cb ) = = 0 , " SID create with domain is different than without (%d) \n " , i ) ;
}
}
}
static void test_LookupAccountSid ( void )
{
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY } ;
2009-05-17 07:05:22 +00:00
CHAR accountA [ MAX_PATH ] , domainA [ MAX_PATH ] , usernameA [ MAX_PATH ] ;
DWORD acc_sizeA , dom_sizeA , user_sizeA ;
2008-05-09 17:35:45 +00:00
DWORD real_acc_sizeA , real_dom_sizeA ;
WCHAR accountW [ MAX_PATH ] , domainW [ MAX_PATH ] ;
DWORD acc_sizeW , dom_sizeW ;
DWORD real_acc_sizeW , real_dom_sizeW ;
PSID pUsersSid = NULL ;
SID_NAME_USE use ;
BOOL ret ;
2009-05-17 07:05:22 +00:00
DWORD size , cbti = 0 ;
2008-05-09 17:35:45 +00:00
MAX_SID max_sid ;
CHAR * str_sidA ;
int i ;
2009-05-17 07:05:22 +00:00
HANDLE hToken ;
PTOKEN_USER ptiUser = NULL ;
2008-05-09 17:35:45 +00:00
/* native windows crashes if account size, domain size, or name use is NULL */
ret = AllocateAndInitializeSid ( & SIDAuthNT , 2 , SECURITY_BUILTIN_DOMAIN_RID ,
DOMAIN_ALIAS_RID_USERS , 0 , 0 , 0 , 0 , 0 , 0 , & pUsersSid ) ;
ok ( ret | | ( GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED ) ,
" AllocateAndInitializeSid failed with error %d \n " , GetLastError ( ) ) ;
/* not running on NT so give up */
if ( ! ret & & ( GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED ) )
return ;
real_acc_sizeA = MAX_PATH ;
real_dom_sizeA = MAX_PATH ;
ret = LookupAccountSidA ( NULL , pUsersSid , accountA , & real_acc_sizeA , domainA , & real_dom_sizeA , & use ) ;
ok ( ret , " LookupAccountSidA() Expected TRUE, got FALSE \n " ) ;
/* try NULL account */
acc_sizeA = MAX_PATH ;
dom_sizeA = MAX_PATH ;
ret = LookupAccountSidA ( NULL , pUsersSid , NULL , & acc_sizeA , domainA , & dom_sizeA , & use ) ;
ok ( ret , " LookupAccountSidA() Expected TRUE, got FALSE \n " ) ;
/* try NULL domain */
acc_sizeA = MAX_PATH ;
dom_sizeA = MAX_PATH ;
ret = LookupAccountSidA ( NULL , pUsersSid , accountA , & acc_sizeA , NULL , & dom_sizeA , & use ) ;
ok ( ret , " LookupAccountSidA() Expected TRUE, got FALSE \n " ) ;
/* try a small account buffer */
acc_sizeA = 1 ;
dom_sizeA = MAX_PATH ;
accountA [ 0 ] = 0 ;
ret = LookupAccountSidA ( NULL , pUsersSid , accountA , & acc_sizeA , domainA , & dom_sizeA , & use ) ;
ok ( ! ret , " LookupAccountSidA() Expected FALSE got TRUE \n " ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %u \n " , GetLastError ( ) ) ;
/* try a 0 sized account buffer */
acc_sizeA = 0 ;
dom_sizeA = MAX_PATH ;
accountA [ 0 ] = 0 ;
ret = LookupAccountSidA ( NULL , pUsersSid , accountA , & acc_sizeA , domainA , & dom_sizeA , & use ) ;
/* this can fail or succeed depending on OS version but the size will always be returned */
ok ( acc_sizeA = = real_acc_sizeA + 1 ,
" LookupAccountSidA() Expected acc_size = %u, got %u \n " ,
real_acc_sizeA + 1 , acc_sizeA ) ;
/* try a 0 sized account buffer */
acc_sizeA = 0 ;
dom_sizeA = MAX_PATH ;
ret = LookupAccountSidA ( NULL , pUsersSid , NULL , & acc_sizeA , domainA , & dom_sizeA , & use ) ;
/* this can fail or succeed depending on OS version but the size will always be returned */
ok ( acc_sizeA = = real_acc_sizeA + 1 ,
" LookupAccountSid() Expected acc_size = %u, got %u \n " ,
real_acc_sizeA + 1 , acc_sizeA ) ;
/* try a small domain buffer */
dom_sizeA = 1 ;
acc_sizeA = MAX_PATH ;
accountA [ 0 ] = 0 ;
ret = LookupAccountSidA ( NULL , pUsersSid , accountA , & acc_sizeA , domainA , & dom_sizeA , & use ) ;
ok ( ! ret , " LookupAccountSidA() Expected FALSE got TRUE \n " ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %u \n " , GetLastError ( ) ) ;
/* try a 0 sized domain buffer */
dom_sizeA = 0 ;
acc_sizeA = MAX_PATH ;
accountA [ 0 ] = 0 ;
ret = LookupAccountSidA ( NULL , pUsersSid , accountA , & acc_sizeA , domainA , & dom_sizeA , & use ) ;
/* this can fail or succeed depending on OS version but the size will always be returned */
ok ( dom_sizeA = = real_dom_sizeA + 1 ,
" LookupAccountSidA() Expected dom_size = %u, got %u \n " ,
real_dom_sizeA + 1 , dom_sizeA ) ;
/* try a 0 sized domain buffer */
dom_sizeA = 0 ;
acc_sizeA = MAX_PATH ;
ret = LookupAccountSidA ( NULL , pUsersSid , accountA , & acc_sizeA , NULL , & dom_sizeA , & use ) ;
/* this can fail or succeed depending on OS version but the size will always be returned */
ok ( dom_sizeA = = real_dom_sizeA + 1 ,
" LookupAccountSidA() Expected dom_size = %u, got %u \n " ,
real_dom_sizeA + 1 , dom_sizeA ) ;
real_acc_sizeW = MAX_PATH ;
real_dom_sizeW = MAX_PATH ;
ret = LookupAccountSidW ( NULL , pUsersSid , accountW , & real_acc_sizeW , domainW , & real_dom_sizeW , & use ) ;
ok ( ret , " LookupAccountSidW() Expected TRUE, got FALSE \n " ) ;
2008-12-09 19:26:45 +00:00
/* try an invalid system name */
real_acc_sizeA = MAX_PATH ;
real_dom_sizeA = MAX_PATH ;
ret = LookupAccountSidA ( " deepthought " , pUsersSid , accountA , & real_acc_sizeA , domainA , & real_dom_sizeA , & use ) ;
ok ( ! ret , " LookupAccountSidA() Expected FALSE got TRUE \n " ) ;
ok ( GetLastError ( ) = = RPC_S_SERVER_UNAVAILABLE | | GetLastError ( ) = = RPC_S_INVALID_NET_ADDR /* Vista */ ,
" LookupAccountSidA() Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %u \n " , GetLastError ( ) ) ;
2008-05-09 17:35:45 +00:00
/* native windows crashes if domainW or accountW is NULL */
/* try a small account buffer */
acc_sizeW = 1 ;
dom_sizeW = MAX_PATH ;
accountW [ 0 ] = 0 ;
ret = LookupAccountSidW ( NULL , pUsersSid , accountW , & acc_sizeW , domainW , & dom_sizeW , & use ) ;
ok ( ! ret , " LookupAccountSidW() Expected FALSE got TRUE \n " ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %u \n " , GetLastError ( ) ) ;
/* try a 0 sized account buffer */
acc_sizeW = 0 ;
dom_sizeW = MAX_PATH ;
accountW [ 0 ] = 0 ;
ret = LookupAccountSidW ( NULL , pUsersSid , accountW , & acc_sizeW , domainW , & dom_sizeW , & use ) ;
/* this can fail or succeed depending on OS version but the size will always be returned */
ok ( acc_sizeW = = real_acc_sizeW + 1 ,
" LookupAccountSidW() Expected acc_size = %u, got %u \n " ,
real_acc_sizeW + 1 , acc_sizeW ) ;
/* try a 0 sized account buffer */
acc_sizeW = 0 ;
dom_sizeW = MAX_PATH ;
ret = LookupAccountSidW ( NULL , pUsersSid , NULL , & acc_sizeW , domainW , & dom_sizeW , & use ) ;
/* this can fail or succeed depending on OS version but the size will always be returned */
ok ( acc_sizeW = = real_acc_sizeW + 1 ,
" LookupAccountSidW() Expected acc_size = %u, got %u \n " ,
real_acc_sizeW + 1 , acc_sizeW ) ;
/* try a small domain buffer */
dom_sizeW = 1 ;
acc_sizeW = MAX_PATH ;
accountW [ 0 ] = 0 ;
ret = LookupAccountSidW ( NULL , pUsersSid , accountW , & acc_sizeW , domainW , & dom_sizeW , & use ) ;
ok ( ! ret , " LookupAccountSidW() Expected FALSE got TRUE \n " ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %u \n " , GetLastError ( ) ) ;
/* try a 0 sized domain buffer */
dom_sizeW = 0 ;
acc_sizeW = MAX_PATH ;
accountW [ 0 ] = 0 ;
ret = LookupAccountSidW ( NULL , pUsersSid , accountW , & acc_sizeW , domainW , & dom_sizeW , & use ) ;
/* this can fail or succeed depending on OS version but the size will always be returned */
ok ( dom_sizeW = = real_dom_sizeW + 1 ,
" LookupAccountSidW() Expected dom_size = %u, got %u \n " ,
real_dom_sizeW + 1 , dom_sizeW ) ;
/* try a 0 sized domain buffer */
dom_sizeW = 0 ;
acc_sizeW = MAX_PATH ;
ret = LookupAccountSidW ( NULL , pUsersSid , accountW , & acc_sizeW , NULL , & dom_sizeW , & use ) ;
/* this can fail or succeed depending on OS version but the size will always be returned */
ok ( dom_sizeW = = real_dom_sizeW + 1 ,
" LookupAccountSidW() Expected dom_size = %u, got %u \n " ,
real_dom_sizeW + 1 , dom_sizeW ) ;
FreeSid ( pUsersSid ) ;
2009-05-17 07:05:22 +00:00
/* Test LookupAccountSid with Sid retrieved from token information.
This assumes this process is running under the account of the current user . */
ret = OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_QUERY | TOKEN_DUPLICATE , & hToken ) ;
ret = GetTokenInformation ( hToken , TokenUser , NULL , 0 , & cbti ) ;
ptiUser = ( PTOKEN_USER ) HeapAlloc ( GetProcessHeap ( ) , 0 , cbti ) ;
if ( GetTokenInformation ( hToken , TokenUser , ptiUser , cbti , & cbti ) )
{
acc_sizeA = dom_sizeA = MAX_PATH ;
ret = LookupAccountSidA ( NULL , ptiUser - > User . Sid , accountA , & acc_sizeA , domainA , & dom_sizeA , & use ) ;
ok ( ret , " LookupAccountSidA() Expected TRUE, got FALSE \n " ) ;
user_sizeA = MAX_PATH ;
ret = GetUserNameA ( usernameA , & user_sizeA ) ;
ok ( ret , " GetUserNameA() Expected TRUE, got FALSE \n " ) ;
todo_wine
{
ok ( lstrcmpA ( usernameA , accountA ) = = 0 , " LookupAccountSidA() Expected account name: %s got: %s \n " , usernameA , accountA ) ;
}
}
HeapFree ( GetProcessHeap ( ) , 0 , ptiUser ) ;
2008-05-09 17:35:45 +00:00
if ( pCreateWellKnownSid & & pConvertSidToStringSidA )
{
trace ( " Well Known SIDs: \n " ) ;
for ( i = 0 ; i < = 60 ; i + + )
{
size = SECURITY_MAX_SID_SIZE ;
if ( pCreateWellKnownSid ( i , NULL , & max_sid . sid , & size ) )
{
if ( pConvertSidToStringSidA ( & max_sid . sid , & str_sidA ) )
{
acc_sizeA = MAX_PATH ;
dom_sizeA = MAX_PATH ;
if ( LookupAccountSidA ( NULL , & max_sid . sid , accountA , & acc_sizeA , domainA , & dom_sizeA , & use ) )
trace ( " %d: %s %s \\ %s %d \n " , i , str_sidA , domainA , accountA , use ) ;
LocalFree ( str_sidA ) ;
}
}
else
{
if ( GetLastError ( ) ! = ERROR_INVALID_PARAMETER )
trace ( " CreateWellKnownSid(%d) failed: %d \n " , i , GetLastError ( ) ) ;
else
trace ( " %d: not supported \n " , i ) ;
}
}
pLsaQueryInformationPolicy = ( fnLsaQueryInformationPolicy ) GetProcAddress ( hmod , " LsaQueryInformationPolicy " ) ;
pLsaOpenPolicy = ( fnLsaOpenPolicy ) GetProcAddress ( hmod , " LsaOpenPolicy " ) ;
pLsaFreeMemory = ( fnLsaFreeMemory ) GetProcAddress ( hmod , " LsaFreeMemory " ) ;
pLsaClose = ( fnLsaClose ) GetProcAddress ( hmod , " LsaClose " ) ;
if ( pLsaQueryInformationPolicy & & pLsaOpenPolicy & & pLsaFreeMemory & & pLsaClose )
{
NTSTATUS status ;
LSA_HANDLE handle ;
LSA_OBJECT_ATTRIBUTES object_attributes ;
ZeroMemory ( & object_attributes , sizeof ( object_attributes ) ) ;
object_attributes . Length = sizeof ( object_attributes ) ;
status = pLsaOpenPolicy ( NULL , & object_attributes , POLICY_ALL_ACCESS , & handle ) ;
ok ( status = = STATUS_SUCCESS | | status = = STATUS_ACCESS_DENIED ,
" LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08x \n " , status ) ;
/* try a more restricted access mask if necessary */
if ( status = = STATUS_ACCESS_DENIED ) {
trace ( " LsaOpenPolicy(POLICY_ALL_ACCESS) failed, trying POLICY_VIEW_LOCAL_INFORMATION \n " ) ;
status = pLsaOpenPolicy ( NULL , & object_attributes , POLICY_VIEW_LOCAL_INFORMATION , & handle ) ;
ok ( status = = STATUS_SUCCESS , " LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) returned 0x%08x \n " , status ) ;
}
if ( status = = STATUS_SUCCESS )
{
PPOLICY_ACCOUNT_DOMAIN_INFO info ;
status = pLsaQueryInformationPolicy ( handle , PolicyAccountDomainInformation , ( PVOID * ) & info ) ;
ok ( status = = STATUS_SUCCESS , " LsaQueryInformationPolicy() failed, returned 0x%08x \n " , status ) ;
if ( status = = STATUS_SUCCESS )
{
ok ( info - > DomainSid ! = 0 , " LsaQueryInformationPolicy(PolicyAccountDomainInformation) missing SID \n " ) ;
if ( info - > DomainSid )
{
int count = * GetSidSubAuthorityCount ( info - > DomainSid ) ;
CopySid ( GetSidLengthRequired ( count ) , & max_sid , info - > DomainSid ) ;
test_sid_str ( ( PSID ) & max_sid . sid ) ;
max_sid . sid . SubAuthority [ count ] = DOMAIN_USER_RID_ADMIN ;
max_sid . sid . SubAuthorityCount = count + 1 ;
test_sid_str ( ( PSID ) & max_sid . sid ) ;
max_sid . sid . SubAuthority [ count ] = DOMAIN_USER_RID_GUEST ;
test_sid_str ( ( PSID ) & max_sid . sid ) ;
max_sid . sid . SubAuthority [ count ] = DOMAIN_GROUP_RID_ADMINS ;
test_sid_str ( ( PSID ) & max_sid . sid ) ;
max_sid . sid . SubAuthority [ count ] = DOMAIN_GROUP_RID_USERS ;
test_sid_str ( ( PSID ) & max_sid . sid ) ;
max_sid . sid . SubAuthority [ count ] = DOMAIN_GROUP_RID_GUESTS ;
test_sid_str ( ( PSID ) & max_sid . sid ) ;
max_sid . sid . SubAuthority [ count ] = DOMAIN_GROUP_RID_COMPUTERS ;
test_sid_str ( ( PSID ) & max_sid . sid ) ;
max_sid . sid . SubAuthority [ count ] = DOMAIN_GROUP_RID_CONTROLLERS ;
test_sid_str ( ( PSID ) & max_sid . sid ) ;
max_sid . sid . SubAuthority [ count ] = DOMAIN_GROUP_RID_CERT_ADMINS ;
test_sid_str ( ( PSID ) & max_sid . sid ) ;
max_sid . sid . SubAuthority [ count ] = DOMAIN_GROUP_RID_SCHEMA_ADMINS ;
test_sid_str ( ( PSID ) & max_sid . sid ) ;
max_sid . sid . SubAuthority [ count ] = DOMAIN_GROUP_RID_ENTERPRISE_ADMINS ;
test_sid_str ( ( PSID ) & max_sid . sid ) ;
max_sid . sid . SubAuthority [ count ] = DOMAIN_GROUP_RID_POLICY_ADMINS ;
test_sid_str ( ( PSID ) & max_sid . sid ) ;
max_sid . sid . SubAuthority [ count ] = DOMAIN_ALIAS_RID_RAS_SERVERS ;
test_sid_str ( ( PSID ) & max_sid . sid ) ;
max_sid . sid . SubAuthority [ count ] = 1000 ; /* first user account */
test_sid_str ( ( PSID ) & max_sid . sid ) ;
}
pLsaFreeMemory ( ( LPVOID ) info ) ;
}
status = pLsaClose ( handle ) ;
ok ( status = = STATUS_SUCCESS , " LsaClose() failed, returned 0x%08x \n " , status ) ;
}
}
}
}
2009-05-17 07:05:22 +00:00
static BOOL get_sid_info ( PSID psid , LPSTR * user , LPSTR * dom )
2008-05-09 17:35:45 +00:00
{
static CHAR account [ UNLEN + 1 ] ;
static CHAR domain [ UNLEN + 1 ] ;
DWORD size , dom_size ;
SID_NAME_USE use ;
* user = account ;
* dom = domain ;
size = dom_size = UNLEN + 1 ;
account [ 0 ] = ' \0 ' ;
domain [ 0 ] = ' \0 ' ;
2009-05-17 07:05:22 +00:00
SetLastError ( 0xdeadbeef ) ;
return LookupAccountSidA ( NULL , psid , account , & size , domain , & dom_size , & use ) ;
}
static void check_wellknown_name ( const char * name , WELL_KNOWN_SID_TYPE result )
{
SID_IDENTIFIER_AUTHORITY ident = { SECURITY_NT_AUTHORITY } ;
PSID domainsid ;
char wk_sid [ SECURITY_MAX_SID_SIZE ] ;
DWORD cb ;
DWORD sid_size , domain_size ;
SID_NAME_USE sid_use ;
LPSTR domain , account , sid_domain , wk_domain , wk_account ;
PSID psid ;
BOOL ret , ret2 ;
sid_size = 0 ;
domain_size = 0 ;
ret = LookupAccountNameA ( NULL , name , NULL , & sid_size , NULL , & domain_size , & sid_use ) ;
psid = HeapAlloc ( GetProcessHeap ( ) , 0 , sid_size ) ;
domain = HeapAlloc ( GetProcessHeap ( ) , 0 , domain_size ) ;
ret = LookupAccountNameA ( NULL , name , psid , & sid_size , domain , & domain_size , & sid_use ) ;
if ( ! result )
{
ok ( ! ret , " %s Should have failed to lookup account name \n " , name ) ;
goto cleanup ;
}
AllocateAndInitializeSid ( & ident , 6 , SECURITY_NT_NON_UNIQUE , 12 , 23 , 34 , 45 , 56 , 0 , 0 , & domainsid ) ;
cb = sizeof ( wk_sid ) ;
if ( ! pCreateWellKnownSid ( result , domainsid , wk_sid , & cb ) )
{
win_skip ( " SID %i is not available on the system \n " , result ) ;
goto cleanup ;
}
ret2 = get_sid_info ( wk_sid , & wk_account , & wk_domain ) ;
if ( ! ret2 & & GetLastError ( ) = = ERROR_NONE_MAPPED )
{
win_skip ( " CreateWellKnownSid() succeeded but the account '%s' is not present (W2K) \n " , name ) ;
goto cleanup ;
}
get_sid_info ( psid , & account , & sid_domain ) ;
ok ( ret , " Failed to lookup account name %s \n " , name ) ;
ok ( sid_size ! = 0 , " sid_size was zero \n " ) ;
ok ( EqualSid ( psid , wk_sid ) , " (%s) Sids fail to match well known sid! \n " , name ) ;
ok ( ! lstrcmp ( account , wk_account ) , " Expected %s , got %s \n " , account , wk_account ) ;
ok ( ! lstrcmp ( domain , wk_domain ) , " Expected %s, got %s \n " , wk_domain , domain ) ;
ok ( sid_use = = SidTypeWellKnownGroup , " Expected Use (5), got %d \n " , sid_use ) ;
cleanup :
HeapFree ( GetProcessHeap ( ) , 0 , psid ) ;
HeapFree ( GetProcessHeap ( ) , 0 , domain ) ;
2008-05-09 17:35:45 +00:00
}
static void test_LookupAccountName ( void )
{
DWORD sid_size , domain_size , user_size ;
DWORD sid_save , domain_save ;
CHAR user_name [ UNLEN + 1 ] ;
2009-02-08 09:32:24 +00:00
CHAR computer_name [ UNLEN + 1 ] ;
2008-05-09 17:35:45 +00:00
SID_NAME_USE sid_use ;
LPSTR domain , account , sid_dom ;
PSID psid ;
BOOL ret ;
/* native crashes if (assuming all other parameters correct):
* - peUse is NULL
* - Sid is NULL and cbSid is > 0
* - cbSid or cchReferencedDomainName are NULL
* - ReferencedDomainName is NULL and cchReferencedDomainName is the correct size
*/
user_size = UNLEN + 1 ;
SetLastError ( 0xdeadbeef ) ;
ret = GetUserNameA ( user_name , & user_size ) ;
if ( ! ret & & ( GetLastError ( ) = = ERROR_NOT_LOGGED_ON ) )
{
/* Probably on win9x where the user used 'Cancel' instead of properly logging in */
skip ( " Cannot get the user name (win9x and not logged in properly) \n " ) ;
return ;
}
ok ( ret , " Failed to get user name : %d \n " , GetLastError ( ) ) ;
/* get sizes */
sid_size = 0 ;
domain_size = 0 ;
sid_use = 0xcafebabe ;
SetLastError ( 0xdeadbeef ) ;
ret = LookupAccountNameA ( NULL , user_name , NULL , & sid_size , NULL , & domain_size , & sid_use ) ;
if ( ! ret & & ( GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED ) )
{
2009-05-17 07:05:22 +00:00
win_skip ( " LookupAccountNameA is not implemented \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
ok ( ! ret , " Expected 0, got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" Expected ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
ok ( sid_size ! = 0 , " Expected non-zero sid size \n " ) ;
ok ( domain_size ! = 0 , " Expected non-zero domain size \n " ) ;
ok ( sid_use = = 0xcafebabe , " Expected 0xcafebabe, got %d \n " , sid_use ) ;
sid_save = sid_size ;
domain_save = domain_size ;
psid = HeapAlloc ( GetProcessHeap ( ) , 0 , sid_size ) ;
domain = HeapAlloc ( GetProcessHeap ( ) , 0 , domain_size ) ;
/* try valid account name */
ret = LookupAccountNameA ( NULL , user_name , psid , & sid_size , domain , & domain_size , & sid_use ) ;
get_sid_info ( psid , & account , & sid_dom ) ;
ok ( ret , " Failed to lookup account name \n " ) ;
ok ( sid_size = = GetLengthSid ( psid ) , " Expected %d, got %d \n " , GetLengthSid ( psid ) , sid_size ) ;
todo_wine
{
ok ( ! lstrcmp ( account , user_name ) , " Expected %s, got %s \n " , user_name , account ) ;
ok ( ! lstrcmp ( domain , sid_dom ) , " Expected %s, got %s \n " , sid_dom , domain ) ;
}
2008-12-09 19:26:45 +00:00
ok ( domain_size = = domain_save - 1 , " Expected %d, got %d \n " , domain_save - 1 , domain_size ) ;
ok ( lstrlen ( domain ) = = domain_size , " Expected %d, got %d \n " , lstrlen ( domain ) , domain_size ) ;
ok ( sid_use = = SidTypeUser , " Expected SidTypeUser (%d), got %d \n " , SidTypeUser , sid_use ) ;
2008-05-09 17:35:45 +00:00
domain_size = domain_save ;
sid_size = sid_save ;
if ( PRIMARYLANGID ( LANGIDFROMLCID ( GetThreadLocale ( ) ) ) ! = LANG_ENGLISH )
{
skip ( " Non-english locale (test with hardcoded 'Everyone') \n " ) ;
}
else
{
ret = LookupAccountNameA ( NULL , " Everyone " , psid , & sid_size , domain , & domain_size , & sid_use ) ;
get_sid_info ( psid , & account , & sid_dom ) ;
ok ( ret , " Failed to lookup account name \n " ) ;
ok ( sid_size ! = 0 , " sid_size was zero \n " ) ;
ok ( ! lstrcmp ( account , " Everyone " ) , " Expected Everyone, got %s \n " , account ) ;
ok ( ! lstrcmp ( domain , sid_dom ) , " Expected %s, got %s \n " , sid_dom , domain ) ;
ok ( domain_size = = 0 , " Expected 0, got %d \n " , domain_size ) ;
ok ( lstrlen ( domain ) = = domain_size , " Expected %d, got %d \n " , lstrlen ( domain ) , domain_size ) ;
2008-12-09 19:26:45 +00:00
ok ( sid_use = = SidTypeWellKnownGroup , " Expected SidTypeWellKnownGroup (%d), got %d \n " , SidTypeWellKnownGroup , sid_use ) ;
2008-05-09 17:35:45 +00:00
domain_size = domain_save ;
}
/* NULL Sid with zero sid size */
SetLastError ( 0xdeadbeef ) ;
sid_size = 0 ;
ret = LookupAccountNameA ( NULL , user_name , NULL , & sid_size , domain , & domain_size , & sid_use ) ;
ok ( ! ret , " Expected 0, got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" Expected ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
ok ( sid_size = = sid_save , " Expected %d, got %d \n " , sid_save , sid_size ) ;
ok ( domain_size = = domain_save , " Expected %d, got %d \n " , domain_save , domain_size ) ;
/* try cchReferencedDomainName - 1 */
SetLastError ( 0xdeadbeef ) ;
domain_size - - ;
ret = LookupAccountNameA ( NULL , user_name , NULL , & sid_size , domain , & domain_size , & sid_use ) ;
ok ( ! ret , " Expected 0, got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" Expected ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
ok ( sid_size = = sid_save , " Expected %d, got %d \n " , sid_save , sid_size ) ;
ok ( domain_size = = domain_save , " Expected %d, got %d \n " , domain_save , domain_size ) ;
/* NULL ReferencedDomainName with zero domain name size */
SetLastError ( 0xdeadbeef ) ;
domain_size = 0 ;
ret = LookupAccountNameA ( NULL , user_name , psid , & sid_size , NULL , & domain_size , & sid_use ) ;
ok ( ! ret , " Expected 0, got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" Expected ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
ok ( sid_size = = sid_save , " Expected %d, got %d \n " , sid_save , sid_size ) ;
ok ( domain_size = = domain_save , " Expected %d, got %d \n " , domain_save , domain_size ) ;
HeapFree ( GetProcessHeap ( ) , 0 , psid ) ;
HeapFree ( GetProcessHeap ( ) , 0 , domain ) ;
/* get sizes for NULL account name */
sid_size = 0 ;
domain_size = 0 ;
sid_use = 0xcafebabe ;
SetLastError ( 0xdeadbeef ) ;
ret = LookupAccountNameA ( NULL , NULL , NULL , & sid_size , NULL , & domain_size , & sid_use ) ;
2009-02-08 09:32:24 +00:00
if ( ! ret & & GetLastError ( ) = = ERROR_NONE_MAPPED )
win_skip ( " NULL account name doesn't work on NT4 \n " ) ;
else
2008-05-09 17:35:45 +00:00
{
2008-12-09 19:26:45 +00:00
ok ( ! ret , " Expected 0, got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" Expected ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
ok ( sid_size ! = 0 , " Expected non-zero sid size \n " ) ;
ok ( domain_size ! = 0 , " Expected non-zero domain size \n " ) ;
ok ( sid_use = = 0xcafebabe , " Expected 0xcafebabe, got %d \n " , sid_use ) ;
psid = HeapAlloc ( GetProcessHeap ( ) , 0 , sid_size ) ;
domain = HeapAlloc ( GetProcessHeap ( ) , 0 , domain_size ) ;
/* try NULL account name */
ret = LookupAccountNameA ( NULL , NULL , psid , & sid_size , domain , & domain_size , & sid_use ) ;
get_sid_info ( psid , & account , & sid_dom ) ;
ok ( ret , " Failed to lookup account name \n " ) ;
2008-05-09 17:35:45 +00:00
/* Using a fixed string will not work on different locales */
ok ( ! lstrcmp ( account , domain ) ,
" Got %s for account and %s for domain, these should be the same \n " ,
account , domain ) ;
2008-12-09 19:26:45 +00:00
ok ( sid_use = = SidTypeDomain , " Expected SidTypeDomain (%d), got %d \n " , SidTypeDomain , sid_use ) ;
HeapFree ( GetProcessHeap ( ) , 0 , psid ) ;
HeapFree ( GetProcessHeap ( ) , 0 , domain ) ;
2008-05-09 17:35:45 +00:00
}
/* try an invalid account name */
SetLastError ( 0xdeadbeef ) ;
sid_size = 0 ;
domain_size = 0 ;
ret = LookupAccountNameA ( NULL , " oogabooga " , NULL , & sid_size , NULL , & domain_size , & sid_use ) ;
ok ( ! ret , " Expected 0, got %d \n " , ret ) ;
2008-12-09 19:26:45 +00:00
ok ( GetLastError ( ) = = ERROR_NONE_MAPPED | |
broken ( GetLastError ( ) = = ERROR_TRUSTED_RELATIONSHIP_FAILURE ) ,
" Expected ERROR_NONE_MAPPED, got %d \n " , GetLastError ( ) ) ;
ok ( sid_size = = 0 , " Expected 0, got %d \n " , sid_size ) ;
ok ( domain_size = = 0 , " Expected 0, got %d \n " , domain_size ) ;
2008-05-09 17:35:45 +00:00
2008-12-09 19:26:45 +00:00
/* try an invalid system name */
SetLastError ( 0xdeadbeef ) ;
sid_size = 0 ;
domain_size = 0 ;
ret = LookupAccountNameA ( " deepthought " , NULL , NULL , & sid_size , NULL , & domain_size , & sid_use ) ;
ok ( ! ret , " Expected 0, got %d \n " , ret ) ;
ok ( GetLastError ( ) = = RPC_S_SERVER_UNAVAILABLE | | GetLastError ( ) = = RPC_S_INVALID_NET_ADDR /* Vista */ ,
" Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d \n " , GetLastError ( ) ) ;
ok ( sid_size = = 0 , " Expected 0, got %d \n " , sid_size ) ;
ok ( domain_size = = 0 , " Expected 0, got %d \n " , domain_size ) ;
2009-02-08 09:32:24 +00:00
/* try with the computer name as the account name */
domain_size = sizeof ( computer_name ) ;
GetComputerNameA ( computer_name , & domain_size ) ;
sid_size = 0 ;
domain_size = 0 ;
ret = LookupAccountNameA ( NULL , computer_name , NULL , & sid_size , NULL , & domain_size , & sid_use ) ;
ok ( ! ret & & ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER | |
2009-05-17 07:05:22 +00:00
GetLastError ( ) = = ERROR_NONE_MAPPED /* in a domain */ | |
2009-02-08 09:32:24 +00:00
broken ( GetLastError ( ) = = ERROR_TRUSTED_DOMAIN_FAILURE ) | |
broken ( GetLastError ( ) = = ERROR_TRUSTED_RELATIONSHIP_FAILURE ) ) ,
" LookupAccountNameA failed: %d \n " , GetLastError ( ) ) ;
if ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER )
{
psid = HeapAlloc ( GetProcessHeap ( ) , 0 , sid_size ) ;
domain = HeapAlloc ( GetProcessHeap ( ) , 0 , domain_size ) ;
ret = LookupAccountNameA ( NULL , computer_name , psid , & sid_size , domain , & domain_size , & sid_use ) ;
ok ( ret , " LookupAccountNameA failed: %d \n " , GetLastError ( ) ) ;
ok ( sid_use = = SidTypeDomain , " expected SidTypeDomain, got %d \n " , sid_use ) ;
HeapFree ( GetProcessHeap ( ) , 0 , domain ) ;
HeapFree ( GetProcessHeap ( ) , 0 , psid ) ;
}
2009-05-17 07:05:22 +00:00
/* Well Known names */
if ( ! pCreateWellKnownSid )
{
win_skip ( " CreateWellKnownSid not available \n " ) ;
return ;
}
if ( PRIMARYLANGID ( LANGIDFROMLCID ( GetThreadLocale ( ) ) ) ! = LANG_ENGLISH )
{
skip ( " Non-english locale (skipping well known name creation tests) \n " ) ;
return ;
}
check_wellknown_name ( " LocalService " , WinLocalServiceSid ) ;
check_wellknown_name ( " Local Service " , WinLocalServiceSid ) ;
/* 2 spaces */
check_wellknown_name ( " Local Service " , 0 ) ;
check_wellknown_name ( " NetworkService " , WinNetworkServiceSid ) ;
check_wellknown_name ( " Network Service " , WinNetworkServiceSid ) ;
/* example of some names where the spaces are not optional */
check_wellknown_name ( " Terminal Server User " , WinTerminalServerSid ) ;
check_wellknown_name ( " TerminalServer User " , 0 ) ;
check_wellknown_name ( " TerminalServerUser " , 0 ) ;
check_wellknown_name ( " Terminal ServerUser " , 0 ) ;
check_wellknown_name ( " enterprise domain controllers " , WinEnterpriseControllersSid ) ;
check_wellknown_name ( " enterprisedomain controllers " , 0 ) ;
check_wellknown_name ( " enterprise domaincontrollers " , 0 ) ;
check_wellknown_name ( " enterprisedomaincontrollers " , 0 ) ;
/* case insensitivity */
check_wellknown_name ( " lOCAlServICE " , WinLocalServiceSid ) ;
/* fully qualified account names */
check_wellknown_name ( " NT AUTHORITY \\ LocalService " , WinLocalServiceSid ) ;
check_wellknown_name ( " nt authority \\ Network Service " , WinNetworkServiceSid ) ;
check_wellknown_name ( " nt authority test \\ Network Service " , 0 ) ;
check_wellknown_name ( " Dummy \\ Network Service " , 0 ) ;
check_wellknown_name ( " ntauthority \\ Network Service " , 0 ) ;
2008-05-09 17:35:45 +00:00
}
static void test_security_descriptor ( void )
{
SECURITY_DESCRIPTOR sd ;
char buf [ 8192 ] ;
DWORD size ;
BOOL isDefault , isPresent , ret ;
PACL pacl ;
PSID psid ;
SetLastError ( 0xdeadbeef ) ;
ret = InitializeSecurityDescriptor ( & sd , SECURITY_DESCRIPTOR_REVISION ) ;
if ( ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
{
2009-05-17 07:05:22 +00:00
win_skip ( " InitializeSecurityDescriptor is not implemented \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
ok ( GetSecurityDescriptorOwner ( & sd , & psid , & isDefault ) , " GetSecurityDescriptorOwner failed \n " ) ;
expect_eq ( psid , NULL , PSID , " %p " ) ;
expect_eq ( isDefault , FALSE , BOOL , " %d " ) ;
sd . Control | = SE_DACL_PRESENT | SE_SACL_PRESENT ;
SetLastError ( 0xdeadbeef ) ;
size = 5 ;
expect_eq ( MakeSelfRelativeSD ( & sd , buf , & size ) , FALSE , BOOL , " %d " ) ;
expect_eq ( GetLastError ( ) , ERROR_INSUFFICIENT_BUFFER , DWORD , " %u " ) ;
ok ( size > 5 , " Size not increased \n " ) ;
if ( size < = 8192 )
{
expect_eq ( MakeSelfRelativeSD ( & sd , buf , & size ) , TRUE , BOOL , " %d " ) ;
ok ( GetSecurityDescriptorOwner ( & sd , & psid , & isDefault ) , " GetSecurityDescriptorOwner failed \n " ) ;
expect_eq ( psid , NULL , PSID , " %p " ) ;
expect_eq ( isDefault , FALSE , BOOL , " %d " ) ;
ok ( GetSecurityDescriptorGroup ( & sd , & psid , & isDefault ) , " GetSecurityDescriptorGroup failed \n " ) ;
expect_eq ( psid , NULL , PSID , " %p " ) ;
expect_eq ( isDefault , FALSE , BOOL , " %d " ) ;
ok ( GetSecurityDescriptorDacl ( & sd , & isPresent , & pacl , & isDefault ) , " GetSecurityDescriptorDacl failed \n " ) ;
expect_eq ( isPresent , TRUE , BOOL , " %d " ) ;
expect_eq ( psid , NULL , PSID , " %p " ) ;
expect_eq ( isDefault , FALSE , BOOL , " %d " ) ;
ok ( GetSecurityDescriptorSacl ( & sd , & isPresent , & pacl , & isDefault ) , " GetSecurityDescriptorSacl failed \n " ) ;
expect_eq ( isPresent , TRUE , BOOL , " %d " ) ;
expect_eq ( psid , NULL , PSID , " %p " ) ;
expect_eq ( isDefault , FALSE , BOOL , " %d " ) ;
}
}
2008-09-14 18:24:25 +00:00
# define TEST_GRANTED_ACCESS(a,b) test_granted_access(a,b,0,__LINE__)
# define TEST_GRANTED_ACCESS2(a,b,c) test_granted_access(a,b,c,__LINE__)
static void test_granted_access ( HANDLE handle , ACCESS_MASK access ,
ACCESS_MASK alt , int line )
2008-05-09 17:35:45 +00:00
{
OBJECT_BASIC_INFORMATION obj_info ;
NTSTATUS status ;
if ( ! pNtQueryObject )
{
skip_ ( __FILE__ , line ) ( " Not NT platform - skipping tests \n " ) ;
return ;
}
status = pNtQueryObject ( handle , ObjectBasicInformation , & obj_info ,
sizeof ( obj_info ) , NULL ) ;
ok_ ( __FILE__ , line ) ( ! status , " NtQueryObject with err: %08x \n " , status ) ;
2008-09-14 18:24:25 +00:00
if ( alt )
ok_ ( __FILE__ , line ) ( obj_info . GrantedAccess = = access | |
obj_info . GrantedAccess = = alt , " Granted access should be 0x%08x "
" or 0x%08x, instead of 0x%08x \n " , access , alt , obj_info . GrantedAccess ) ;
else
ok_ ( __FILE__ , line ) ( obj_info . GrantedAccess = = access , " Granted access should "
" be 0x%08x, instead of 0x%08x \n " , access , obj_info . GrantedAccess ) ;
2008-05-09 17:35:45 +00:00
}
# define CHECK_SET_SECURITY(o,i,e) \
do { \
BOOL res ; \
DWORD err ; \
SetLastError ( 0xdeadbeef ) ; \
res = SetKernelObjectSecurity ( o , i , SecurityDescriptor ) ; \
err = GetLastError ( ) ; \
if ( e = = ERROR_SUCCESS ) \
ok ( res , " SetKernelObjectSecurity failed with %d \n " , err ) ; \
else \
ok ( ! res & & err = = e , " SetKernelObjectSecurity should have failed " \
" with %s, instead of %d \n " , # e , err ) ; \
} while ( 0 )
static void test_process_security ( void )
{
BOOL res ;
2009-02-08 09:32:24 +00:00
PTOKEN_OWNER owner ;
PTOKEN_PRIMARY_GROUP group ;
2008-05-09 17:35:45 +00:00
PSID AdminSid = NULL , UsersSid = NULL ;
PACL Acl = NULL ;
SECURITY_DESCRIPTOR * SecurityDescriptor = NULL ;
char buffer [ MAX_PATH ] ;
PROCESS_INFORMATION info ;
STARTUPINFOA startup ;
SECURITY_ATTRIBUTES psa ;
HANDLE token , event ;
2009-02-08 09:32:24 +00:00
DWORD size ;
2008-05-09 17:35:45 +00:00
Acl = HeapAlloc ( GetProcessHeap ( ) , 0 , 256 ) ;
res = InitializeAcl ( Acl , 256 , ACL_REVISION ) ;
if ( ! res & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
{
2009-05-17 07:05:22 +00:00
win_skip ( " ACLs not implemented - skipping tests \n " ) ;
2008-05-09 17:35:45 +00:00
HeapFree ( GetProcessHeap ( ) , 0 , Acl ) ;
return ;
}
ok ( res , " InitializeAcl failed with error %d \n " , GetLastError ( ) ) ;
/* get owner from the token we might be running as a user not admin */
res = OpenProcessToken ( GetCurrentProcess ( ) , MAXIMUM_ALLOWED , & token ) ;
ok ( res , " OpenProcessToken failed with error %d \n " , GetLastError ( ) ) ;
if ( ! res )
{
HeapFree ( GetProcessHeap ( ) , 0 , Acl ) ;
return ;
}
2009-02-08 09:32:24 +00:00
res = GetTokenInformation ( token , TokenOwner , NULL , 0 , & size ) ;
ok ( ! res , " Expected failure, got %d \n " , res ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" Expected ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
owner = HeapAlloc ( GetProcessHeap ( ) , 0 , size ) ;
res = GetTokenInformation ( token , TokenOwner , owner , size , & size ) ;
2008-05-09 17:35:45 +00:00
ok ( res , " GetTokenInformation failed with error %d \n " , GetLastError ( ) ) ;
AdminSid = ( ( TOKEN_OWNER * ) owner ) - > Owner ;
2009-02-08 09:32:24 +00:00
res = GetTokenInformation ( token , TokenPrimaryGroup , NULL , 0 , & size ) ;
ok ( ! res , " Expected failure, got %d \n " , res ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
" Expected ERROR_INSUFFICIENT_BUFFER, got %d \n " , GetLastError ( ) ) ;
group = HeapAlloc ( GetProcessHeap ( ) , 0 , size ) ;
res = GetTokenInformation ( token , TokenPrimaryGroup , group , size , & size ) ;
2008-05-09 17:35:45 +00:00
ok ( res , " GetTokenInformation failed with error %d \n " , GetLastError ( ) ) ;
UsersSid = ( ( TOKEN_PRIMARY_GROUP * ) group ) - > PrimaryGroup ;
CloseHandle ( token ) ;
if ( ! res )
{
2009-02-08 09:32:24 +00:00
HeapFree ( GetProcessHeap ( ) , 0 , group ) ;
HeapFree ( GetProcessHeap ( ) , 0 , owner ) ;
2008-05-09 17:35:45 +00:00
HeapFree ( GetProcessHeap ( ) , 0 , Acl ) ;
return ;
}
res = AddAccessDeniedAce ( Acl , ACL_REVISION , PROCESS_VM_READ , AdminSid ) ;
ok ( res , " AddAccessDeniedAce failed with error %d \n " , GetLastError ( ) ) ;
res = AddAccessAllowedAce ( Acl , ACL_REVISION , PROCESS_ALL_ACCESS , AdminSid ) ;
ok ( res , " AddAccessAllowedAce failed with error %d \n " , GetLastError ( ) ) ;
SecurityDescriptor = HeapAlloc ( GetProcessHeap ( ) , 0 , SECURITY_DESCRIPTOR_MIN_LENGTH ) ;
res = InitializeSecurityDescriptor ( SecurityDescriptor , SECURITY_DESCRIPTOR_REVISION ) ;
ok ( res , " InitializeSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
event = CreateEvent ( NULL , TRUE , TRUE , " test_event " ) ;
ok ( event ! = NULL , " CreateEvent %d \n " , GetLastError ( ) ) ;
SecurityDescriptor - > Revision = 0 ;
CHECK_SET_SECURITY ( event , OWNER_SECURITY_INFORMATION , ERROR_UNKNOWN_REVISION ) ;
SecurityDescriptor - > Revision = SECURITY_DESCRIPTOR_REVISION ;
CHECK_SET_SECURITY ( event , OWNER_SECURITY_INFORMATION , ERROR_INVALID_SECURITY_DESCR ) ;
CHECK_SET_SECURITY ( event , GROUP_SECURITY_INFORMATION , ERROR_INVALID_SECURITY_DESCR ) ;
CHECK_SET_SECURITY ( event , SACL_SECURITY_INFORMATION , ERROR_ACCESS_DENIED ) ;
CHECK_SET_SECURITY ( event , DACL_SECURITY_INFORMATION , ERROR_SUCCESS ) ;
/* NULL DACL is valid and means default DACL from token */
SecurityDescriptor - > Control | = SE_DACL_PRESENT ;
CHECK_SET_SECURITY ( event , DACL_SECURITY_INFORMATION , ERROR_SUCCESS ) ;
/* Set owner and group and dacl */
res = SetSecurityDescriptorOwner ( SecurityDescriptor , AdminSid , FALSE ) ;
ok ( res , " SetSecurityDescriptorOwner failed with error %d \n " , GetLastError ( ) ) ;
CHECK_SET_SECURITY ( event , OWNER_SECURITY_INFORMATION , ERROR_SUCCESS ) ;
res = SetSecurityDescriptorGroup ( SecurityDescriptor , UsersSid , FALSE ) ;
ok ( res , " SetSecurityDescriptorGroup failed with error %d \n " , GetLastError ( ) ) ;
CHECK_SET_SECURITY ( event , GROUP_SECURITY_INFORMATION , ERROR_SUCCESS ) ;
res = SetSecurityDescriptorDacl ( SecurityDescriptor , TRUE , Acl , FALSE ) ;
ok ( res , " SetSecurityDescriptorDacl failed with error %d \n " , GetLastError ( ) ) ;
CHECK_SET_SECURITY ( event , DACL_SECURITY_INFORMATION , ERROR_SUCCESS ) ;
sprintf ( buffer , " %s tests/security.c test " , myARGV [ 0 ] ) ;
memset ( & startup , 0 , sizeof ( startup ) ) ;
startup . cb = sizeof ( startup ) ;
startup . dwFlags = STARTF_USESHOWWINDOW ;
startup . wShowWindow = SW_SHOWNORMAL ;
psa . nLength = sizeof ( psa ) ;
psa . lpSecurityDescriptor = SecurityDescriptor ;
psa . bInheritHandle = TRUE ;
/* Doesn't matter what ACL say we should get full access for ourselves */
ok ( CreateProcessA ( NULL , buffer , & psa , NULL , FALSE , 0 , NULL , NULL , & startup , & info ) ,
" CreateProcess with err:%d \n " , GetLastError ( ) ) ;
2008-09-14 18:24:25 +00:00
TEST_GRANTED_ACCESS2 ( info . hProcess , PROCESS_ALL_ACCESS ,
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ) ;
2008-05-09 17:35:45 +00:00
winetest_wait_child_process ( info . hProcess ) ;
CloseHandle ( info . hProcess ) ;
CloseHandle ( info . hThread ) ;
CloseHandle ( event ) ;
2009-02-08 09:32:24 +00:00
HeapFree ( GetProcessHeap ( ) , 0 , group ) ;
HeapFree ( GetProcessHeap ( ) , 0 , owner ) ;
2008-05-09 17:35:45 +00:00
HeapFree ( GetProcessHeap ( ) , 0 , Acl ) ;
HeapFree ( GetProcessHeap ( ) , 0 , SecurityDescriptor ) ;
}
static void test_process_security_child ( void )
{
HANDLE handle , handle1 ;
BOOL ret ;
DWORD err ;
handle = OpenProcess ( PROCESS_TERMINATE , FALSE , GetCurrentProcessId ( ) ) ;
ok ( handle ! = NULL , " OpenProcess(PROCESS_TERMINATE) with err:%d \n " , GetLastError ( ) ) ;
TEST_GRANTED_ACCESS ( handle , PROCESS_TERMINATE ) ;
ok ( DuplicateHandle ( GetCurrentProcess ( ) , handle , GetCurrentProcess ( ) ,
& handle1 , 0 , TRUE , DUPLICATE_SAME_ACCESS ) ,
" duplicating handle err:%d \n " , GetLastError ( ) ) ;
TEST_GRANTED_ACCESS ( handle1 , PROCESS_TERMINATE ) ;
CloseHandle ( handle1 ) ;
SetLastError ( 0xdeadbeef ) ;
ret = DuplicateHandle ( GetCurrentProcess ( ) , handle , GetCurrentProcess ( ) ,
& handle1 , PROCESS_ALL_ACCESS , TRUE , 0 ) ;
err = GetLastError ( ) ;
todo_wine
ok ( ! ret & & err = = ERROR_ACCESS_DENIED , " duplicating handle should have failed "
" with STATUS_ACCESS_DENIED, instead of err:%d \n " , err ) ;
CloseHandle ( handle ) ;
/* These two should fail - they are denied by ACL */
handle = OpenProcess ( PROCESS_VM_READ , FALSE , GetCurrentProcessId ( ) ) ;
todo_wine
ok ( handle = = NULL , " OpenProcess(PROCESS_VM_READ) should have failed \n " ) ;
handle = OpenProcess ( PROCESS_ALL_ACCESS , FALSE , GetCurrentProcessId ( ) ) ;
todo_wine
ok ( handle = = NULL , " OpenProcess(PROCESS_ALL_ACCESS) should have failed \n " ) ;
/* Documented privilege elevation */
ok ( DuplicateHandle ( GetCurrentProcess ( ) , GetCurrentProcess ( ) , GetCurrentProcess ( ) ,
& handle , 0 , TRUE , DUPLICATE_SAME_ACCESS ) ,
" duplicating handle err:%d \n " , GetLastError ( ) ) ;
2008-09-14 18:24:25 +00:00
TEST_GRANTED_ACCESS2 ( handle , PROCESS_ALL_ACCESS ,
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ) ;
2008-05-09 17:35:45 +00:00
CloseHandle ( handle ) ;
/* Same only explicitly asking for all access rights */
ok ( DuplicateHandle ( GetCurrentProcess ( ) , GetCurrentProcess ( ) , GetCurrentProcess ( ) ,
& handle , PROCESS_ALL_ACCESS , TRUE , 0 ) ,
" duplicating handle err:%d \n " , GetLastError ( ) ) ;
2008-09-14 18:24:25 +00:00
TEST_GRANTED_ACCESS2 ( handle , PROCESS_ALL_ACCESS ,
PROCESS_ALL_ACCESS | PROCESS_QUERY_LIMITED_INFORMATION ) ;
2008-05-09 17:35:45 +00:00
ok ( DuplicateHandle ( GetCurrentProcess ( ) , handle , GetCurrentProcess ( ) ,
& handle1 , PROCESS_VM_READ , TRUE , 0 ) ,
" duplicating handle err:%d \n " , GetLastError ( ) ) ;
TEST_GRANTED_ACCESS ( handle1 , PROCESS_VM_READ ) ;
CloseHandle ( handle1 ) ;
CloseHandle ( handle ) ;
}
static void test_impersonation_level ( void )
{
HANDLE Token , ProcessToken ;
HANDLE Token2 ;
DWORD Size ;
TOKEN_PRIVILEGES * Privileges ;
TOKEN_USER * User ;
PRIVILEGE_SET * PrivilegeSet ;
BOOL AccessGranted ;
BOOL ret ;
HKEY hkey ;
DWORD error ;
pDuplicateTokenEx = ( fnDuplicateTokenEx ) GetProcAddress ( hmod , " DuplicateTokenEx " ) ;
if ( ! pDuplicateTokenEx ) {
2009-05-17 07:05:22 +00:00
win_skip ( " DuplicateTokenEx is not available \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
SetLastError ( 0xdeadbeef ) ;
ret = ImpersonateSelf ( SecurityAnonymous ) ;
if ( ! ret & & ( GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED ) )
{
2009-05-17 07:05:22 +00:00
win_skip ( " ImpersonateSelf is not implemented \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
ok ( ret , " ImpersonateSelf(SecurityAnonymous) failed with error %d \n " , GetLastError ( ) ) ;
ret = OpenThreadToken ( GetCurrentThread ( ) , TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT , TRUE , & Token ) ;
ok ( ! ret , " OpenThreadToken should have failed \n " ) ;
error = GetLastError ( ) ;
ok ( error = = ERROR_CANT_OPEN_ANONYMOUS , " OpenThreadToken on anonymous token should have returned ERROR_CANT_OPEN_ANONYMOUS instead of %d \n " , error ) ;
/* can't perform access check when opening object against an anonymous impersonation token */
todo_wine {
error = RegOpenKeyEx ( HKEY_CURRENT_USER , " Software " , 0 , KEY_READ , & hkey ) ;
2009-10-18 14:57:22 +00:00
ok ( error = = ERROR_INVALID_HANDLE | | error = = ERROR_CANT_OPEN_ANONYMOUS ,
" RegOpenKeyEx should have failed with ERROR_INVALID_HANDLE or ERROR_CANT_OPEN_ANONYMOUS instead of %d \n " , error ) ;
2008-05-09 17:35:45 +00:00
}
RevertToSelf ( ) ;
ret = OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_DUPLICATE , & ProcessToken ) ;
ok ( ret , " OpenProcessToken failed with error %d \n " , GetLastError ( ) ) ;
ret = pDuplicateTokenEx ( ProcessToken ,
TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE , NULL ,
SecurityAnonymous , TokenImpersonation , & Token ) ;
ok ( ret , " DuplicateTokenEx failed with error %d \n " , GetLastError ( ) ) ;
/* can't increase the impersonation level */
ret = DuplicateToken ( Token , SecurityIdentification , & Token2 ) ;
error = GetLastError ( ) ;
ok ( ! ret & & error = = ERROR_BAD_IMPERSONATION_LEVEL ,
" Duplicating a token and increasing the impersonation level should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %d \n " , error ) ;
/* we can query anything from an anonymous token, including the user */
ret = GetTokenInformation ( Token , TokenUser , NULL , 0 , & Size ) ;
error = GetLastError ( ) ;
ok ( ! ret & & error = = ERROR_INSUFFICIENT_BUFFER , " GetTokenInformation(TokenUser) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d \n " , error ) ;
2008-12-09 19:26:45 +00:00
User = HeapAlloc ( GetProcessHeap ( ) , 0 , Size ) ;
2008-05-09 17:35:45 +00:00
ret = GetTokenInformation ( Token , TokenUser , User , Size , & Size ) ;
ok ( ret , " GetTokenInformation(TokenUser) failed with error %d \n " , GetLastError ( ) ) ;
HeapFree ( GetProcessHeap ( ) , 0 , User ) ;
/* PrivilegeCheck fails with SecurityAnonymous level */
ret = GetTokenInformation ( Token , TokenPrivileges , NULL , 0 , & Size ) ;
error = GetLastError ( ) ;
ok ( ! ret & & error = = ERROR_INSUFFICIENT_BUFFER , " GetTokenInformation(TokenPrivileges) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d \n " , error ) ;
2008-12-09 19:26:45 +00:00
Privileges = HeapAlloc ( GetProcessHeap ( ) , 0 , Size ) ;
2008-05-09 17:35:45 +00:00
ret = GetTokenInformation ( Token , TokenPrivileges , Privileges , Size , & Size ) ;
ok ( ret , " GetTokenInformation(TokenPrivileges) failed with error %d \n " , GetLastError ( ) ) ;
2008-12-09 19:26:45 +00:00
PrivilegeSet = HeapAlloc ( GetProcessHeap ( ) , 0 , FIELD_OFFSET ( PRIVILEGE_SET , Privilege [ Privileges - > PrivilegeCount ] ) ) ;
2008-05-09 17:35:45 +00:00
PrivilegeSet - > PrivilegeCount = Privileges - > PrivilegeCount ;
memcpy ( PrivilegeSet - > Privilege , Privileges - > Privileges , PrivilegeSet - > PrivilegeCount * sizeof ( PrivilegeSet - > Privilege [ 0 ] ) ) ;
PrivilegeSet - > Control = PRIVILEGE_SET_ALL_NECESSARY ;
HeapFree ( GetProcessHeap ( ) , 0 , Privileges ) ;
ret = PrivilegeCheck ( Token , PrivilegeSet , & AccessGranted ) ;
error = GetLastError ( ) ;
ok ( ! ret & & error = = ERROR_BAD_IMPERSONATION_LEVEL , " PrivilegeCheck for SecurityAnonymous token should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %d \n " , error ) ;
CloseHandle ( Token ) ;
ret = ImpersonateSelf ( SecurityIdentification ) ;
ok ( ret , " ImpersonateSelf(SecurityIdentification) failed with error %d \n " , GetLastError ( ) ) ;
ret = OpenThreadToken ( GetCurrentThread ( ) , TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT , TRUE , & Token ) ;
ok ( ret , " OpenThreadToken failed with error %d \n " , GetLastError ( ) ) ;
/* can't perform access check when opening object against an identification impersonation token */
error = RegOpenKeyEx ( HKEY_CURRENT_USER , " Software " , 0 , KEY_READ , & hkey ) ;
todo_wine {
2009-10-18 14:57:22 +00:00
ok ( error = = ERROR_INVALID_HANDLE | | error = = ERROR_BAD_IMPERSONATION_LEVEL ,
" RegOpenKeyEx should have failed with ERROR_INVALID_HANDLE or ERROR_BAD_IMPERSONATION_LEVEL instead of %d \n " , error ) ;
2008-05-09 17:35:45 +00:00
}
ret = PrivilegeCheck ( Token , PrivilegeSet , & AccessGranted ) ;
ok ( ret , " PrivilegeCheck for SecurityIdentification failed with error %d \n " , GetLastError ( ) ) ;
CloseHandle ( Token ) ;
RevertToSelf ( ) ;
ret = ImpersonateSelf ( SecurityImpersonation ) ;
ok ( ret , " ImpersonateSelf(SecurityImpersonation) failed with error %d \n " , GetLastError ( ) ) ;
ret = OpenThreadToken ( GetCurrentThread ( ) , TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT , TRUE , & Token ) ;
ok ( ret , " OpenThreadToken failed with error %d \n " , GetLastError ( ) ) ;
error = RegOpenKeyEx ( HKEY_CURRENT_USER , " Software " , 0 , KEY_READ , & hkey ) ;
ok ( error = = ERROR_SUCCESS , " RegOpenKeyEx should have succeeded instead of failing with %d \n " , error ) ;
RegCloseKey ( hkey ) ;
ret = PrivilegeCheck ( Token , PrivilegeSet , & AccessGranted ) ;
ok ( ret , " PrivilegeCheck for SecurityImpersonation failed with error %d \n " , GetLastError ( ) ) ;
RevertToSelf ( ) ;
CloseHandle ( Token ) ;
CloseHandle ( ProcessToken ) ;
HeapFree ( GetProcessHeap ( ) , 0 , PrivilegeSet ) ;
}
static void test_SetEntriesInAcl ( void )
{
DWORD res ;
PSID EveryoneSid = NULL , UsersSid = NULL ;
PACL OldAcl = NULL , NewAcl ;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY } ;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY } ;
EXPLICIT_ACCESSW ExplicitAccess ;
static const WCHAR wszEveryone [ ] = { ' E ' , ' v ' , ' e ' , ' r ' , ' y ' , ' o ' , ' n ' , ' e ' , 0 } ;
2009-10-18 14:57:22 +00:00
static const WCHAR wszCurrentUser [ ] = { ' C ' , ' U ' , ' R ' , ' R ' , ' E ' , ' N ' , ' T ' , ' _ ' , ' U ' , ' S ' , ' E ' , ' R ' , ' \0 ' } ;
2008-05-09 17:35:45 +00:00
if ( ! pSetEntriesInAclW )
{
2008-12-09 19:26:45 +00:00
win_skip ( " SetEntriesInAclW is not available \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
NewAcl = ( PACL ) 0xdeadbeef ;
res = pSetEntriesInAclW ( 0 , NULL , NULL , & NewAcl ) ;
if ( res = = ERROR_CALL_NOT_IMPLEMENTED )
{
2008-12-09 19:26:45 +00:00
win_skip ( " SetEntriesInAclW is not implemented \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
ok ( res = = ERROR_SUCCESS , " SetEntriesInAclW failed: %u \n " , res ) ;
2008-12-09 19:26:45 +00:00
ok ( NewAcl = = NULL | |
broken ( NewAcl ! = NULL ) , /* NT4 */
" NewAcl=%p, expected NULL \n " , NewAcl ) ;
LocalFree ( NewAcl ) ;
2008-05-09 17:35:45 +00:00
OldAcl = HeapAlloc ( GetProcessHeap ( ) , 0 , 256 ) ;
res = InitializeAcl ( OldAcl , 256 , ACL_REVISION ) ;
if ( ! res & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
{
2008-12-09 19:26:45 +00:00
win_skip ( " ACLs not implemented - skipping tests \n " ) ;
2008-05-09 17:35:45 +00:00
HeapFree ( GetProcessHeap ( ) , 0 , OldAcl ) ;
return ;
}
ok ( res , " InitializeAcl failed with error %d \n " , GetLastError ( ) ) ;
res = AllocateAndInitializeSid ( & SIDAuthWorld , 1 , SECURITY_WORLD_RID , 0 , 0 , 0 , 0 , 0 , 0 , 0 , & EveryoneSid ) ;
ok ( res , " AllocateAndInitializeSid failed with error %d \n " , GetLastError ( ) ) ;
res = AllocateAndInitializeSid ( & SIDAuthNT , 2 , SECURITY_BUILTIN_DOMAIN_RID ,
DOMAIN_ALIAS_RID_USERS , 0 , 0 , 0 , 0 , 0 , 0 , & UsersSid ) ;
ok ( res , " AllocateAndInitializeSid failed with error %d \n " , GetLastError ( ) ) ;
res = AddAccessAllowedAce ( OldAcl , ACL_REVISION , KEY_READ , UsersSid ) ;
ok ( res , " AddAccessAllowedAce failed with error %d \n " , GetLastError ( ) ) ;
ExplicitAccess . grfAccessPermissions = KEY_WRITE ;
ExplicitAccess . grfAccessMode = GRANT_ACCESS ;
ExplicitAccess . grfInheritance = NO_INHERITANCE ;
ExplicitAccess . Trustee . pMultipleTrustee = NULL ;
ExplicitAccess . Trustee . MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE ;
ExplicitAccess . Trustee . TrusteeForm = TRUSTEE_IS_SID ;
ExplicitAccess . Trustee . TrusteeType = TRUSTEE_IS_UNKNOWN ;
2009-02-08 09:32:24 +00:00
ExplicitAccess . Trustee . ptstrName = EveryoneSid ;
2008-05-09 17:35:45 +00:00
res = pSetEntriesInAclW ( 1 , & ExplicitAccess , OldAcl , & NewAcl ) ;
ok ( res = = ERROR_SUCCESS , " SetEntriesInAclW failed: %u \n " , res ) ;
ok ( NewAcl ! = NULL , " returned acl was NULL \n " ) ;
LocalFree ( NewAcl ) ;
if ( PRIMARYLANGID ( LANGIDFROMLCID ( GetThreadLocale ( ) ) ) ! = LANG_ENGLISH )
{
skip ( " Non-english locale (test with hardcoded 'Everyone') \n " ) ;
}
else
{
ExplicitAccess . Trustee . TrusteeForm = TRUSTEE_IS_USER ;
ExplicitAccess . Trustee . ptstrName = ( LPWSTR ) wszEveryone ;
res = pSetEntriesInAclW ( 1 , & ExplicitAccess , OldAcl , & NewAcl ) ;
ok ( res = = ERROR_SUCCESS , " SetEntriesInAclW failed: %u \n " , res ) ;
ok ( NewAcl ! = NULL , " returned acl was NULL \n " ) ;
LocalFree ( NewAcl ) ;
ExplicitAccess . Trustee . TrusteeForm = TRUSTEE_BAD_FORM ;
res = pSetEntriesInAclW ( 1 , & ExplicitAccess , OldAcl , & NewAcl ) ;
2008-12-09 19:26:45 +00:00
ok ( res = = ERROR_INVALID_PARAMETER | |
broken ( res = = ERROR_NOT_SUPPORTED ) , /* NT4 */
" SetEntriesInAclW failed: %u \n " , res ) ;
ok ( NewAcl = = NULL | |
broken ( NewAcl ! = NULL ) , /* NT4 */
" returned acl wasn't NULL: %p \n " , NewAcl ) ;
2008-05-09 17:35:45 +00:00
ExplicitAccess . Trustee . TrusteeForm = TRUSTEE_IS_USER ;
ExplicitAccess . Trustee . MultipleTrusteeOperation = TRUSTEE_IS_IMPERSONATE ;
res = pSetEntriesInAclW ( 1 , & ExplicitAccess , OldAcl , & NewAcl ) ;
2008-12-09 19:26:45 +00:00
ok ( res = = ERROR_INVALID_PARAMETER | |
broken ( res = = ERROR_NOT_SUPPORTED ) , /* NT4 */
" SetEntriesInAclW failed: %u \n " , res ) ;
ok ( NewAcl = = NULL | |
broken ( NewAcl ! = NULL ) , /* NT4 */
" returned acl wasn't NULL: %p \n " , NewAcl ) ;
2008-05-09 17:35:45 +00:00
ExplicitAccess . Trustee . MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE ;
ExplicitAccess . grfAccessMode = SET_ACCESS ;
res = pSetEntriesInAclW ( 1 , & ExplicitAccess , OldAcl , & NewAcl ) ;
ok ( res = = ERROR_SUCCESS , " SetEntriesInAclW failed: %u \n " , res ) ;
ok ( NewAcl ! = NULL , " returned acl was NULL \n " ) ;
LocalFree ( NewAcl ) ;
}
2009-10-18 14:57:22 +00:00
ExplicitAccess . Trustee . TrusteeForm = TRUSTEE_IS_USER ;
ExplicitAccess . Trustee . ptstrName = ( LPWSTR ) wszCurrentUser ;
res = pSetEntriesInAclW ( 1 , & ExplicitAccess , OldAcl , & NewAcl ) ;
ok ( res = = ERROR_SUCCESS , " SetEntriesInAclW failed: %u \n " , res ) ;
ok ( NewAcl ! = NULL , " returned acl was NULL \n " ) ;
LocalFree ( NewAcl ) ;
2008-05-09 17:35:45 +00:00
ExplicitAccess . grfAccessMode = REVOKE_ACCESS ;
ExplicitAccess . Trustee . TrusteeForm = TRUSTEE_IS_SID ;
2009-02-08 09:32:24 +00:00
ExplicitAccess . Trustee . ptstrName = UsersSid ;
2008-05-09 17:35:45 +00:00
res = pSetEntriesInAclW ( 1 , & ExplicitAccess , OldAcl , & NewAcl ) ;
ok ( res = = ERROR_SUCCESS , " SetEntriesInAclW failed: %u \n " , res ) ;
ok ( NewAcl ! = NULL , " returned acl was NULL \n " ) ;
LocalFree ( NewAcl ) ;
LocalFree ( UsersSid ) ;
LocalFree ( EveryoneSid ) ;
HeapFree ( GetProcessHeap ( ) , 0 , OldAcl ) ;
}
static void test_GetNamedSecurityInfoA ( void )
{
PSECURITY_DESCRIPTOR pSecDesc ;
DWORD revision ;
SECURITY_DESCRIPTOR_CONTROL control ;
PSID owner ;
PSID group ;
BOOL owner_defaulted ;
BOOL group_defaulted ;
DWORD error ;
BOOL ret ;
CHAR windows_dir [ MAX_PATH ] ;
if ( ! pGetNamedSecurityInfoA )
{
2009-05-17 07:05:22 +00:00
win_skip ( " GetNamedSecurityInfoA is not available \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
ret = GetWindowsDirectoryA ( windows_dir , MAX_PATH ) ;
ok ( ret , " GetWindowsDirectory failed with error %d \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
error = pGetNamedSecurityInfoA ( windows_dir , SE_FILE_OBJECT ,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION ,
NULL , NULL , NULL , NULL , & pSecDesc ) ;
if ( error ! = ERROR_SUCCESS & & ( GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED ) )
{
2009-05-17 07:05:22 +00:00
win_skip ( " GetNamedSecurityInfoA is not implemented \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
ok ( ! error , " GetNamedSecurityInfo failed with error %d \n " , error ) ;
ret = GetSecurityDescriptorControl ( pSecDesc , & control , & revision ) ;
ok ( ret , " GetSecurityDescriptorControl failed with error %d \n " , GetLastError ( ) ) ;
2009-02-08 09:32:24 +00:00
ok ( ( control & ( SE_SELF_RELATIVE | SE_DACL_PRESENT ) ) = = ( SE_SELF_RELATIVE | SE_DACL_PRESENT ) | |
broken ( ( control & ( SE_SELF_RELATIVE | SE_DACL_PRESENT ) ) = = SE_DACL_PRESENT ) , /* NT4 */
2008-05-09 17:35:45 +00:00
" control (0x%x) doesn't have (SE_SELF_RELATIVE|SE_DACL_PRESENT) flags set \n " , control ) ;
ok ( revision = = SECURITY_DESCRIPTOR_REVISION1 , " revision was %d instead of 1 \n " , revision ) ;
ret = GetSecurityDescriptorOwner ( pSecDesc , & owner , & owner_defaulted ) ;
ok ( ret , " GetSecurityDescriptorOwner failed with error %d \n " , GetLastError ( ) ) ;
ok ( owner ! = NULL , " owner should not be NULL \n " ) ;
ret = GetSecurityDescriptorGroup ( pSecDesc , & group , & group_defaulted ) ;
ok ( ret , " GetSecurityDescriptorGroup failed with error %d \n " , GetLastError ( ) ) ;
ok ( group ! = NULL , " group should not be NULL \n " ) ;
2009-02-08 09:32:24 +00:00
LocalFree ( pSecDesc ) ;
2008-05-09 17:35:45 +00:00
}
static void test_ConvertStringSecurityDescriptor ( void )
{
BOOL ret ;
PSECURITY_DESCRIPTOR pSD ;
2008-12-09 19:26:45 +00:00
static const WCHAR Blank [ ] = { 0 } ;
2008-05-09 17:35:45 +00:00
if ( ! pConvertStringSecurityDescriptorToSecurityDescriptorA )
{
2009-05-17 07:05:22 +00:00
win_skip ( " ConvertStringSecurityDescriptorToSecurityDescriptor is not available \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(A;;GA;;;WD) " , 0xdeadbeef , & pSD , NULL ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_UNKNOWN_REVISION ,
" ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_UNKNOWN_REVISION instead of %d \n " ,
GetLastError ( ) ) ;
/* test ACE string type */
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(A;;GA;;;WD) " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ret , " ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
LocalFree ( pSD ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(D;;GA;;;WD) " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ret , " ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
LocalFree ( pSD ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" ERROR:(D;;GA;;;WD) " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d \n " ,
GetLastError ( ) ) ;
/* test ACE string access rights */
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(A;;GA;;;WD) " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ret , " ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
LocalFree ( pSD ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(A;;GRGWGX;;;WD) " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ret , " ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
LocalFree ( pSD ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(A;;RCSDWDWO;;;WD) " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ret , " ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
LocalFree ( pSD ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(A;;RPWPCCDCLCSWLODTCR;;;WD) " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ret , " ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
LocalFree ( pSD ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(A;;FAFRFWFX;;;WD) " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ret , " ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
LocalFree ( pSD ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(A;;KAKRKWKX;;;WD) " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ret , " ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
LocalFree ( pSD ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(A;;0xFFFFFFFF;;;WD) " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ret , " ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
LocalFree ( pSD ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" S:(AU;;0xFFFFFFFF;;;WD) " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ret , " ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
LocalFree ( pSD ) ;
/* test ACE string access right error case */
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(A;;ROB;;;WD) " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_ACL ,
" ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_ACL instead of %d \n " ,
GetLastError ( ) ) ;
2008-12-09 19:26:45 +00:00
/* test behaviour with NULL parameters */
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
NULL , 0xdeadbeef , & pSD , NULL ) ;
todo_wine
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d \n " ,
GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorW (
NULL , 0xdeadbeef , & pSD , NULL ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d \n " ,
GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(A;;ROB;;;WD) " , 0xdeadbeef , NULL , NULL ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d \n " ,
GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(A;;ROB;;;WD) " , SDDL_REVISION_1 , NULL , NULL ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
" ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d \n " ,
GetLastError ( ) ) ;
/* test behaviour with empty strings */
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ret , " ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorW (
Blank , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ret , " ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
2008-05-09 17:35:45 +00:00
/* test ACE string SID */
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(D;;GA;;;S-1-0-0) " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ret , " ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
LocalFree ( pSD ) ;
SetLastError ( 0xdeadbeef ) ;
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA (
" D:(D;;GA;;;Nonexistent account) " , SDDL_REVISION_1 , & pSD , NULL ) ;
ok ( ! ret , " Expected failure, got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_ACL | | GetLastError ( ) = = ERROR_INVALID_SID ,
" Expected ERROR_INVALID_ACL or ERROR_INVALID_SID, got %d \n " , GetLastError ( ) ) ;
}
2009-02-08 09:32:24 +00:00
static void test_ConvertSecurityDescriptorToString ( void )
2008-05-09 17:35:45 +00:00
{
SECURITY_DESCRIPTOR desc ;
SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION ;
LPSTR string ;
DWORD size ;
PSID psid , psid2 ;
PACL pacl ;
char sid_buf [ 256 ] ;
char acl_buf [ 8192 ] ;
ULONG len ;
if ( ! pConvertSecurityDescriptorToStringSecurityDescriptorA )
{
2009-05-17 07:05:22 +00:00
win_skip ( " ConvertSecurityDescriptorToStringSecurityDescriptor is not available \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
if ( ! pCreateWellKnownSid )
{
2009-05-17 07:05:22 +00:00
win_skip ( " CreateWellKnownSid is not available \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
/* It seems Windows XP adds an extra character to the length of the string for each ACE in an ACL. We
* don ' t replicate this feature so we only test len > = strlen + 1. */
# define CHECK_RESULT_AND_FREE(exp_str) \
ok ( strcmp ( string , ( exp_str ) ) = = 0 , " String mismatch (expected \" %s \" , got \" %s \" ) \n " , ( exp_str ) , string ) ; \
ok ( len > = ( lstrlen ( exp_str ) + 1 ) , " Length mismatch (expected %d, got %d) \n " , lstrlen ( exp_str ) + 1 , len ) ; \
LocalFree ( string ) ;
# define CHECK_ONE_OF_AND_FREE(exp_str1, exp_str2) \
ok ( strcmp ( string , ( exp_str1 ) ) = = 0 | | strcmp ( string , ( exp_str2 ) ) = = 0 , " String mismatch (expected \n \" %s \" or \n \" %s \" , got \n \" %s \" ) \n " , ( exp_str1 ) , ( exp_str2 ) , string ) ; \
ok ( len > = ( strlen ( string ) + 1 ) , " Length mismatch (expected %d, got %d) \n " , lstrlen ( string ) + 1 , len ) ; \
LocalFree ( string ) ;
InitializeSecurityDescriptor ( & desc , SECURITY_DESCRIPTOR_REVISION ) ;
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( & desc , SDDL_REVISION_1 , sec_info , & string , & len ) , " Conversion failed \n " ) ;
CHECK_RESULT_AND_FREE ( " " ) ;
size = 4096 ;
pCreateWellKnownSid ( WinLocalSid , NULL , sid_buf , & size ) ;
2009-02-08 09:32:24 +00:00
SetSecurityDescriptorOwner ( & desc , sid_buf , FALSE ) ;
2008-05-09 17:35:45 +00:00
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( & desc , SDDL_REVISION_1 , sec_info , & string , & len ) , " Conversion failed \n " ) ;
CHECK_RESULT_AND_FREE ( " O:S-1-2-0 " ) ;
2009-02-08 09:32:24 +00:00
SetSecurityDescriptorOwner ( & desc , sid_buf , TRUE ) ;
2008-05-09 17:35:45 +00:00
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( & desc , SDDL_REVISION_1 , sec_info , & string , & len ) , " Conversion failed \n " ) ;
CHECK_RESULT_AND_FREE ( " O:S-1-2-0 " ) ;
size = sizeof ( sid_buf ) ;
pCreateWellKnownSid ( WinLocalSystemSid , NULL , sid_buf , & size ) ;
2009-02-08 09:32:24 +00:00
SetSecurityDescriptorOwner ( & desc , sid_buf , TRUE ) ;
2008-05-09 17:35:45 +00:00
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( & desc , SDDL_REVISION_1 , sec_info , & string , & len ) , " Conversion failed \n " ) ;
CHECK_RESULT_AND_FREE ( " O:SY " ) ;
pConvertStringSidToSidA ( " S-1-5-21-93476-23408-4576 " , & psid ) ;
SetSecurityDescriptorGroup ( & desc , psid , TRUE ) ;
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( & desc , SDDL_REVISION_1 , sec_info , & string , & len ) , " Conversion failed \n " ) ;
CHECK_RESULT_AND_FREE ( " O:SYG:S-1-5-21-93476-23408-4576 " ) ;
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( & desc , SDDL_REVISION_1 , GROUP_SECURITY_INFORMATION , & string , & len ) , " Conversion failed \n " ) ;
CHECK_RESULT_AND_FREE ( " G:S-1-5-21-93476-23408-4576 " ) ;
pacl = ( PACL ) acl_buf ;
InitializeAcl ( pacl , sizeof ( acl_buf ) , ACL_REVISION ) ;
SetSecurityDescriptorDacl ( & desc , TRUE , pacl , TRUE ) ;
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( & desc , SDDL_REVISION_1 , sec_info , & string , & len ) , " Conversion failed \n " ) ;
CHECK_RESULT_AND_FREE ( " O:SYG:S-1-5-21-93476-23408-4576D: " ) ;
SetSecurityDescriptorDacl ( & desc , TRUE , pacl , FALSE ) ;
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( & desc , SDDL_REVISION_1 , sec_info , & string , & len ) , " Conversion failed \n " ) ;
CHECK_RESULT_AND_FREE ( " O:SYG:S-1-5-21-93476-23408-4576D: " ) ;
pConvertStringSidToSidA ( " S-1-5-6 " , & psid2 ) ;
pAddAccessAllowedAceEx ( pacl , ACL_REVISION , NO_PROPAGATE_INHERIT_ACE , 0xf0000000 , psid2 ) ;
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( & desc , SDDL_REVISION_1 , sec_info , & string , & len ) , " Conversion failed \n " ) ;
CHECK_RESULT_AND_FREE ( " O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU) " ) ;
pAddAccessAllowedAceEx ( pacl , ACL_REVISION , INHERIT_ONLY_ACE | INHERITED_ACE , 0x00000003 , psid2 ) ;
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( & desc , SDDL_REVISION_1 , sec_info , & string , & len ) , " Conversion failed \n " ) ;
CHECK_RESULT_AND_FREE ( " O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU) " ) ;
pAddAccessDeniedAceEx ( pacl , ACL_REVISION , OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE , 0xffffffff , psid ) ;
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( & desc , SDDL_REVISION_1 , sec_info , & string , & len ) , " Conversion failed \n " ) ;
CHECK_RESULT_AND_FREE ( " O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576) " ) ;
pacl = ( PACL ) acl_buf ;
InitializeAcl ( pacl , sizeof ( acl_buf ) , ACL_REVISION ) ;
SetSecurityDescriptorSacl ( & desc , TRUE , pacl , FALSE ) ;
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( & desc , SDDL_REVISION_1 , sec_info , & string , & len ) , " Conversion failed \n " ) ;
CHECK_RESULT_AND_FREE ( " O:SYG:S-1-5-21-93476-23408-4576D:S: " ) ;
/* fails in win2k */
SetSecurityDescriptorDacl ( & desc , TRUE , NULL , FALSE ) ;
pAddAuditAccessAceEx ( pacl , ACL_REVISION , VALID_INHERIT_FLAGS , KEY_READ | KEY_WRITE , psid2 , TRUE , TRUE ) ;
if ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( & desc , SDDL_REVISION_1 , sec_info , & string , & len ) )
{
CHECK_ONE_OF_AND_FREE ( " O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU) " , /* XP */
" O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU) " /* Vista */ ) ;
}
/* fails in win2k */
pAddAuditAccessAceEx ( pacl , ACL_REVISION , NO_PROPAGATE_INHERIT_ACE , FILE_GENERIC_READ | FILE_GENERIC_WRITE , psid2 , TRUE , FALSE ) ;
if ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( & desc , SDDL_REVISION_1 , sec_info , & string , & len ) )
{
CHECK_ONE_OF_AND_FREE ( " O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU) " , /* XP */
" O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU) " /* Vista */ ) ;
}
}
2008-12-09 19:26:45 +00:00
static void test_SetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR sec )
{
SECURITY_DESCRIPTOR_CONTROL ref ;
SECURITY_DESCRIPTOR_CONTROL test ;
SECURITY_DESCRIPTOR_CONTROL const mutable
= SE_DACL_AUTO_INHERIT_REQ | SE_SACL_AUTO_INHERIT_REQ
| SE_DACL_AUTO_INHERITED | SE_SACL_AUTO_INHERITED
| SE_DACL_PROTECTED | SE_SACL_PROTECTED
| 0x00000040 | 0x00000080 /* not defined in winnt.h */
;
SECURITY_DESCRIPTOR_CONTROL const immutable
= SE_OWNER_DEFAULTED | SE_GROUP_DEFAULTED
| SE_DACL_PRESENT | SE_DACL_DEFAULTED
| SE_SACL_PRESENT | SE_SACL_DEFAULTED
| SE_RM_CONTROL_VALID | SE_SELF_RELATIVE
;
int bit ;
DWORD dwRevision ;
LPCSTR fmt = " Expected error %s, got %u \n " ;
GetSecurityDescriptorControl ( sec , & ref , & dwRevision ) ;
/* The mutable bits are mutable regardless of the truth of
SE_DACL_PRESENT and / or SE_SACL_PRESENT */
/* Check call barfs if any bit-of-interest is immutable */
for ( bit = 0 ; bit < 16 ; + + bit )
{
SECURITY_DESCRIPTOR_CONTROL const bitOfInterest = 1 < < bit ;
SECURITY_DESCRIPTOR_CONTROL setOrClear = ref & bitOfInterest ;
SECURITY_DESCRIPTOR_CONTROL ctrl ;
DWORD dwExpect = ( bitOfInterest & immutable )
? ERROR_INVALID_PARAMETER : 0xbebecaca ;
LPCSTR strExpect = ( bitOfInterest & immutable )
? " ERROR_INVALID_PARAMETER " : " 0xbebecaca " ;
ctrl = ( bitOfInterest & mutable ) ? ref + bitOfInterest : ref ;
setOrClear ^ = bitOfInterest ;
SetLastError ( 0xbebecaca ) ;
pSetSecurityDescriptorControl ( sec , bitOfInterest , setOrClear ) ;
ok ( GetLastError ( ) = = dwExpect , fmt , strExpect , GetLastError ( ) ) ;
GetSecurityDescriptorControl ( sec , & test , & dwRevision ) ;
expect_eq ( test , ctrl , int , " %x " ) ;
ctrl = ref ;
setOrClear ^ = bitOfInterest ;
SetLastError ( 0xbebecaca ) ;
pSetSecurityDescriptorControl ( sec , bitOfInterest , setOrClear ) ;
ok ( GetLastError ( ) = = dwExpect , fmt , strExpect , GetLastError ( ) ) ;
GetSecurityDescriptorControl ( sec , & test , & dwRevision ) ;
expect_eq ( test , ref , int , " %x " ) ;
}
/* Check call barfs if any bit-to-set is immutable
even when not a bit - of - interest */
for ( bit = 0 ; bit < 16 ; + + bit )
{
SECURITY_DESCRIPTOR_CONTROL const bitsOfInterest = mutable ;
SECURITY_DESCRIPTOR_CONTROL setOrClear = ref & bitsOfInterest ;
SECURITY_DESCRIPTOR_CONTROL ctrl ;
DWORD dwExpect = ( ( 1 < < bit ) & immutable )
? ERROR_INVALID_PARAMETER : 0xbebecaca ;
LPCSTR strExpect = ( ( 1 < < bit ) & immutable )
? " ERROR_INVALID_PARAMETER " : " 0xbebecaca " ;
ctrl = ( ( 1 < < bit ) & immutable ) ? test : ref | mutable ;
setOrClear ^ = bitsOfInterest ;
SetLastError ( 0xbebecaca ) ;
pSetSecurityDescriptorControl ( sec , bitsOfInterest , setOrClear | ( 1 < < bit ) ) ;
ok ( GetLastError ( ) = = dwExpect , fmt , strExpect , GetLastError ( ) ) ;
GetSecurityDescriptorControl ( sec , & test , & dwRevision ) ;
expect_eq ( test , ctrl , int , " %x " ) ;
ctrl = ( ( 1 < < bit ) & immutable ) ? test : ref | ( 1 < < bit ) ;
setOrClear ^ = bitsOfInterest ;
SetLastError ( 0xbebecaca ) ;
pSetSecurityDescriptorControl ( sec , bitsOfInterest , setOrClear | ( 1 < < bit ) ) ;
ok ( GetLastError ( ) = = dwExpect , fmt , strExpect , GetLastError ( ) ) ;
GetSecurityDescriptorControl ( sec , & test , & dwRevision ) ;
expect_eq ( test , ctrl , int , " %x " ) ;
}
}
2008-05-09 17:35:45 +00:00
static void test_PrivateObjectSecurity ( void )
{
SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION ;
SECURITY_DESCRIPTOR_CONTROL ctrl ;
2008-12-09 19:26:45 +00:00
PSECURITY_DESCRIPTOR sec ;
2008-05-09 17:35:45 +00:00
DWORD dwDescSize ;
DWORD dwRevision ;
DWORD retSize ;
LPSTR string ;
ULONG len ;
PSECURITY_DESCRIPTOR buf ;
if ( ! pConvertStringSecurityDescriptorToSecurityDescriptorA )
{
2009-05-17 07:05:22 +00:00
win_skip ( " ConvertStringSecurityDescriptorToSecurityDescriptor is not available \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
2008-12-09 19:26:45 +00:00
ok ( pConvertStringSecurityDescriptorToSecurityDescriptorA (
" O:SY "
" G:S-1-5-21-93476-23408-4576 "
" D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU) "
" (D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576) "
" S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU) " ,
2009-05-17 07:05:22 +00:00
SDDL_REVISION_1 , & sec , & dwDescSize ) , " Creating descriptor failed \n " ) ;
2009-02-08 09:32:24 +00:00
2008-12-09 19:26:45 +00:00
test_SetSecurityDescriptorControl ( sec ) ;
LocalFree ( sec ) ;
ok ( pConvertStringSecurityDescriptorToSecurityDescriptorA (
" O:SY "
" G:S-1-5-21-93476-23408-4576 " ,
SDDL_REVISION_1 , & sec , & dwDescSize ) , " Creating descriptor failed \n " ) ;
test_SetSecurityDescriptorControl ( sec ) ;
LocalFree ( sec ) ;
2008-05-09 17:35:45 +00:00
ok ( pConvertStringSecurityDescriptorToSecurityDescriptorA (
" O:SY "
" G:S-1-5-21-93476-23408-4576 "
" D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576) "
" S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU) " , SDDL_REVISION_1 , & sec , & dwDescSize ) , " Creating descriptor failed \n " ) ;
buf = HeapAlloc ( GetProcessHeap ( ) , 0 , dwDescSize ) ;
pSetSecurityDescriptorControl ( sec , SE_DACL_PROTECTED , SE_DACL_PROTECTED ) ;
GetSecurityDescriptorControl ( sec , & ctrl , & dwRevision ) ;
2008-12-09 19:26:45 +00:00
expect_eq ( ctrl , 0x9014 , int , " %x " ) ;
2008-05-09 17:35:45 +00:00
ok ( GetPrivateObjectSecurity ( sec , GROUP_SECURITY_INFORMATION , buf , dwDescSize , & retSize ) ,
" GetPrivateObjectSecurity failed (err=%u) \n " , GetLastError ( ) ) ;
ok ( retSize < = dwDescSize , " Buffer too small (%d vs %d) \n " , retSize , dwDescSize ) ;
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( buf , SDDL_REVISION_1 , sec_info , & string , & len ) , " Conversion failed \n " ) ;
CHECK_RESULT_AND_FREE ( " G:S-1-5-21-93476-23408-4576 " ) ;
GetSecurityDescriptorControl ( buf , & ctrl , & dwRevision ) ;
expect_eq ( ctrl , 0x8000 , int , " %x " ) ;
ok ( GetPrivateObjectSecurity ( sec , GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION , buf , dwDescSize , & retSize ) ,
" GetPrivateObjectSecurity failed (err=%u) \n " , GetLastError ( ) ) ;
ok ( retSize < = dwDescSize , " Buffer too small (%d vs %d) \n " , retSize , dwDescSize ) ;
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( buf , SDDL_REVISION_1 , sec_info , & string , & len ) , " Conversion failed err=%u \n " , GetLastError ( ) ) ;
2009-10-18 14:57:22 +00:00
CHECK_ONE_OF_AND_FREE ( " G:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576) " ,
" G:S-1-5-21-93476-23408-4576D:P(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576) " ) ; /* Win7 */
2008-05-09 17:35:45 +00:00
GetSecurityDescriptorControl ( buf , & ctrl , & dwRevision ) ;
2009-10-18 14:57:22 +00:00
expect_eq ( ctrl & ( ~ SE_DACL_PROTECTED ) , 0x8004 , int , " %x " ) ;
2008-05-09 17:35:45 +00:00
ok ( GetPrivateObjectSecurity ( sec , sec_info , buf , dwDescSize , & retSize ) ,
" GetPrivateObjectSecurity failed (err=%u) \n " , GetLastError ( ) ) ;
ok ( retSize = = dwDescSize , " Buffer too small (%d vs %d) \n " , retSize , dwDescSize ) ;
ok ( pConvertSecurityDescriptorToStringSecurityDescriptorA ( buf , SDDL_REVISION_1 , sec_info , & string , & len ) , " Conversion failed \n " ) ;
2009-10-18 14:57:22 +00:00
CHECK_ONE_OF_AND_FREE ( " O:SY "
2008-05-09 17:35:45 +00:00
" G:S-1-5-21-93476-23408-4576 "
" D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576) "
2009-10-18 14:57:22 +00:00
" S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU) " ,
" O:SY "
" G:S-1-5-21-93476-23408-4576 "
" D:P(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576) "
" S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU) " ) ; /* Win7 */
2008-05-09 17:35:45 +00:00
GetSecurityDescriptorControl ( buf , & ctrl , & dwRevision ) ;
2009-10-18 14:57:22 +00:00
expect_eq ( ctrl & ( ~ SE_DACL_PROTECTED ) , 0x8014 , int , " %x " ) ;
2008-05-09 17:35:45 +00:00
SetLastError ( 0xdeadbeef ) ;
ok ( GetPrivateObjectSecurity ( sec , sec_info , buf , 5 , & retSize ) = = FALSE , " GetPrivateObjectSecurity should have failed \n " ) ;
ok ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER , " Expected error ERROR_INSUFFICIENT_BUFFER, got %u \n " , GetLastError ( ) ) ;
LocalFree ( sec ) ;
HeapFree ( GetProcessHeap ( ) , 0 , buf ) ;
}
# undef CHECK_RESULT_AND_FREE
# undef CHECK_ONE_OF_AND_FREE
static void test_acls ( void )
{
char buffer [ 256 ] ;
PACL pAcl = ( PACL ) buffer ;
BOOL ret ;
SetLastError ( 0xdeadbeef ) ;
ret = InitializeAcl ( pAcl , sizeof ( ACL ) - 1 , ACL_REVISION ) ;
if ( ! ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
{
2009-05-17 07:05:22 +00:00
win_skip ( " InitializeAcl is not implemented \n " ) ;
2008-05-09 17:35:45 +00:00
return ;
}
ok ( ! ret & & GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER , " InitializeAcl with too small a buffer should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = InitializeAcl ( pAcl , 0xffffffff , ACL_REVISION ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER , " InitializeAcl with too large a buffer should have failed with ERROR_INVALID_PARAMETER instead of %d \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = InitializeAcl ( pAcl , sizeof ( buffer ) , ACL_REVISION1 ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER , " InitializeAcl(ACL_REVISION1) should have failed with ERROR_INVALID_PARAMETER instead of %d \n " , GetLastError ( ) ) ;
ret = InitializeAcl ( pAcl , sizeof ( buffer ) , ACL_REVISION2 ) ;
ok ( ret , " InitializeAcl(ACL_REVISION2) failed with error %d \n " , GetLastError ( ) ) ;
ret = IsValidAcl ( pAcl ) ;
ok ( ret , " IsValidAcl failed with error %d \n " , GetLastError ( ) ) ;
ret = InitializeAcl ( pAcl , sizeof ( buffer ) , ACL_REVISION3 ) ;
ok ( ret , " InitializeAcl(ACL_REVISION3) failed with error %d \n " , GetLastError ( ) ) ;
ret = IsValidAcl ( pAcl ) ;
ok ( ret , " IsValidAcl failed with error %d \n " , GetLastError ( ) ) ;
2008-12-09 19:26:45 +00:00
SetLastError ( 0xdeadbeef ) ;
2008-05-09 17:35:45 +00:00
ret = InitializeAcl ( pAcl , sizeof ( buffer ) , ACL_REVISION4 ) ;
2008-12-09 19:26:45 +00:00
if ( GetLastError ( ) ! = ERROR_INVALID_PARAMETER )
{
ok ( ret , " InitializeAcl(ACL_REVISION4) failed with error %d \n " , GetLastError ( ) ) ;
2008-05-09 17:35:45 +00:00
2008-12-09 19:26:45 +00:00
ret = IsValidAcl ( pAcl ) ;
ok ( ret , " IsValidAcl failed with error %d \n " , GetLastError ( ) ) ;
}
else
win_skip ( " ACL_REVISION4 is not implemented on NT4 \n " ) ;
2008-05-09 17:35:45 +00:00
SetLastError ( 0xdeadbeef ) ;
ret = InitializeAcl ( pAcl , sizeof ( buffer ) , - 1 ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INVALID_PARAMETER , " InitializeAcl(-1) failed with error %d \n " , GetLastError ( ) ) ;
2007-03-06 11:59:18 +00:00
}
2008-09-14 18:24:25 +00:00
static void test_GetSecurityInfo ( void )
{
HANDLE obj ;
PSECURITY_DESCRIPTOR sd ;
PSID owner , group ;
PACL dacl ;
DWORD ret ;
if ( ! pGetSecurityInfo )
{
win_skip ( " GetSecurityInfo is not available \n " ) ;
return ;
}
/* Create something. Files have lots of associated security info. */
obj = CreateFile ( myARGV [ 0 ] , GENERIC_READ , FILE_SHARE_READ , NULL ,
OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL ) ;
if ( obj = = INVALID_HANDLE_VALUE )
{
skip ( " Couldn't create an object for GetSecurityInfo test \n " ) ;
return ;
}
ret = pGetSecurityInfo ( obj , SE_FILE_OBJECT ,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION ,
& owner , & group , & dacl , NULL , & sd ) ;
if ( ret = = ERROR_CALL_NOT_IMPLEMENTED )
{
win_skip ( " GetSecurityInfo is not implemented \n " ) ;
CloseHandle ( obj ) ;
return ;
}
ok ( ret = = ERROR_SUCCESS , " GetSecurityInfo returned %d \n " , ret ) ;
ok ( sd ! = NULL , " GetSecurityInfo \n " ) ;
ok ( owner ! = NULL , " GetSecurityInfo \n " ) ;
ok ( group ! = NULL , " GetSecurityInfo \n " ) ;
ok ( dacl ! = NULL , " GetSecurityInfo \n " ) ;
ok ( IsValidAcl ( dacl ) , " GetSecurityInfo \n " ) ;
LocalFree ( sd ) ;
2008-12-09 19:26:45 +00:00
if ( ! pCreateWellKnownSid )
{
win_skip ( " NULL parameter test would crash on NT4 \n " ) ;
CloseHandle ( obj ) ;
return ;
}
2008-09-14 18:24:25 +00:00
/* If we don't ask for the security descriptor, Windows will still give us
the other stuff , leaving us no way to free it . */
ret = pGetSecurityInfo ( obj , SE_FILE_OBJECT ,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION ,
& owner , & group , & dacl , NULL , NULL ) ;
ok ( ret = = ERROR_SUCCESS , " GetSecurityInfo returned %d \n " , ret ) ;
ok ( owner ! = NULL , " GetSecurityInfo \n " ) ;
ok ( group ! = NULL , " GetSecurityInfo \n " ) ;
ok ( dacl ! = NULL , " GetSecurityInfo \n " ) ;
2009-05-17 07:05:22 +00:00
ok ( IsValidAcl ( dacl ) , " GetSecurityInfo \n " ) ;
2008-09-14 18:24:25 +00:00
CloseHandle ( obj ) ;
}
2009-10-18 14:57:22 +00:00
static void test_GetSidSubAuthority ( void )
{
PSID psid = NULL ;
if ( ! pGetSidSubAuthority | | ! pConvertStringSidToSidA | | ! pIsValidSid | | ! pGetSidSubAuthorityCount )
{
win_skip ( " Some functions not available \n " ) ;
return ;
}
/* Note: on windows passing in an invalid index like -1, lets GetSidSubAuthority return 0x05000000 but
still GetLastError returns ERROR_SUCCESS then . We don ' t test these unlikely cornercases here for now */
ok ( pConvertStringSidToSidA ( " S-1-5-21-93476-23408-4576 " , & psid ) , " ConvertStringSidToSidA failed \n " ) ;
ok ( pIsValidSid ( psid ) , " Sid is not valid \n " ) ;
SetLastError ( 0xbebecaca ) ;
ok ( * pGetSidSubAuthorityCount ( psid ) = = 4 , " GetSidSubAuthorityCount gave %d expected 4 \n " , * pGetSidSubAuthorityCount ( psid ) ) ;
ok ( GetLastError ( ) = = 0 , " GetLastError returned %d instead of 0 \n " , GetLastError ( ) ) ;
SetLastError ( 0xbebecaca ) ;
ok ( * pGetSidSubAuthority ( psid , 0 ) = = 21 , " GetSidSubAuthority gave %d expected 21 \n " , * pGetSidSubAuthority ( psid , 0 ) ) ;
ok ( GetLastError ( ) = = 0 , " GetLastError returned %d instead of 0 \n " , GetLastError ( ) ) ;
SetLastError ( 0xbebecaca ) ;
ok ( * pGetSidSubAuthority ( psid , 1 ) = = 93476 , " GetSidSubAuthority gave %d expected 93476 \n " , * pGetSidSubAuthority ( psid , 1 ) ) ;
ok ( GetLastError ( ) = = 0 , " GetLastError returned %d instead of 0 \n " , GetLastError ( ) ) ;
SetLastError ( 0xbebecaca ) ;
todo_wine ok ( * pGetSidSubAuthority ( psid , 4 ) = = 0 , " GetSidSubAuthority gave %d,expected 0 \n " , * pGetSidSubAuthority ( psid , 4 ) ) ;
ok ( GetLastError ( ) = = 0 , " GetLastError returned %d instead of 0 \n " , GetLastError ( ) ) ;
LocalFree ( psid ) ;
}
2007-03-06 11:59:18 +00:00
START_TEST ( security )
{
init ( ) ;
if ( ! hmod ) return ;
2008-05-09 17:35:45 +00:00
if ( myARGC > = 3 )
{
test_process_security_child ( ) ;
return ;
}
2007-03-06 11:59:18 +00:00
test_sid ( ) ;
test_trustee ( ) ;
test_luid ( ) ;
2008-05-09 17:35:45 +00:00
test_CreateWellKnownSid ( ) ;
2007-03-06 11:59:18 +00:00
test_FileSecurity ( ) ;
2008-05-09 17:35:45 +00:00
test_AccessCheck ( ) ;
test_token_attr ( ) ;
test_LookupAccountSid ( ) ;
test_LookupAccountName ( ) ;
test_security_descriptor ( ) ;
test_process_security ( ) ;
test_impersonation_level ( ) ;
test_SetEntriesInAcl ( ) ;
test_GetNamedSecurityInfoA ( ) ;
test_ConvertStringSecurityDescriptor ( ) ;
test_ConvertSecurityDescriptorToString ( ) ;
test_PrivateObjectSecurity ( ) ;
test_acls ( ) ;
2008-09-14 18:24:25 +00:00
test_GetSecurityInfo ( ) ;
2009-10-18 14:57:22 +00:00
test_GetSidSubAuthority ( ) ;
2007-03-06 11:59:18 +00:00
}