@ -1724,17 +1724,6 @@ pgwin32_doRunAsService(void)
}
/*
* Mingw headers are incomplete , and so are the libraries . So we have to load
* a whole lot of API functions dynamically .
*/
typedef BOOL ( WINAPI * __CreateRestrictedToken ) ( HANDLE , DWORD , DWORD , PSID_AND_ATTRIBUTES , DWORD , PLUID_AND_ATTRIBUTES , DWORD , PSID_AND_ATTRIBUTES , PHANDLE ) ;
typedef BOOL ( WINAPI * __IsProcessInJob ) ( HANDLE , HANDLE , PBOOL ) ;
typedef HANDLE ( WINAPI * __CreateJobObject ) ( LPSECURITY_ATTRIBUTES , LPCTSTR ) ;
typedef BOOL ( WINAPI * __SetInformationJobObject ) ( HANDLE , JOBOBJECTINFOCLASS , LPVOID , DWORD ) ;
typedef BOOL ( WINAPI * __AssignProcessToJobObject ) ( HANDLE , HANDLE ) ;
typedef BOOL ( WINAPI * __QueryInformationJobObject ) ( HANDLE , JOBOBJECTINFOCLASS , LPVOID , DWORD , LPDWORD ) ;
/*
* Set up STARTUPINFO for the new process to inherit this process ' handles .
*
@ -1777,20 +1766,11 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_ser
STARTUPINFO si ;
HANDLE origToken ;
HANDLE restrictedToken ;
BOOL inJob ;
SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY } ;
SID_AND_ATTRIBUTES dropSids [ 2 ] ;
PTOKEN_PRIVILEGES delPrivs ;
/* Functions loaded dynamically */
__CreateRestrictedToken _CreateRestrictedToken = NULL ;
__IsProcessInJob _IsProcessInJob = NULL ;
__CreateJobObject _CreateJobObject = NULL ;
__SetInformationJobObject _SetInformationJobObject = NULL ;
__AssignProcessToJobObject _AssignProcessToJobObject = NULL ;
__QueryInformationJobObject _QueryInformationJobObject = NULL ;
HANDLE Kernel32Handle ;
HANDLE Advapi32Handle ;
ZeroMemory ( & si , sizeof ( si ) ) ;
si . cb = sizeof ( si ) ;
@ -1802,20 +1782,6 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_ser
*/
InheritStdHandles ( & si ) ;
Advapi32Handle = LoadLibrary ( " ADVAPI32.DLL " ) ;
if ( Advapi32Handle ! = NULL )
{
_CreateRestrictedToken = ( __CreateRestrictedToken ) ( pg_funcptr_t ) GetProcAddress ( Advapi32Handle , " CreateRestrictedToken " ) ;
}
if ( _CreateRestrictedToken = = NULL )
{
/* Log error if we cannot get the function */
write_stderr ( _ ( " %s: could not locate object function to create restricted token: error code %lu \n " ) ,
progname , ( unsigned long ) GetLastError ( ) ) ;
return 0 ;
}
/* Open the current token to use as a base for the restricted one */
if ( ! OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_ALL_ACCESS , & origToken ) )
{
@ -1848,19 +1814,18 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_ser
/* Error message already printed */
return 0 ;
b = _ CreateRestrictedToken( origToken ,
0 ,
sizeof ( dropSids ) / sizeof ( dropSids [ 0 ] ) ,
dropSids ,
delPrivs - > PrivilegeCount , delPrivs - > Privileges ,
0 , NULL ,
& restrictedToken ) ;
b = CreateRestrictedToken ( origToken ,
0 ,
sizeof ( dropSids ) / sizeof ( dropSids [ 0 ] ) ,
dropSids ,
delPrivs - > PrivilegeCount , delPrivs - > Privileges ,
0 , NULL ,
& restrictedToken ) ;
free ( delPrivs ) ;
FreeSid ( dropSids [ 1 ] . Sid ) ;
FreeSid ( dropSids [ 0 ] . Sid ) ;
CloseHandle ( origToken ) ;
FreeLibrary ( Advapi32Handle ) ;
if ( ! b )
{
@ -1872,79 +1837,55 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_ser
AddUserToTokenDacl ( restrictedToken ) ;
r = CreateProcessAsUser ( restrictedToken , NULL , cmd , NULL , NULL , TRUE , CREATE_SUSPENDED , NULL , NULL , & si , processInfo ) ;
Kernel32Handle = LoadLibrary ( " KERNEL32.DLL " ) ;
if ( Kernel32Handle ! = NULL )
{
_IsProcessInJob = ( __IsProcessInJob ) ( pg_funcptr_t ) GetProcAddress ( Kernel32Handle , " IsProcessInJob " ) ;
_CreateJobObject = ( __CreateJobObject ) ( pg_funcptr_t ) GetProcAddress ( Kernel32Handle , " CreateJobObjectA " ) ;
_SetInformationJobObject = ( __SetInformationJobObject ) ( pg_funcptr_t ) GetProcAddress ( Kernel32Handle , " SetInformationJobObject " ) ;
_AssignProcessToJobObject = ( __AssignProcessToJobObject ) ( pg_funcptr_t ) GetProcAddress ( Kernel32Handle , " AssignProcessToJobObject " ) ;
_QueryInformationJobObject = ( __QueryInformationJobObject ) ( pg_funcptr_t ) GetProcAddress ( Kernel32Handle , " QueryInformationJobObject " ) ;
}
/* Verify that we found all functions */
if ( _IsProcessInJob = = NULL | | _CreateJobObject = = NULL | | _SetInformationJobObject = = NULL | | _AssignProcessToJobObject = = NULL | | _QueryInformationJobObject = = NULL )
if ( IsProcessInJob ( processInfo - > hProcess , NULL , & inJob ) )
{
/* Log error if we can't get version */
write_stderr ( _ ( " %s: WARNING: could not locate all job object functions in system API \n " ) , progname ) ;
}
else
{
BOOL inJob ;
if ( _IsProcessInJob ( processInfo - > hProcess , NULL , & inJob ) )
if ( ! inJob )
{
if ( ! inJob )
{
/*
* Job objects are working , and the new process isn ' t in one ,
* so we can create one safely . If any problems show up when
* setting it , we ' re going to ignore them .
*/
HANDLE job ;
char jobname [ 128 ] ;
/*
* Job objects are working , and the new process isn ' t in one , so
* we can create one safely . If any problems show up when setting
* it , we ' re going to ignore them .
*/
HANDLE job ;
char jobname [ 128 ] ;
sprintf ( jobname , " PostgreSQL_%lu " ,
( unsigned long ) processInfo - > dwProcessId ) ;
sprintf ( jobname , " PostgreSQL_%lu " ,
( unsigned long ) processInfo - > dwProcessId ) ;
job = _ CreateJobObject( NULL , jobname ) ;
if ( job )
{
JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit ;
JOBOBJECT_BASIC_UI_RESTRICTIONS uiRestrictions ;
JOBOBJECT_SECURITY_LIMIT_INFORMATION securityLimit ;
job = CreateJobObject ( NULL , jobname ) ;
if ( job )
{
JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit ;
JOBOBJECT_BASIC_UI_RESTRICTIONS uiRestrictions ;
JOBOBJECT_SECURITY_LIMIT_INFORMATION securityLimit ;
ZeroMemory ( & basicLimit , sizeof ( basicLimit ) ) ;
ZeroMemory ( & uiRestrictions , sizeof ( uiRestrictions ) ) ;
ZeroMemory ( & securityLimit , sizeof ( securityLimit ) ) ;
ZeroMemory ( & basicLimit , sizeof ( basicLimit ) ) ;
ZeroMemory ( & uiRestrictions , sizeof ( uiRestrictions ) ) ;
ZeroMemory ( & securityLimit , sizeof ( securityLimit ) ) ;
basicLimit . LimitFlags = JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_PRIORITY_CLASS ;
basicLimit . PriorityClass = NORMAL_PRIORITY_CLASS ;
_ SetInformationJobObject( job , JobObjectBasicLimitInformation , & basicLimit , sizeof ( basicLimit ) ) ;
basicLimit . LimitFlags = JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_PRIORITY_CLASS ;
basicLimit . PriorityClass = NORMAL_PRIORITY_CLASS ;
SetInformationJobObject ( job , JobObjectBasicLimitInformation , & basicLimit , sizeof ( basicLimit ) ) ;
uiRestrictions . UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS |
JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_READCLIPBOARD |
JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD ;
uiRestrictions . UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS |
JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_READCLIPBOARD |
JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD ;
_ SetInformationJobObject( job , JobObjectBasicUIRestrictions , & uiRestrictions , sizeof ( uiRestrictions ) ) ;
SetInformationJobObject ( job , JobObjectBasicUIRestrictions , & uiRestrictions , sizeof ( uiRestrictions ) ) ;
securityLimit . SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN ;
securityLimit . JobToken = restrictedToken ;
_ SetInformationJobObject( job , JobObjectSecurityLimitInformation , & securityLimit , sizeof ( securityLimit ) ) ;
securityLimit . SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN ;
securityLimit . JobToken = restrictedToken ;
SetInformationJobObject ( job , JobObjectSecurityLimitInformation , & securityLimit , sizeof ( securityLimit ) ) ;
_AssignProcessToJobObject ( job , processInfo - > hProcess ) ;
}
AssignProcessToJobObject ( job , processInfo - > hProcess ) ;
}
}
}
CloseHandle ( restrictedToken ) ;
ResumeThread ( processInfo - > hThread ) ;
FreeLibrary ( Kernel32Handle ) ;
/*
* We intentionally don ' t close the job object handle , because we want the
* object to live on until pg_ctl shuts down .