2004-08-09 20:47:22 +02: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
2006-05-18 14:49:52 +02:00
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2004-08-09 20:47:22 +02:00
*/
2006-08-04 14:17:58 +02:00
# include <stdarg.h>
2004-08-09 20:47:22 +02:00
# include <stdio.h>
2006-08-04 14:17:58 +02:00
# include "ntstatus.h"
# define WIN32_NO_STATUS
2004-08-09 20:47:22 +02:00
# include "windef.h"
# include "winbase.h"
# include "winerror.h"
2004-08-16 23:07:50 +02:00
# include "aclapi.h"
2004-09-16 22:27:52 +02:00
# include "winnt.h"
2006-05-13 17:56:59 +02:00
# include "sddl.h"
2006-08-04 14:17:58 +02:00
# include "ntsecapi.h"
2006-12-01 00:53:21 +01:00
# include "lmcons.h"
2007-01-25 07:43:18 +01:00
# include "winternl.h"
2006-08-04 14:17:58 +02:00
# include "wine/test.h"
2004-08-09 20:47:22 +02:00
2006-03-26 13:39:58 +02:00
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 ) ;
2004-08-09 20:47:22 +02:00
typedef BOOL ( WINAPI * fnConvertSidToStringSidA ) ( PSID pSid , LPSTR * str ) ;
2004-09-16 22:27:52 +02:00
typedef BOOL ( WINAPI * fnConvertStringSidToSidA ) ( LPCSTR str , PSID pSid ) ;
2005-03-28 12:00:59 +02:00
typedef BOOL ( WINAPI * fnGetFileSecurityA ) ( LPCSTR , SECURITY_INFORMATION ,
PSECURITY_DESCRIPTOR , DWORD , LPDWORD ) ;
2005-06-27 21:48:35 +02:00
typedef DWORD ( WINAPI * fnRtlAdjustPrivilege ) ( ULONG , BOOLEAN , BOOLEAN , PBOOLEAN ) ;
2006-07-20 13:05:46 +02:00
typedef BOOL ( WINAPI * fnCreateWellKnownSid ) ( WELL_KNOWN_SID_TYPE , PSID , PSID , DWORD * ) ;
2004-08-09 20:47:22 +02:00
2006-08-04 14:17:58 +02:00
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 ) ;
2007-01-25 07:43:18 +01:00
static NTSTATUS ( WINAPI * pNtQueryObject ) ( HANDLE , OBJECT_INFORMATION_CLASS , PVOID , ULONG , PULONG ) ;
2006-08-04 14:17:58 +02:00
2004-11-04 05:52:17 +01:00
static HMODULE hmod ;
2007-01-25 07:43:18 +01:00
static int myARGC ;
static char * * myARGV ;
2004-11-04 05:52:17 +01:00
2005-02-14 12:06:16 +01:00
fnBuildTrusteeWithSidA pBuildTrusteeWithSidA ;
fnBuildTrusteeWithNameA pBuildTrusteeWithNameA ;
2006-03-26 13:39:58 +02:00
fnBuildTrusteeWithObjectsAndNameA pBuildTrusteeWithObjectsAndNameA ;
fnBuildTrusteeWithObjectsAndSidA pBuildTrusteeWithObjectsAndSidA ;
fnGetTrusteeNameA pGetTrusteeNameA ;
2004-08-09 20:47:22 +02:00
fnConvertSidToStringSidA pConvertSidToStringSidA ;
2004-09-16 22:27:52 +02:00
fnConvertStringSidToSidA pConvertStringSidToSidA ;
2005-03-28 12:00:59 +02:00
fnGetFileSecurityA pGetFileSecurityA ;
2005-06-27 21:48:35 +02:00
fnRtlAdjustPrivilege pRtlAdjustPrivilege ;
2006-07-20 13:05:46 +02:00
fnCreateWellKnownSid pCreateWellKnownSid ;
2006-08-04 14:17:58 +02:00
fnLsaQueryInformationPolicy pLsaQueryInformationPolicy ;
fnLsaClose pLsaClose ;
fnLsaFreeMemory pLsaFreeMemory ;
fnLsaOpenPolicy pLsaOpenPolicy ;
2004-09-16 22:27:52 +02:00
struct sidRef
{
SID_IDENTIFIER_AUTHORITY auth ;
const char * refStr ;
} ;
2004-08-09 20:47:22 +02:00
2004-11-04 05:52:17 +01:00
static void init ( void )
{
2007-01-25 07:43:18 +01:00
HMODULE hntdll = GetModuleHandleA ( " ntdll.dll " ) ;
2004-11-04 05:52:17 +01:00
hmod = GetModuleHandle ( " advapi32.dll " ) ;
2007-01-25 07:43:18 +01:00
myARGC = winetest_get_mainargs ( & myARGV ) ;
pNtQueryObject = ( void * ) GetProcAddress ( hntdll , " NtQueryObject " ) ;
2004-11-04 05:52:17 +01:00
}
2006-08-13 10:53:29 +02:00
static void test_str_sid ( const char * str_sid )
2006-07-29 13:45:23 +02:00
{
PSID psid ;
char * temp ;
if ( pConvertStringSidToSidA ( str_sid , & psid ) )
{
if ( pConvertSidToStringSidA ( psid , & temp ) )
{
trace ( " %s: %s \n " , str_sid , temp ) ;
LocalFree ( temp ) ;
}
2006-10-17 21:32:00 +02:00
LocalFree ( psid ) ;
2006-07-29 13:45:23 +02:00
}
else
2006-08-27 22:36:23 +02:00
{
if ( GetLastError ( ) ! = ERROR_INVALID_SID )
2006-10-04 12:37:30 +02:00
trace ( " %s: couldn't be converted, returned %d \n " , str_sid , GetLastError ( ) ) ;
2006-08-27 22:36:23 +02:00
else
trace ( " %s: couldn't be converted \n " , str_sid ) ;
}
2006-07-29 13:45:23 +02:00
}
2005-06-09 11:48:36 +02:00
static void test_sid ( void )
2004-08-09 20:47:22 +02:00
{
2004-09-16 22:27:52 +02: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 ;
2004-08-09 20:47:22 +02:00
BOOL r ;
2004-09-16 22:27:52 +02:00
LPSTR str = NULL ;
2004-08-09 20:47:22 +02:00
2004-09-16 22:27:52 +02:00
pConvertSidToStringSidA = ( fnConvertSidToStringSidA )
GetProcAddress ( hmod , " ConvertSidToStringSidA " ) ;
if ( ! pConvertSidToStringSidA )
return ;
pConvertStringSidToSidA = ( fnConvertStringSidToSidA )
GetProcAddress ( hmod , " ConvertStringSidToSidA " ) ;
if ( ! pConvertStringSidToSidA )
return ;
2004-08-09 20:47:22 +02:00
2004-09-16 22:27:52 +02:00
r = pConvertStringSidToSidA ( NULL , NULL ) ;
ok ( ! r , " expected failure with NULL parameters \n " ) ;
if ( GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
2004-08-09 20:47:22 +02:00
return ;
2004-09-16 22:27:52 +02:00
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
2006-10-04 12:37:30 +02:00
" expected GetLastError() is ERROR_INVALID_PARAMETER, got %d \n " ,
2004-09-16 22:27:52 +02:00
GetLastError ( ) ) ;
r = pConvertStringSidToSidA ( refs [ 0 ] . refStr , NULL ) ;
ok ( ! r & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
2006-10-04 12:37:30 +02:00
" expected GetLastError() is ERROR_INVALID_PARAMETER, got %d \n " ,
2004-09-16 22:27:52 +02:00
GetLastError ( ) ) ;
r = pConvertStringSidToSidA ( NULL , & str ) ;
ok ( ! r & & GetLastError ( ) = = ERROR_INVALID_PARAMETER ,
2006-10-04 12:37:30 +02:00
" expected GetLastError() is ERROR_INVALID_PARAMETER, got %d \n " ,
2004-09-16 22:27:52 +02:00
GetLastError ( ) ) ;
r = pConvertStringSidToSidA ( noSubAuthStr , & psid ) ;
ok ( ! r ,
" expected failure with no sub authorities \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_SID ,
2006-10-04 12:37:30 +02:00
" expected GetLastError() is ERROR_INVALID_SID, got %d \n " ,
2004-09-16 22:27:52 +02:00
GetLastError ( ) ) ;
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 " ) ;
2005-03-14 18:20:58 +01:00
if ( r )
{
ok ( ! strcmp ( str , refs [ i ] . refStr ) ,
" incorrect sid, expected %s, got %s \n " , refs [ i ] . refStr , str ) ;
2004-09-16 22:27:52 +02:00
LocalFree ( str ) ;
2005-03-14 18:20:58 +01:00
}
2004-09-16 22:27:52 +02:00
if ( psid )
FreeSid ( psid ) ;
r = pConvertStringSidToSidA ( refs [ i ] . refStr , & psid ) ;
ok ( r , " failed to parse sid string \n " ) ;
pisid = ( PISID ) psid ;
ok ( pisid & &
! memcmp ( pisid - > IdentifierAuthority . Value , refs [ i ] . auth . Value ,
sizeof ( refs [ i ] . auth ) ) ,
" string sid %s didn't parse to expected value \n "
2006-10-04 12:37:30 +02:00
" (got 0x%04x%08x, expected 0x%04x%08x) \n " ,
2004-09-16 22:27:52 +02: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 ) ;
}
2006-07-29 13:45:23 +02:00
2006-08-12 14:27:57 +02:00
trace ( " String SIDs: \n " ) ;
2006-07-29 13:45:23 +02:00
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 " ) ;
2004-08-16 23:07:50 +02:00
}
2005-06-09 11:48:36 +02:00
static void test_trustee ( void )
2004-08-16 23:07:50 +02:00
{
2006-03-26 13:39:58 +02: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 ;
2004-08-16 23:07:50 +02:00
TRUSTEE trustee ;
PSID psid ;
2006-03-26 13:39:58 +02:00
char szObjectTypeName [ ] = " ObjectTypeName " ;
char szInheritedObjectTypeName [ ] = " InheritedObjectTypeName " ;
char szTrusteeName [ ] = " szTrusteeName " ;
2006-03-28 14:43:18 +02:00
SID_IDENTIFIER_AUTHORITY auth = { { 0x11 , 0x22 , 0 , 0 , 0 , 0 } } ;
2006-03-26 13:39:58 +02:00
memset ( & ZeroGuid , 0x00 , sizeof ( ZeroGuid ) ) ;
2004-08-16 23:07:50 +02:00
2005-02-14 12:06:16 +01:00
pBuildTrusteeWithSidA = ( fnBuildTrusteeWithSidA )
GetProcAddress ( hmod , " BuildTrusteeWithSidA " ) ;
pBuildTrusteeWithNameA = ( fnBuildTrusteeWithNameA )
GetProcAddress ( hmod , " BuildTrusteeWithNameA " ) ;
2006-03-26 13:39:58 +02:00
pBuildTrusteeWithObjectsAndNameA = ( fnBuildTrusteeWithObjectsAndNameA )
GetProcAddress ( hmod , " BuildTrusteeWithObjectsAndNameA " ) ;
pBuildTrusteeWithObjectsAndSidA = ( fnBuildTrusteeWithObjectsAndSidA )
GetProcAddress ( hmod , " BuildTrusteeWithObjectsAndSidA " ) ;
pGetTrusteeNameA = ( fnGetTrusteeNameA )
GetProcAddress ( hmod , " GetTrusteeNameA " ) ;
if ( ! pBuildTrusteeWithSidA | | ! pBuildTrusteeWithNameA | |
! pBuildTrusteeWithObjectsAndNameA | | ! pBuildTrusteeWithObjectsAndSidA | |
! pGetTrusteeNameA )
2005-02-14 12:06:16 +01:00
return ;
2004-11-03 23:14:55 +01:00
if ( ! AllocateAndInitializeSid ( & auth , 1 , 42 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , & psid ) )
{
trace ( " failed to init SID \n " ) ;
return ;
}
2004-08-16 23:07:50 +02:00
2006-03-26 13:39:58 +02:00
/* test BuildTrusteeWithSidA */
2004-08-16 23:07:50 +02:00
memset ( & trustee , 0xff , sizeof trustee ) ;
2005-02-14 12:06:16 +01:00
pBuildTrusteeWithSidA ( & trustee , psid ) ;
2004-08-16 23:07:50 +02:00
ok ( trustee . pMultipleTrustee = = NULL , " pMultipleTrustee wrong \n " ) ;
ok ( trustee . MultipleTrusteeOperation = = NO_MULTIPLE_TRUSTEE ,
" MultipleTrusteeOperation wrong \n " ) ;
ok ( trustee . TrusteeForm = = TRUSTEE_IS_SID , " TrusteeForm wrong \n " ) ;
ok ( trustee . TrusteeType = = TRUSTEE_IS_UNKNOWN , " TrusteeType wrong \n " ) ;
ok ( trustee . ptstrName = = ( LPSTR ) psid , " ptstrName wrong \n " ) ;
2006-03-26 13:39:58 +02: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 " ) ;
2004-08-16 23:07:50 +02:00
FreeSid ( psid ) ;
2004-08-09 20:47:22 +02:00
2004-08-19 21:01:12 +02:00
/* test BuildTrusteeWithNameA */
memset ( & trustee , 0xff , sizeof trustee ) ;
2006-03-26 13:39:58 +02:00
pBuildTrusteeWithNameA ( & trustee , szTrusteeName ) ;
2004-08-19 21:01:12 +02:00
ok ( trustee . pMultipleTrustee = = NULL , " pMultipleTrustee wrong \n " ) ;
ok ( trustee . MultipleTrusteeOperation = = NO_MULTIPLE_TRUSTEE ,
" MultipleTrusteeOperation wrong \n " ) ;
ok ( trustee . TrusteeForm = = TRUSTEE_IS_NAME , " TrusteeForm wrong \n " ) ;
ok ( trustee . TrusteeType = = TRUSTEE_IS_UNKNOWN , " TrusteeType wrong \n " ) ;
2006-03-26 13:39:58 +02: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 " ) ;
/* 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 " ) ;
2004-08-19 21:01:12 +02:00
}
2004-11-04 05:52:17 +01: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
# define SE_CHANGE_NOTIFY_PRIVILLEGE 23L
# 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 ;
2005-02-14 22:04:45 +01:00
pAllocateLocallyUniqueId = ( void * ) GetProcAddress ( hmod , " AllocateLocallyUniqueId " ) ;
2004-11-04 05:52:17 +01:00
if ( ! pAllocateLocallyUniqueId ) return ;
ret = pAllocateLocallyUniqueId ( & luid1 ) ;
if ( ! ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
return ;
ok ( ret ,
2006-10-04 12:37:30 +02:00
" AllocateLocallyUniqueId failed: %d \n " , GetLastError ( ) ) ;
2004-12-27 18:26:37 +01:00
ret = pAllocateLocallyUniqueId ( & luid2 ) ;
ok ( ret ,
2006-10-04 12:37:30 +02:00
" AllocateLocallyUniqueId failed: %d \n " , GetLastError ( ) ) ;
2004-11-04 05:52:17 +01: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 " ) ;
2004-12-27 18:26:37 +01:00
ret = pAllocateLocallyUniqueId ( NULL ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_NOACCESS ,
2006-10-04 12:37:30 +02:00
" AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %d \n " ,
2004-11-04 05:52:17 +01:00
GetLastError ( ) ) ;
}
static void test_lookupPrivilegeName ( void )
{
2005-06-09 11:48:36 +02:00
BOOL ( WINAPI * pLookupPrivilegeNameA ) ( LPCSTR , PLUID , LPSTR , LPDWORD ) ;
2004-11-04 05:52:17 +01: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 */
2005-02-14 22:04:45 +01:00
pLookupPrivilegeNameA = ( void * ) GetProcAddress ( hmod , " LookupPrivilegeNameA " ) ;
2004-11-04 05:52:17 +01:00
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 ;
2004-12-27 18:26:37 +01:00
ret = pLookupPrivilegeNameA ( NULL , & luid , NULL , & cchName ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ,
2006-10-04 12:37:30 +02:00
" LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %d \n " ,
2004-11-04 05:52:17 +01:00
GetLastError ( ) ) ;
ok ( cchName = = strlen ( " SeCreateTokenPrivilege " ) + 1 ,
" LookupPrivilegeNameA returned an incorrect required length for \n "
2006-10-04 12:37:30 +02:00
" SeCreateTokenPrivilege (got %d, expected %d) \n " , cchName ,
2006-06-13 13:56:18 +02:00
lstrlenA ( " SeCreateTokenPrivilege " ) + 1 ) ;
2004-11-04 05:52:17 +01: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 "
2006-10-04 12:37:30 +02:00
" SeCreateTokenPrivilege (got %d, expected %d) \n " , cchName ,
2005-02-14 12:52:48 +01:00
( int ) strlen ( " SeCreateTokenPrivilege " ) ) ;
2004-11-04 05:52:17 +01:00
/* check known values */
for ( i = SE_MIN_WELL_KNOWN_PRIVILEGE ; i < SE_MAX_WELL_KNOWN_PRIVILEGE ; i + + )
{
luid . LowPart = i ;
cchName = sizeof ( buf ) ;
2004-12-27 18:26:37 +01:00
ret = pLookupPrivilegeNameA ( NULL , & luid , buf , & cchName ) ;
2005-03-22 17:39:02 +01:00
ok ( ret | | GetLastError ( ) = = ERROR_NO_SUCH_PRIVILEGE ,
2006-10-04 12:37:30 +02:00
" LookupPrivilegeNameA(0.%d) failed: %d \n " , i , GetLastError ( ) ) ;
2004-11-04 05:52:17 +01:00
}
/* check a bogus LUID */
luid . LowPart = 0xdeadbeef ;
cchName = sizeof ( buf ) ;
2004-12-27 18:26:37 +01:00
ret = pLookupPrivilegeNameA ( NULL , & luid , buf , & cchName ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_NO_SUCH_PRIVILEGE ,
2006-10-04 12:37:30 +02:00
" LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d \n " ,
2004-11-04 05:52:17 +01:00
GetLastError ( ) ) ;
/* check on a bogus system */
luid . LowPart = SE_CREATE_TOKEN_PRIVILEGE ;
cchName = sizeof ( buf ) ;
2004-12-27 18:26:37 +01:00
ret = pLookupPrivilegeNameA ( " b0gu5.Nam3 " , & luid , buf , & cchName ) ;
ok ( ! ret & & GetLastError ( ) = = RPC_S_SERVER_UNAVAILABLE ,
2006-10-04 12:37:30 +02:00
" LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE: %d \n " ,
2004-11-04 05:52:17 +01:00
GetLastError ( ) ) ;
}
struct NameToLUID
{
const char * name ;
2005-02-14 22:04:45 +01:00
DWORD lowPart ;
2004-11-04 05:52:17 +01:00
} ;
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 } ,
{ " SeChangeNotifyPrivilege " , SE_CHANGE_NOTIFY_PRIVILLEGE } ,
{ " 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 */
2005-02-14 22:04:45 +01:00
pLookupPrivilegeValueA = ( void * ) GetProcAddress ( hmod , " LookupPrivilegeValueA " ) ;
2004-11-04 05:52:17 +01:00
if ( ! pLookupPrivilegeValueA ) return ;
ret = pLookupPrivilegeValueA ( NULL , " SeCreateTokenPrivilege " , & luid ) ;
if ( ! ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
return ;
/* check a bogus system name */
2004-12-27 18:26:37 +01:00
ret = pLookupPrivilegeValueA ( " b0gu5.Nam3 " , " SeCreateTokenPrivilege " , & luid ) ;
ok ( ! ret & & GetLastError ( ) = = RPC_S_SERVER_UNAVAILABLE ,
2006-10-04 12:37:30 +02:00
" LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE: %d \n " ,
2004-11-04 05:52:17 +01:00
GetLastError ( ) ) ;
/* check a NULL string */
2004-12-27 18:26:37 +01:00
ret = pLookupPrivilegeValueA ( NULL , 0 , & luid ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_NO_SUCH_PRIVILEGE ,
2006-10-04 12:37:30 +02:00
" LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d \n " ,
2004-11-04 05:52:17 +01:00
GetLastError ( ) ) ;
/* check a bogus privilege name */
2004-12-27 18:26:37 +01:00
ret = pLookupPrivilegeValueA ( NULL , " SeBogusPrivilege " , & luid ) ;
ok ( ! ret & & GetLastError ( ) = = ERROR_NO_SUCH_PRIVILEGE ,
2006-10-04 12:37:30 +02:00
" LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d \n " ,
2004-11-04 05:52:17 +01:00
GetLastError ( ) ) ;
/* check case insensitive */
2004-12-27 18:26:37 +01:00
ret = pLookupPrivilegeValueA ( NULL , " sEcREATEtOKENpRIVILEGE " , & luid ) ;
ok ( ret ,
2006-10-04 12:37:30 +02:00
" LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %d \n " ,
2004-11-04 05:52:17 +01: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 ( ) ;
}
2005-03-28 12:00:59 +02:00
static void test_FileSecurity ( void )
{
char directory [ MAX_PATH ] ;
DWORD retval , outSize ;
BOOL result ;
BYTE buffer [ 0x40 ] ;
pGetFileSecurityA = ( fnGetFileSecurityA )
GetProcAddress ( hmod , " GetFileSecurityA " ) ;
if ( ! pGetFileSecurityA )
return ;
retval = GetTempPathA ( sizeof ( directory ) , directory ) ;
if ( ! retval ) {
trace ( " GetTempPathA failed \n " ) ;
return ;
}
strcpy ( directory , " \\ Should not exist " ) ;
SetLastError ( NO_ERROR ) ;
result = pGetFileSecurityA ( directory , OWNER_SECURITY_INFORMATION , buffer , 0x40 , & outSize ) ;
2005-03-29 13:31:18 +02:00
ok ( ! result , " GetFileSecurityA should fail for not existing directories/files \n " ) ;
2005-03-31 12:07:11 +02:00
ok ( ( GetLastError ( ) = = ERROR_FILE_NOT_FOUND ) | |
( GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED ) ,
" last error ERROR_FILE_NOT_FOUND / ERROR_CALL_NOT_IMPLEMENTED (98) "
2006-10-04 12:37:30 +02:00
" expected, got %d \n " , GetLastError ( ) ) ;
2005-03-28 12:00:59 +02:00
}
2005-06-09 12:03:11 +02: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 ;
2007-02-15 17:25:20 +01:00
HANDLE ProcessToken ;
2005-06-09 12:03:11 +02:00
BOOL ret ;
DWORD PrivSetLen ;
PRIVILEGE_SET * PrivSet ;
BOOL res ;
2005-06-27 21:48:35 +02:00
HMODULE NtDllModule ;
BOOLEAN Enabled ;
2007-01-25 07:41:39 +01:00
DWORD err ;
2005-06-27 21:48:35 +02:00
NtDllModule = GetModuleHandle ( " ntdll.dll " ) ;
if ( ! NtDllModule )
{
trace ( " not running on NT, skipping test \n " ) ;
return ;
}
pRtlAdjustPrivilege = ( fnRtlAdjustPrivilege )
GetProcAddress ( NtDllModule , " RtlAdjustPrivilege " ) ;
if ( ! pRtlAdjustPrivilege ) return ;
2005-06-09 12:03:11 +02:00
2005-06-22 14:00:01 +02:00
Acl = HeapAlloc ( GetProcessHeap ( ) , 0 , 256 ) ;
res = InitializeAcl ( Acl , 256 , ACL_REVISION ) ;
if ( ! res & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
{
2007-01-25 07:43:18 +01:00
skip ( " ACLs not implemented - skipping tests \n " ) ;
2005-06-22 14:00:01 +02:00
return ;
}
2006-10-04 12:37:30 +02:00
ok ( res , " InitializeAcl failed with error %d \n " , GetLastError ( ) ) ;
2005-06-22 14:00:01 +02:00
2005-06-09 12:03:11 +02:00
res = AllocateAndInitializeSid ( & SIDAuthWorld , 1 , SECURITY_WORLD_RID , 0 , 0 , 0 , 0 , 0 , 0 , 0 , & EveryoneSid ) ;
2006-10-04 12:37:30 +02:00
ok ( res , " AllocateAndInitializeSid failed with error %d \n " , GetLastError ( ) ) ;
2005-06-09 12:03:11 +02:00
res = AllocateAndInitializeSid ( & SIDAuthNT , 2 , SECURITY_BUILTIN_DOMAIN_RID ,
DOMAIN_ALIAS_RID_ADMINS , 0 , 0 , 0 , 0 , 0 , 0 , & AdminSid ) ;
2006-10-04 12:37:30 +02:00
ok ( res , " AllocateAndInitializeSid failed with error %d \n " , GetLastError ( ) ) ;
2005-06-09 12:03:11 +02:00
res = AllocateAndInitializeSid ( & SIDAuthNT , 2 , SECURITY_BUILTIN_DOMAIN_RID ,
DOMAIN_ALIAS_RID_USERS , 0 , 0 , 0 , 0 , 0 , 0 , & UsersSid ) ;
2006-10-04 12:37:30 +02:00
ok ( res , " AllocateAndInitializeSid failed with error %d \n " , GetLastError ( ) ) ;
2005-06-09 12:03:11 +02:00
res = AddAccessAllowedAce ( Acl , ACL_REVISION , KEY_READ , EveryoneSid ) ;
2006-10-04 12:37:30 +02:00
ok ( res , " AddAccessAllowedAceEx failed with error %d \n " , GetLastError ( ) ) ;
2005-06-09 12:03:11 +02:00
2007-01-25 07:41:39 +01:00
res = AddAccessDeniedAce ( Acl , ACL_REVISION , KEY_SET_VALUE , AdminSid ) ;
ok ( res , " AddAccessDeniedAce failed with error %d \n " , GetLastError ( ) ) ;
2005-06-09 12:03:11 +02:00
SecurityDescriptor = HeapAlloc ( GetProcessHeap ( ) , 0 , SECURITY_DESCRIPTOR_MIN_LENGTH ) ;
res = InitializeSecurityDescriptor ( SecurityDescriptor , SECURITY_DESCRIPTOR_REVISION ) ;
2006-10-04 12:37:30 +02:00
ok ( res , " InitializeSecurityDescriptor failed with error %d \n " , GetLastError ( ) ) ;
2005-06-09 12:03:11 +02:00
res = SetSecurityDescriptorDacl ( SecurityDescriptor , TRUE , Acl , FALSE ) ;
2006-10-04 12:37:30 +02:00
ok ( res , " SetSecurityDescriptorDacl failed with error %d \n " , GetLastError ( ) ) ;
2005-06-09 12:03:11 +02:00
PrivSetLen = FIELD_OFFSET ( PRIVILEGE_SET , Privilege [ 16 ] ) ;
PrivSet = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , PrivSetLen ) ;
PrivSet - > PrivilegeCount = 16 ;
2007-02-15 17:25:20 +01:00
res = OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_DUPLICATE | TOKEN_QUERY , & ProcessToken ) ;
ok ( res , " OpenProcessToken failed with error %d \n " , GetLastError ( ) ) ;
2005-06-09 12:03:11 +02:00
2005-06-27 21:48:35 +02:00
pRtlAdjustPrivilege ( SE_SECURITY_PRIVILEGE , FALSE , TRUE , & Enabled ) ;
2007-02-15 17:25:20 +01:00
res = DuplicateToken ( ProcessToken , SecurityIdentification , & Token ) ;
ok ( res , " DuplicateToken failed with error %d \n " , GetLastError ( ) ) ;
2005-06-09 12:03:11 +02:00
2007-01-25 07:41:39 +01:00
/* 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 ) ;
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 " ) ;
2005-06-09 12:03:11 +02:00
ret = AccessCheck ( SecurityDescriptor , Token , KEY_READ , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
2006-10-04 12:37:30 +02:00
ok ( ret , " AccessCheck failed with error %d \n " , GetLastError ( ) ) ;
2005-06-29 22:14:16 +02:00
ok ( AccessStatus & & ( Access = = KEY_READ ) ,
2006-10-04 12:37:30 +02:00
" AccessCheck failed to grant access with error %d \n " ,
2005-06-09 12:03:11 +02:00
GetLastError ( ) ) ;
ret = AccessCheck ( SecurityDescriptor , Token , MAXIMUM_ALLOWED , & Mapping ,
PrivSet , & PrivSetLen , & Access , & AccessStatus ) ;
2006-10-04 12:37:30 +02:00
ok ( ret , " AccessCheck failed with error %d \n " , GetLastError ( ) ) ;
2005-06-29 22:14:16 +02:00
ok ( AccessStatus ,
2006-10-04 12:37:30 +02:00
" AccessCheck failed to grant any access with error %d \n " ,
2005-06-09 12:03:11 +02:00
GetLastError ( ) ) ;
2006-10-04 12:37:30 +02:00
trace ( " AccessCheck with MAXIMUM_ALLOWED got Access 0x%08x \n " , Access ) ;
2005-06-09 12:03:11 +02:00
2007-01-25 07:41:39 +01:00
/* Access denied by SD */
SetLastError ( 0xdeadbeef ) ;
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 ) ;
2005-06-27 21:48:35 +02:00
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 ,
2006-10-04 12:37:30 +02:00
" AccessCheck should have failed with ERROR_PRIVILEGE_NOT_HELD, instead of %d \n " ,
2005-06-27 21:48:35 +02:00
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 ,
2006-10-04 12:37:30 +02:00
" AccessCheck should have succeeded, error %d \n " ,
2005-06-27 21:48:35 +02:00
GetLastError ( ) ) ;
ok ( Access = = ACCESS_SYSTEM_SECURITY ,
2006-10-04 12:37:30 +02:00
" Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08x \n " ,
2005-06-27 21:48:35 +02:00
Access ) ;
}
else
2005-06-28 15:52:01 +02:00
trace ( " Couldn't get SE_SECURITY_PRIVILEGE (0x%08x), skipping ACCESS_SYSTEM_SECURITY test \n " ,
2005-06-27 21:48:35 +02:00
ret ) ;
2007-02-15 17:25:20 +01:00
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 ) ;
2005-06-09 12:03:11 +02:00
if ( EveryoneSid )
FreeSid ( EveryoneSid ) ;
if ( AdminSid )
FreeSid ( AdminSid ) ;
if ( UsersSid )
FreeSid ( UsersSid ) ;
HeapFree ( GetProcessHeap ( ) , 0 , Acl ) ;
HeapFree ( GetProcessHeap ( ) , 0 , SecurityDescriptor ) ;
HeapFree ( GetProcessHeap ( ) , 0 , PrivSet ) ;
}
2006-05-13 17:56:59 +02:00
/* test GetTokenInformation for the various attributes */
static void test_token_attr ( void )
{
2007-02-21 18:10:45 +01:00
HANDLE Token , ImpersonationToken ;
2006-05-13 17:56:59 +02:00
DWORD Size ;
TOKEN_PRIVILEGES * Privileges ;
TOKEN_GROUPS * Groups ;
TOKEN_USER * User ;
BOOL ret ;
2006-05-21 23:06:47 +02:00
DWORD i , GLE ;
LPSTR SidString ;
2007-02-21 18:10:45 +01:00
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel ;
2006-05-13 17:56:59 +02:00
2006-11-06 12:35:37 +01:00
/* cygwin-like use case */
ret = OpenProcessToken ( GetCurrentProcess ( ) , MAXIMUM_ALLOWED , & Token ) ;
ok ( ret , " OpenProcessToken failed with error %d \n " , GetLastError ( ) ) ;
if ( ret )
{
BYTE buf [ 1024 ] ;
2007-02-21 18:10:45 +01:00
Size = sizeof ( buf ) ;
ret = GetTokenInformation ( Token , TokenUser , ( void * ) buf , Size , & Size ) ;
2007-02-21 14:59:59 +01:00
ok ( ret , " GetTokenInformation failed with error %d \n " , GetLastError ( ) ) ;
2007-02-21 18:10:45 +01:00
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 ) ;
2006-11-06 12:35:37 +01:00
CloseHandle ( Token ) ;
}
2006-06-24 23:36:40 +02:00
if ( ! pConvertSidToStringSidA )
return ;
2007-02-21 18:10:45 +01:00
ret = OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_QUERY | TOKEN_DUPLICATE , & Token ) ;
2006-05-21 23:06:47 +02:00
GLE = GetLastError ( ) ;
ok ( ret | | ( GLE = = ERROR_CALL_NOT_IMPLEMENTED ) ,
2006-10-04 12:37:30 +02:00
" OpenProcessToken failed with error %d \n " , GLE ) ;
2006-05-21 23:06:47 +02:00
if ( ! ret & & ( GLE = = ERROR_CALL_NOT_IMPLEMENTED ) )
{
trace ( " OpenProcessToken() not implemented, skipping test_token_attr() \n " ) ;
return ;
}
2006-05-13 17:56:59 +02:00
/* groups */
ret = GetTokenInformation ( Token , TokenGroups , NULL , 0 , & Size ) ;
Groups = HeapAlloc ( GetProcessHeap ( ) , 0 , Size ) ;
ret = GetTokenInformation ( Token , TokenGroups , Groups , Size , & Size ) ;
2006-10-04 12:37:30 +02:00
ok ( ret , " GetTokenInformation(TokenGroups) failed with error %d \n " , GetLastError ( ) ) ;
2006-05-13 17:56:59 +02:00
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 ;
2006-05-21 22:25:44 +02:00
pConvertSidToStringSidA ( Groups - > Groups [ i ] . Sid , & SidString ) ;
2006-05-13 17:56:59 +02:00
Name [ 0 ] = ' \0 ' ;
Domain [ 0 ] = ' \0 ' ;
ret = LookupAccountSid ( NULL , Groups - > Groups [ i ] . Sid , Name , & NameLength , Domain , & DomainLength , & SidNameUse ) ;
2006-10-04 12:37:30 +02:00
ok ( ret , " LookupAccountSid(%s) failed with error %d \n " , SidString , GetLastError ( ) ) ;
trace ( " \t %s, %s \\ %s use: %d attr: 0x%08x \n " , SidString , Domain , Name , SidNameUse , Groups - > Groups [ i ] . Attributes ) ;
2006-05-13 17:56:59 +02:00
LocalFree ( SidString ) ;
}
2006-08-04 14:17:58 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , Groups ) ;
2006-05-13 17:56:59 +02:00
/* user */
ret = GetTokenInformation ( Token , TokenUser , NULL , 0 , & Size ) ;
ok ( ! ret & & ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ) ,
2006-10-04 12:37:30 +02:00
" GetTokenInformation(TokenUser) failed with error %d \n " , GetLastError ( ) ) ;
2006-05-13 17:56:59 +02:00
User = HeapAlloc ( GetProcessHeap ( ) , 0 , Size ) ;
ret = GetTokenInformation ( Token , TokenUser , User , Size , & Size ) ;
ok ( ret ,
2006-10-04 12:37:30 +02:00
" GetTokenInformation(TokenUser) failed with error %d \n " , GetLastError ( ) ) ;
2006-05-13 17:56:59 +02:00
2006-05-21 22:25:44 +02:00
pConvertSidToStringSidA ( User - > User . Sid , & SidString ) ;
2006-10-04 12:37:30 +02:00
trace ( " TokenUser: %s attr: 0x%08x \n " , SidString , User - > User . Attributes ) ;
2006-05-13 17:56:59 +02:00
LocalFree ( SidString ) ;
2006-10-17 21:32:00 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , User ) ;
2006-05-13 17:56:59 +02:00
/* privileges */
ret = GetTokenInformation ( Token , TokenPrivileges , NULL , 0 , & Size ) ;
ok ( ! ret & & ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ) ,
2006-10-04 12:37:30 +02:00
" GetTokenInformation(TokenPrivileges) failed with error %d \n " , GetLastError ( ) ) ;
2006-05-13 17:56:59 +02:00
Privileges = HeapAlloc ( GetProcessHeap ( ) , 0 , Size ) ;
ret = GetTokenInformation ( Token , TokenPrivileges , Privileges , Size , & Size ) ;
ok ( ret ,
2006-10-04 12:37:30 +02:00
" GetTokenInformation(TokenPrivileges) failed with error %d \n " , GetLastError ( ) ) ;
2006-05-13 17:56:59 +02:00
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 ) ;
2006-10-04 12:37:30 +02:00
trace ( " \t %s, 0x%x \n " , Name , Privileges - > Privileges [ i ] . Attributes ) ;
2006-05-13 17:56:59 +02:00
}
2006-12-04 21:25:13 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , Privileges ) ;
2007-02-21 18:10:45 +01:00
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 ) ;
CloseHandle ( Token ) ;
2006-05-13 17:56:59 +02:00
}
2006-08-12 14:27:57 +02:00
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 ) ;
2006-10-04 12:37:30 +02:00
ok ( ret , " ConvertSidToStringSidA() failed: %d \n " , GetLastError ( ) ) ;
2006-08-12 14:27:57 +02:00
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 ) ) ,
2006-10-04 12:37:30 +02:00
" LookupAccountSid(%s) failed: %d \n " , str_sid , GetLastError ( ) ) ;
2006-08-12 14:27:57 +02:00
if ( ret )
trace ( " %s %s \\ %s %d \n " , str_sid , domain , account , use ) ;
else if ( GetLastError ( ) = = ERROR_NONE_MAPPED )
2006-08-27 22:36:23 +02:00
trace ( " %s couldn't be mapped \n " , str_sid ) ;
2006-08-12 14:27:57 +02:00
LocalFree ( str_sid ) ;
}
}
2006-07-06 04:53:52 +02:00
static void test_LookupAccountSid ( void )
{
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY } ;
2006-08-26 00:14:58 +02:00
CHAR accountA [ MAX_PATH ] , domainA [ MAX_PATH ] ;
DWORD acc_sizeA , dom_sizeA ;
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 ;
2006-07-06 04:53:52 +02:00
PSID pUsersSid = NULL ;
SID_NAME_USE use ;
BOOL ret ;
2006-07-20 13:05:46 +02:00
DWORD size ;
2006-08-12 14:27:57 +02:00
MAX_SID max_sid ;
2006-08-26 00:14:58 +02:00
CHAR * str_sidA ;
2006-07-20 13:05:46 +02:00
int i ;
2006-07-06 04:53:52 +02: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 ) ;
2006-08-17 21:24:21 +02:00
ok ( ret | | ( GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED ) ,
2006-10-04 12:37:30 +02:00
" AllocateAndInitializeSid failed with error %d \n " , GetLastError ( ) ) ;
2006-08-17 21:24:21 +02:00
/* not running on NT so give up */
if ( ! ret & & ( GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED ) )
return ;
2006-07-06 04:53:52 +02:00
2006-08-26 00:14:58 +02:00
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 ,
2006-10-04 12:37:30 +02:00
" LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %u \n " , GetLastError ( ) ) ;
2006-08-26 00:14:58 +02:00
/* 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 ,
2006-10-04 12:37:30 +02:00
" LookupAccountSidA() Expected acc_size = %u, got %u \n " ,
2006-08-26 00:14:58 +02:00
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 ,
2006-10-04 12:37:30 +02:00
" LookupAccountSid() Expected acc_size = %u, got %u \n " ,
2006-08-26 00:14:58 +02:00
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 ,
2006-10-04 12:37:30 +02:00
" LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %u \n " , GetLastError ( ) ) ;
2006-08-26 00:14:58 +02:00
/* 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 ,
2006-10-04 12:37:30 +02:00
" LookupAccountSidA() Expected dom_size = %u, got %u \n " ,
2006-08-26 00:14:58 +02:00
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 ,
2006-10-04 12:37:30 +02:00
" LookupAccountSidA() Expected dom_size = %u, got %u \n " ,
2006-08-26 00:14:58 +02:00
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 " ) ;
2006-08-19 15:17:30 +02:00
2006-08-27 22:36:23 +02:00
/* native windows crashes if domainW or accountW is NULL */
2006-07-20 13:05:46 +02:00
2006-08-19 15:17:30 +02:00
/* try a small account buffer */
2006-08-26 00:14:58 +02:00
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 ,
2006-10-04 12:37:30 +02:00
" LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %u \n " , GetLastError ( ) ) ;
2006-08-19 15:17:30 +02:00
/* try a 0 sized account buffer */
2006-08-26 00:14:58 +02:00
acc_sizeW = 0 ;
dom_sizeW = MAX_PATH ;
accountW [ 0 ] = 0 ;
ret = LookupAccountSidW ( NULL , pUsersSid , accountW , & acc_sizeW , domainW , & dom_sizeW , & use ) ;
2006-08-19 15:17:30 +02:00
/* this can fail or succeed depending on OS version but the size will always be returned */
2006-08-26 00:14:58 +02:00
ok ( acc_sizeW = = real_acc_sizeW + 1 ,
2006-10-04 12:37:30 +02:00
" LookupAccountSidW() Expected acc_size = %u, got %u \n " ,
2006-08-26 00:14:58 +02:00
real_acc_sizeW + 1 , acc_sizeW ) ;
2006-08-19 15:17:30 +02:00
/* try a 0 sized account buffer */
2006-08-26 00:14:58 +02:00
acc_sizeW = 0 ;
dom_sizeW = MAX_PATH ;
ret = LookupAccountSidW ( NULL , pUsersSid , NULL , & acc_sizeW , domainW , & dom_sizeW , & use ) ;
2006-08-19 15:17:30 +02:00
/* this can fail or succeed depending on OS version but the size will always be returned */
2006-08-26 00:14:58 +02:00
ok ( acc_sizeW = = real_acc_sizeW + 1 ,
2006-10-04 12:37:30 +02:00
" LookupAccountSidW() Expected acc_size = %u, got %u \n " ,
2006-08-26 00:14:58 +02:00
real_acc_sizeW + 1 , acc_sizeW ) ;
2006-08-19 15:17:30 +02:00
/* try a small domain buffer */
2006-08-26 00:14:58 +02:00
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 ,
2006-10-04 12:37:30 +02:00
" LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %u \n " , GetLastError ( ) ) ;
2006-08-19 15:17:30 +02:00
/* try a 0 sized domain buffer */
2006-08-26 00:14:58 +02:00
dom_sizeW = 0 ;
acc_sizeW = MAX_PATH ;
accountW [ 0 ] = 0 ;
ret = LookupAccountSidW ( NULL , pUsersSid , accountW , & acc_sizeW , domainW , & dom_sizeW , & use ) ;
2006-08-19 15:17:30 +02:00
/* this can fail or succeed depending on OS version but the size will always be returned */
2006-08-26 00:14:58 +02:00
ok ( dom_sizeW = = real_dom_sizeW + 1 ,
2006-10-04 12:37:30 +02:00
" LookupAccountSidW() Expected dom_size = %u, got %u \n " ,
2006-08-26 00:14:58 +02:00
real_dom_sizeW + 1 , dom_sizeW ) ;
2006-08-19 15:17:30 +02:00
/* try a 0 sized domain buffer */
2006-08-26 00:14:58 +02:00
dom_sizeW = 0 ;
acc_sizeW = MAX_PATH ;
ret = LookupAccountSidW ( NULL , pUsersSid , accountW , & acc_sizeW , NULL , & dom_sizeW , & use ) ;
2006-08-19 15:17:30 +02:00
/* this can fail or succeed depending on OS version but the size will always be returned */
2006-08-26 00:14:58 +02:00
ok ( dom_sizeW = = real_dom_sizeW + 1 ,
2006-10-04 12:37:30 +02:00
" LookupAccountSidW() Expected dom_size = %u, got %u \n " ,
2006-08-26 00:14:58 +02:00
real_dom_sizeW + 1 , dom_sizeW ) ;
2006-08-19 15:17:30 +02:00
2006-10-17 21:32:00 +02:00
FreeSid ( pUsersSid ) ;
2006-07-20 13:05:46 +02:00
pCreateWellKnownSid = ( fnCreateWellKnownSid ) GetProcAddress ( hmod , " CreateWellKnownSid " ) ;
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 ) )
{
2006-08-26 00:14:58 +02:00
if ( pConvertSidToStringSidA ( & max_sid . sid , & str_sidA ) )
2006-07-20 13:05:46 +02:00
{
2006-08-26 00:14:58 +02:00
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 ) ;
2006-07-20 13:05:46 +02:00
}
}
else
2006-08-27 22:36:23 +02:00
{
if ( GetLastError ( ) ! = ERROR_INVALID_PARAMETER )
2006-10-04 12:37:30 +02:00
trace ( " CreateWellKnownSid(%d) failed: %d \n " , i , GetLastError ( ) ) ;
2006-08-27 22:36:23 +02:00
else
trace ( " %d: not supported \n " , i ) ;
}
2006-08-04 14:17:58 +02:00
}
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 ) ) ;
2006-08-14 13:17:55 +02:00
object_attributes . Length = sizeof ( object_attributes ) ;
2006-08-04 14:17:58 +02:00
status = pLsaOpenPolicy ( NULL , & object_attributes , POLICY_ALL_ACCESS , & handle ) ;
2006-08-14 13:17:55 +02:00
ok ( status = = STATUS_SUCCESS | | status = = STATUS_ACCESS_DENIED ,
2006-10-04 12:37:30 +02:00
" LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08x \n " , status ) ;
2006-08-14 13:17:55 +02:00
/* 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 ) ;
2006-10-04 12:37:30 +02:00
ok ( status = = STATUS_SUCCESS , " LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) returned 0x%08x \n " , status ) ;
2006-08-14 13:17:55 +02:00
}
2006-08-04 14:17:58 +02:00
if ( status = = STATUS_SUCCESS )
{
PPOLICY_ACCOUNT_DOMAIN_INFO info ;
status = pLsaQueryInformationPolicy ( handle , PolicyAccountDomainInformation , ( PVOID * ) & info ) ;
2006-10-04 12:37:30 +02:00
ok ( status = = STATUS_SUCCESS , " LsaQueryInformationPolicy() failed, returned 0x%08x \n " , status ) ;
2006-08-04 14:17:58 +02:00
if ( status = = STATUS_SUCCESS )
{
ok ( info - > DomainSid ! = 0 , " LsaQueryInformationPolicy(PolicyAccountDomainInformation) missing SID \n " ) ;
if ( info - > DomainSid )
{
int count = * GetSidSubAuthorityCount ( info - > DomainSid ) ;
2006-08-12 14:27:57 +02:00
CopySid ( GetSidLengthRequired ( count ) , & max_sid , info - > DomainSid ) ;
test_sid_str ( ( PSID ) & max_sid . sid ) ;
2006-08-04 14:17:58 +02:00
max_sid . sid . SubAuthority [ count ] = DOMAIN_USER_RID_ADMIN ;
max_sid . sid . SubAuthorityCount = count + 1 ;
2006-08-12 14:27:57 +02:00
test_sid_str ( ( PSID ) & max_sid . sid ) ;
2006-08-04 14:17:58 +02:00
max_sid . sid . SubAuthority [ count ] = DOMAIN_USER_RID_GUEST ;
2006-08-12 14:27:57 +02:00
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 ) ;
2006-08-04 14:17:58 +02:00
}
pLsaFreeMemory ( ( LPVOID ) info ) ;
}
status = pLsaClose ( handle ) ;
2006-10-04 12:37:30 +02:00
ok ( status = = STATUS_SUCCESS , " LsaClose() failed, returned 0x%08x \n " , status ) ;
2006-08-04 14:17:58 +02:00
}
2006-07-20 13:05:46 +02:00
}
}
2006-07-06 04:53:52 +02:00
}
2006-12-01 00:53:21 +01:00
static void get_sid_info ( PSID psid , LPSTR * user , LPSTR * dom )
{
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 ' ;
LookupAccountSidA ( NULL , psid , account , & size , domain , & dom_size , & use ) ;
}
static void test_LookupAccountName ( void )
{
DWORD sid_size , domain_size , user_size ;
DWORD sid_save , domain_save ;
CHAR user_name [ UNLEN + 1 ] ;
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 ;
ret = GetUserNameA ( user_name , & user_size ) ;
ok ( ret , " Failed to get user name \n " ) ;
/* 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 ) ;
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 ) ;
ok ( domain_size = = domain_save - 1 , " Expected %d, got %d \n " , domain_save - 1 , domain_size ) ;
ok ( lstrlen ( domain ) = = domain_size , " Expected %d \n " , lstrlen ( domain ) ) ;
ok ( sid_use = = SidTypeUser , " Expected SidTypeUser, got %d \n " , SidTypeUser ) ;
}
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 ) ;
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 " ) ;
todo_wine
{
ok ( ! lstrcmp ( account , " BUILTIN " ) , " Expected BUILTIN, got %s \n " , account ) ;
ok ( ! lstrcmp ( domain , " BUILTIN " ) , " Expected BUILTIN, got %s \n " , domain ) ;
ok ( sid_use = = SidTypeDomain , " Expected SidTypeDomain, got %d \n " , SidTypeDomain ) ;
}
/* 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 ) ;
todo_wine
{
ok ( GetLastError ( ) = = ERROR_NONE_MAPPED ,
" 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 ) ;
}
2006-12-04 21:25:13 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , psid ) ;
HeapFree ( GetProcessHeap ( ) , 0 , domain ) ;
2006-12-01 00:53:21 +01:00
}
2007-01-25 07:43:18 +01:00
# define TEST_GRANTED_ACCESS(a,b) test_granted_access(a,b,__LINE__)
static void test_granted_access ( HANDLE handle , ACCESS_MASK access , int line )
{
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 ) ;
ok_ ( __FILE__ , line ) ( obj_info . GrantedAccess = = access , " Gratned access should "
" be 0x%08x, instead of 0x%08x \n " , access , obj_info . GrantedAccess ) ;
}
2007-02-07 05:55:24 +01: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 )
2007-01-25 07:43:18 +01:00
static void test_process_security ( void )
{
BOOL res ;
2007-02-07 05:55:24 +01:00
char owner [ 32 ] , group [ 32 ] ;
2007-01-25 07:43:18 +01: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 ;
2007-02-07 05:55:24 +01:00
HANDLE token , event ;
DWORD tmp ;
2007-01-25 07:43:18 +01:00
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 " ) ;
return ;
}
ok ( res , " InitializeAcl failed with error %d \n " , GetLastError ( ) ) ;
2007-02-07 05:55:24 +01:00
/* 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 ) return ;
res = GetTokenInformation ( token , TokenOwner , owner , sizeof ( owner ) , & tmp ) ;
ok ( res , " GetTokenInformation failed with error %d \n " , GetLastError ( ) ) ;
AdminSid = ( ( TOKEN_OWNER * ) owner ) - > Owner ;
res = GetTokenInformation ( token , TokenPrimaryGroup , group , sizeof ( group ) , & tmp ) ;
ok ( res , " GetTokenInformation failed with error %d \n " , GetLastError ( ) ) ;
UsersSid = ( ( TOKEN_PRIMARY_GROUP * ) group ) - > PrimaryGroup ;
CloseHandle ( token ) ;
if ( ! res ) return ;
2007-01-25 07:43:18 +01:00
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 , " AddAccessAllowedAceEx 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 ( ) ) ;
2007-02-07 05:55:24 +01:00
event = CreateEvent ( NULL , TRUE , TRUE , " test_event " ) ;
ok ( event ! = NULL , " CreateEvent %d \n " , GetLastError ( ) ) ;
2007-02-27 15:28:18 +01:00
SecurityDescriptor - > Revision = 0 ;
CHECK_SET_SECURITY ( event , OWNER_SECURITY_INFORMATION , ERROR_UNKNOWN_REVISION ) ;
SecurityDescriptor - > Revision = SECURITY_DESCRIPTOR_REVISION ;
2007-02-07 05:55:24 +01:00
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 ) ;
2007-02-27 15:28:18 +01:00
/* NULL DACL is valid and means default DACL from token */
SecurityDescriptor - > Control | = SE_DACL_PRESENT ;
CHECK_SET_SECURITY ( event , DACL_SECURITY_INFORMATION , ERROR_SUCCESS ) ;
2007-02-07 05:55:24 +01:00
2007-01-25 07:43:18 +01:00
/* Set owner and group and dacl */
res = SetSecurityDescriptorOwner ( SecurityDescriptor , AdminSid , FALSE ) ;
ok ( res , " SetSecurityDescriptorOwner failed with error %d \n " , GetLastError ( ) ) ;
2007-02-07 05:55:24 +01:00
CHECK_SET_SECURITY ( event , OWNER_SECURITY_INFORMATION , ERROR_SUCCESS ) ;
res = SetSecurityDescriptorGroup ( SecurityDescriptor , UsersSid , FALSE ) ;
2007-01-25 07:43:18 +01:00
ok ( res , " SetSecurityDescriptorGroup failed with error %d \n " , GetLastError ( ) ) ;
2007-02-07 05:55:24 +01:00
CHECK_SET_SECURITY ( event , GROUP_SECURITY_INFORMATION , ERROR_SUCCESS ) ;
2007-01-25 07:43:18 +01:00
res = SetSecurityDescriptorDacl ( SecurityDescriptor , TRUE , Acl , FALSE ) ;
ok ( res , " SetSecurityDescriptorDacl failed with error %d \n " , GetLastError ( ) ) ;
2007-02-07 05:55:24 +01:00
CHECK_SET_SECURITY ( event , DACL_SECURITY_INFORMATION , ERROR_SUCCESS ) ;
2007-01-25 07:43:18 +01:00
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 ( ) ) ;
TEST_GRANTED_ACCESS ( info . hProcess , PROCESS_ALL_ACCESS ) ;
ok ( WaitForSingleObject ( info . hProcess , 30000 ) = = WAIT_OBJECT_0 , " Child process termination \n " ) ;
2007-02-07 05:55:24 +01:00
CloseHandle ( event ) ;
2007-01-25 07:43:18 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , Acl ) ;
HeapFree ( GetProcessHeap ( ) , 0 , SecurityDescriptor ) ;
}
static void test_process_security_child ( void )
{
HANDLE handle , handle1 ;
2007-02-07 05:55:24 +01:00
BOOL ret ;
DWORD err ;
2007-01-25 07:43:18 +01:00
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 ( ) ,
2007-02-07 05:55:24 +01:00
& handle1 , 0 , TRUE , DUPLICATE_SAME_ACCESS ) ,
2007-01-25 07:43:18 +01:00
" duplicating handle err:%d \n " , GetLastError ( ) ) ;
2007-02-07 05:55:24 +01:00
TEST_GRANTED_ACCESS ( handle1 , PROCESS_TERMINATE ) ;
2007-01-25 07:43:18 +01:00
CloseHandle ( handle1 ) ;
2007-02-07 05:55:24 +01:00
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 ) ;
2007-01-25 07:43:18 +01:00
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 ( ) ,
2007-02-07 05:55:24 +01:00
& handle , 0 , TRUE , DUPLICATE_SAME_ACCESS ) ,
2007-01-25 07:43:18 +01:00
" duplicating handle err:%d \n " , GetLastError ( ) ) ;
TEST_GRANTED_ACCESS ( handle , PROCESS_ALL_ACCESS ) ;
CloseHandle ( handle ) ;
2007-02-07 05:55:24 +01:00
/* 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 ( ) ) ;
TEST_GRANTED_ACCESS ( handle , PROCESS_ALL_ACCESS ) ;
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 ) ;
2007-01-25 07:43:18 +01:00
}
2007-02-15 17:25:58 +01:00
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 ;
ret = ImpersonateSelf ( SecurityAnonymous ) ;
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 */
2007-02-16 00:21:40 +01:00
todo_wine {
2007-02-15 17:25:58 +01:00
error = RegOpenKeyEx ( HKEY_CURRENT_USER , " Software " , 0 , KEY_READ , & hkey ) ;
ok ( error = = ERROR_INVALID_HANDLE , " RegOpenKeyEx should have failed with ERROR_INVALID_HANDLE instead of %d \n " , error ) ;
}
RevertToSelf ( ) ;
ret = OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_DUPLICATE , & ProcessToken ) ;
ok ( ret , " OpenProcessToken failed with error %d \n " , GetLastError ( ) ) ;
ret = DuplicateTokenEx ( 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 ) ;
User = ( TOKEN_USER * ) HeapAlloc ( GetProcessHeap ( ) , 0 , Size ) ;
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 ) ;
Privileges = ( TOKEN_PRIVILEGES * ) HeapAlloc ( GetProcessHeap ( ) , 0 , Size ) ;
ret = GetTokenInformation ( Token , TokenPrivileges , Privileges , Size , & Size ) ;
ok ( ret , " GetTokenInformation(TokenPrivileges) failed with error %d \n " , GetLastError ( ) ) ;
PrivilegeSet = ( PRIVILEGE_SET * ) HeapAlloc ( GetProcessHeap ( ) , 0 , FIELD_OFFSET ( PRIVILEGE_SET , Privilege [ Privileges - > PrivilegeCount ] ) ) ;
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 {
ok ( error = = ERROR_INVALID_HANDLE , " RegOpenKeyEx should have failed with ERROR_INVALID_HANDLE instead of %d \n " , error ) ;
}
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 ) ;
}
2004-08-09 20:47:22 +02:00
START_TEST ( security )
{
2004-11-04 05:52:17 +01:00
init ( ) ;
if ( ! hmod ) return ;
2007-01-25 07:43:18 +01:00
if ( myARGC > = 3 )
{
test_process_security_child ( ) ;
return ;
}
2004-08-09 20:47:22 +02:00
test_sid ( ) ;
2004-08-16 23:07:50 +02:00
test_trustee ( ) ;
2004-11-04 05:52:17 +01:00
test_luid ( ) ;
2005-03-28 12:00:59 +02:00
test_FileSecurity ( ) ;
2005-06-09 12:03:11 +02:00
test_AccessCheck ( ) ;
2006-05-13 17:56:59 +02:00
test_token_attr ( ) ;
2006-07-06 04:53:52 +02:00
test_LookupAccountSid ( ) ;
2006-12-01 00:53:21 +01:00
test_LookupAccountName ( ) ;
2007-01-25 07:43:18 +01:00
test_process_security ( ) ;
2007-02-15 17:25:58 +01:00
test_impersonation_level ( ) ;
2004-08-09 20:47:22 +02:00
}